chore: import upstream snapshot with attribution
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, AzureResponsesAgent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an Azure Responses Agent that answers
|
||||
user questions using the file search tool.
|
||||
"""
|
||||
|
||||
# Define the YAML string for the sample
|
||||
spec = """
|
||||
type: azure_responses
|
||||
name: FileSearchAgent
|
||||
description: Agent with file search tool.
|
||||
instructions: >
|
||||
Use the file search tool to answer questions from the user.
|
||||
model:
|
||||
id: ${AzureOpenAI:ChatModelId}
|
||||
connection:
|
||||
endpoint: ${AzureOpenAI:Endpoint}
|
||||
tools:
|
||||
- type: file_search
|
||||
options:
|
||||
vector_store_ids:
|
||||
- ${AzureOpenAI:VectorStoreId}
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# Setup the Azure OpenAI client
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# Read and upload the file to the OpenAI AI service
|
||||
pdf_file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
|
||||
"resources",
|
||||
"file_search",
|
||||
"employees.pdf",
|
||||
)
|
||||
# Upload the pdf file to the server
|
||||
with open(pdf_file_path, "rb") as file:
|
||||
file = await client.files.create(file=file, purpose="assistants")
|
||||
|
||||
vector_store = await client.vector_stores.create(
|
||||
name="responses_file_search",
|
||||
file_ids=[file.id],
|
||||
)
|
||||
|
||||
try:
|
||||
# Create the Responses Agent from the YAML spec
|
||||
# Note: the extras can be provided in the short-format (shown below) or
|
||||
# in the long-format (as shown in the YAML spec, with the `AzureOpenAI:` prefix).
|
||||
# The short-format is used here for brevity
|
||||
agent: AzureResponsesAgent = await AgentRegistry.create_from_yaml(
|
||||
yaml_str=spec,
|
||||
client=client,
|
||||
extras={"AzureOpenAI:VectorStoreId": vector_store.id},
|
||||
)
|
||||
|
||||
# Define the task for the agent
|
||||
TASK = "Who can help me if I have a sales question?"
|
||||
|
||||
print(f"# User: '{TASK}'")
|
||||
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=TASK,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
finally:
|
||||
# Cleanup: Delete the agent, vector store, and file
|
||||
await client.vector_stores.delete(vector_store.id)
|
||||
await client.files.delete(file.id)
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
|
||||
# User: 'Who can help me if I have a sales question?'
|
||||
# FileSearchAgent: If you have a sales question, you may contact the following individuals:
|
||||
|
||||
1. **Hicran Bea** - Sales Manager
|
||||
2. **Mariam Jaslyn** - Sales Representative
|
||||
3. **Angelino Embla** - Sales Representative
|
||||
|
||||
This information comes from the employee records【4:0†source】.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from typing import Annotated
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, AzureResponsesAgent
|
||||
from semantic_kernel.functions import kernel_function
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an Azure Responses Agent that answers
|
||||
user questions. The sample shows how to load a declarative spec from a file.
|
||||
The plugins/functions must already exist in the kernel.
|
||||
They are not created declaratively via the spec.
|
||||
"""
|
||||
|
||||
|
||||
class MenuPlugin:
|
||||
"""A sample Menu Plugin used for the concept sample."""
|
||||
|
||||
@kernel_function(description="Provides a list of specials from the menu.")
|
||||
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
|
||||
return """
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
"""
|
||||
|
||||
@kernel_function(description="Provides the price of the requested menu item.")
|
||||
def get_item_price(
|
||||
self, menu_item: Annotated[str, "The name of the menu item."]
|
||||
) -> Annotated[str, "Returns the price of the menu item."]:
|
||||
return "$9.99"
|
||||
|
||||
|
||||
async def main():
|
||||
try:
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# Define the YAML file path for the sample
|
||||
file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
|
||||
"resources",
|
||||
"declarative_spec",
|
||||
"azure_responses_spec.yaml",
|
||||
)
|
||||
|
||||
# Create the Responses Agent from the YAML spec
|
||||
agent: AzureResponsesAgent = await AgentRegistry.create_from_file(
|
||||
file_path,
|
||||
plugins=[MenuPlugin()],
|
||||
client=client,
|
||||
)
|
||||
|
||||
# Create the agent
|
||||
user_inputs = [
|
||||
"Hello",
|
||||
"What is the special soup?",
|
||||
"How much does that cost?",
|
||||
"Thank you",
|
||||
]
|
||||
|
||||
# Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
for user_input in user_inputs:
|
||||
print(f"# User: '{user_input}'")
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
# Store the thread for the next iteration
|
||||
thread = response.thread
|
||||
finally:
|
||||
# Cleanup: Delete the thread
|
||||
await thread.delete() if thread else None
|
||||
|
||||
"""
|
||||
Sample Output:
|
||||
|
||||
# User: 'Hello'
|
||||
# Host: Hi there! How can I assist you today?
|
||||
# User: 'What is the special soup?'
|
||||
# Host: The special soup is Clam Chowder.
|
||||
# User: 'What is the special drink?'
|
||||
# Host: The special drink is Chai Tea.
|
||||
# User: 'How much is it?'
|
||||
# Host: The Chai Tea costs $9.99.
|
||||
# User: 'Thank you'
|
||||
# Host: You're welcome! If you have any more questions, feel free to ask.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, AzureResponsesAgent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an Azure Responses Agent that invokes
|
||||
a story generation task using a prompt template and a declarative spec.
|
||||
"""
|
||||
|
||||
# Define the YAML string for the sample
|
||||
spec = """
|
||||
type: azure_responses
|
||||
name: StoryAgent
|
||||
description: An agent that generates a story about a topic.
|
||||
instructions: Tell a story about {{$topic}} that is {{$length}} sentences long.
|
||||
model:
|
||||
id: ${AzureOpenAI:ChatModelId}
|
||||
connection:
|
||||
endpoint: ${AzureOpenAI:Endpoint}
|
||||
inputs:
|
||||
topic:
|
||||
description: The topic of the story.
|
||||
required: true
|
||||
default: Cats
|
||||
length:
|
||||
description: The number of sentences in the story.
|
||||
required: true
|
||||
default: 2
|
||||
outputs:
|
||||
output1:
|
||||
description: The generated story.
|
||||
template:
|
||||
format: semantic-kernel
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# Setup the Azure OpenAI client
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# Create the Responses Agent from the YAML spec
|
||||
# Note: the extras can be provided in the short-format (shown below) or
|
||||
# in the long-format (as shown in the YAML spec, with the `AzureOpenAI:` prefix).
|
||||
# The short-format is used here for brevity
|
||||
agent: AzureResponsesAgent = await AgentRegistry.create_from_yaml(
|
||||
yaml_str=spec,
|
||||
client=client,
|
||||
)
|
||||
|
||||
USER_INPUTS = ["Tell me a fun story."]
|
||||
|
||||
# Invoke the agent for the specified task
|
||||
for user_input in USER_INPUTS:
|
||||
# Print the user input
|
||||
print(f"# User: '{user_input}'")
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
|
||||
# User: 'Tell me a fun story.'
|
||||
# StoryAgent: Late at night, a mischievous cat named Whiskers tiptoed across the piano keys,
|
||||
accidentally composing a tune so catchy that all the neighborhood felines gathered outside
|
||||
to dance. By morning, the humans awoke to find a crowd of cats meowing for an encore performance.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, OpenAIResponsesAgent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent that answers
|
||||
user questions using the file search tool based on a declarative spec.
|
||||
"""
|
||||
|
||||
# Define the YAML string for the sample
|
||||
spec = """
|
||||
type: openai_responses
|
||||
name: FileSearchAgent
|
||||
description: Agent with file search tool.
|
||||
instructions: >
|
||||
Find answers to the user's questions in the provided file.
|
||||
model:
|
||||
id: ${OpenAI:ChatModelId}
|
||||
connection:
|
||||
api_key: ${OpenAI:ApiKey}
|
||||
tools:
|
||||
- type: file_search
|
||||
description: File search for document retrieval.
|
||||
options:
|
||||
vector_store_ids:
|
||||
- ${OpenAI:VectorStoreId}
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# Setup the OpenAI Responses client
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
# Read and upload the file to the OpenAI AI service
|
||||
pdf_file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
|
||||
"resources",
|
||||
"file_search",
|
||||
"employees.pdf",
|
||||
)
|
||||
# Upload the pdf file to the assistant service
|
||||
with open(pdf_file_path, "rb") as file:
|
||||
file = await client.files.create(file=file, purpose="assistants")
|
||||
|
||||
vector_store = await client.vector_stores.create(
|
||||
name="assistant_file_search",
|
||||
file_ids=[file.id],
|
||||
)
|
||||
|
||||
try:
|
||||
# Create the Responses Agent from the YAML spec
|
||||
# Note: the extras can be provided in the short-format (shown below) or
|
||||
# in the long-format (as shown in the YAML spec, with the `OpenAI:` prefix).
|
||||
# The short-format is used here for brevity
|
||||
agent: OpenAIResponsesAgent = await AgentRegistry.create_from_yaml(
|
||||
yaml_str=spec,
|
||||
client=client,
|
||||
extras={"OpenAI:VectorStoreId": vector_store.id},
|
||||
)
|
||||
|
||||
# Define the task for the agent
|
||||
USER_INPUTS = ["Who can help me if I have a sales question?", "Who works in sales?"]
|
||||
|
||||
thread = None
|
||||
|
||||
for user_input in USER_INPUTS:
|
||||
# Print the user input
|
||||
print(f"# User: '{user_input}'")
|
||||
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
thread = response.thread
|
||||
finally:
|
||||
# Cleanup: Delete the vector store, and file
|
||||
await client.vector_stores.delete(vector_store.id)
|
||||
await client.files.delete(file.id)
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
|
||||
# User: 'Who can help me if I have a sales question?'
|
||||
# FileSearchAgent: If you have a sales question, you may contact the following individuals:
|
||||
|
||||
1. **Hicran Bea** - Sales Manager
|
||||
2. **Mariam Jaslyn** - Sales Representative
|
||||
3. **Angelino Embla** - Sales Representative
|
||||
|
||||
This information comes from the employee records【4:0†source】.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
from typing import Annotated
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, OpenAIResponsesAgent
|
||||
from semantic_kernel.functions import kernel_function
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent that answers
|
||||
user questions. The sample shows how to load a declarative spec from a file.
|
||||
The plugins/functions must already exist in the kernel.
|
||||
They are not created declaratively via the spec.
|
||||
"""
|
||||
|
||||
|
||||
class MenuPlugin:
|
||||
"""A sample Menu Plugin used for the concept sample."""
|
||||
|
||||
@kernel_function(description="Provides a list of specials from the menu.")
|
||||
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
|
||||
return """
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
"""
|
||||
|
||||
@kernel_function(description="Provides the price of the requested menu item.")
|
||||
def get_item_price(
|
||||
self, menu_item: Annotated[str, "The name of the menu item."]
|
||||
) -> Annotated[str, "Returns the price of the menu item."]:
|
||||
return "$9.99"
|
||||
|
||||
|
||||
async def main():
|
||||
try:
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
# Define the YAML file path for the sample
|
||||
file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
|
||||
"resources",
|
||||
"declarative_spec",
|
||||
"openai_responses_spec.yaml",
|
||||
)
|
||||
|
||||
# Create the Responses Agent from the YAML spec
|
||||
agent: OpenAIResponsesAgent = await AgentRegistry.create_from_file(
|
||||
file_path,
|
||||
plugins=[MenuPlugin()],
|
||||
client=client,
|
||||
)
|
||||
|
||||
# Create the agent
|
||||
user_inputs = [
|
||||
"Hello",
|
||||
"What is the special soup?",
|
||||
"How much does that cost?",
|
||||
"Thank you",
|
||||
]
|
||||
|
||||
# Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
for user_input in user_inputs:
|
||||
print(f"# User: '{user_input}'")
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
# Store the thread for the next iteration
|
||||
thread = response.thread
|
||||
finally:
|
||||
# Cleanup: Delete the thread
|
||||
await thread.delete() if thread else None
|
||||
|
||||
"""
|
||||
Sample Output:
|
||||
|
||||
# User: 'Hello'
|
||||
# Host: Hi there! How can I assist you today?
|
||||
# User: 'What is the special soup?'
|
||||
# Host: The special soup is Clam Chowder.
|
||||
# User: 'What is the special drink?'
|
||||
# Host: The special drink is Chai Tea.
|
||||
# User: 'How much is it?'
|
||||
# Host: The Chai Tea costs $9.99.
|
||||
# User: 'Thank you'
|
||||
# Host: You're welcome! If you have any more questions, feel free to ask.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, OpenAIResponsesAgent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent that invokes
|
||||
a story generation task using a prompt template and a declarative spec.
|
||||
"""
|
||||
|
||||
# Define the YAML string for the sample
|
||||
spec = """
|
||||
type: openai_responses
|
||||
name: StoryAgent
|
||||
description: An agent that generates a story about a topic.
|
||||
instructions: Tell a story about {{$topic}} that is {{$length}} sentences long.
|
||||
model:
|
||||
id: ${OpenAI:ChatModelId}
|
||||
inputs:
|
||||
topic:
|
||||
description: The topic of the story.
|
||||
required: true
|
||||
default: Cats
|
||||
length:
|
||||
description: The number of sentences in the story.
|
||||
required: true
|
||||
default: 2
|
||||
outputs:
|
||||
output1:
|
||||
description: The generated story.
|
||||
template:
|
||||
format: semantic-kernel
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# Setup the OpenAI client
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
# Create the Responses Agent from the YAML spec
|
||||
# Note: the extras can be provided in the short-format (shown below) or
|
||||
# in the long-format (as shown in the YAML spec, with the `OpenAI:` prefix).
|
||||
# The short-format is used here for brevity
|
||||
agent: OpenAIResponsesAgent = await AgentRegistry.create_from_yaml(
|
||||
yaml_str=spec,
|
||||
client=client,
|
||||
)
|
||||
|
||||
USER_INPUTS = ["Tell me a fun story."]
|
||||
|
||||
# Invoke the agent for the specified task
|
||||
for user_input in USER_INPUTS:
|
||||
# Print the user input
|
||||
print(f"# User: '{user_input}'")
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
|
||||
# User: 'Tell me a fun story.'
|
||||
# StoryAgent: Late at night, a mischievous cat named Whiskers tiptoed across the piano keys,
|
||||
accidentally composing a tune so catchy that all the neighborhood felines gathered outside
|
||||
to dance. By morning, the humans awoke to find a crowd of cats meowing for an encore performance.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
|
||||
import asyncio
|
||||
|
||||
from semantic_kernel.agents import AgentRegistry, OpenAIResponsesAgent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent that answers
|
||||
user questions using the web search tool based on a declarative spec.
|
||||
"""
|
||||
|
||||
# Define the YAML string for the sample
|
||||
spec = """
|
||||
type: openai_responses
|
||||
name: WebSearchAgent
|
||||
description: Agent with web search tool.
|
||||
instructions: >
|
||||
Find answers to the user's questions using the provided tool.
|
||||
model:
|
||||
id: ${OpenAI:ChatModelId}
|
||||
connection:
|
||||
api_key: ${OpenAI:ApiKey}
|
||||
tools:
|
||||
- type: web_search
|
||||
description: Search the internet for recent information.
|
||||
options:
|
||||
search_context_size: high
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# Setup the OpenAI client
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
try:
|
||||
# Create the Responses Agent from the YAML spec
|
||||
# Note: the extras can be provided in the short-format (shown below) or
|
||||
# in the long-format (as shown in the YAML spec, with the `OpenAI:` prefix).
|
||||
# The short-format is used here for brevity
|
||||
agent: OpenAIResponsesAgent = await AgentRegistry.create_from_yaml(
|
||||
yaml_str=spec,
|
||||
client=client,
|
||||
)
|
||||
|
||||
# Define the task for the agent
|
||||
USER_INPUTS = ["Who won the 2025 NCAA basketball championship?"]
|
||||
|
||||
thread = None
|
||||
|
||||
for user_input in USER_INPUTS:
|
||||
# Print the user input
|
||||
print(f"# User: '{user_input}'")
|
||||
|
||||
# Invoke the agent for the specified task
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
):
|
||||
print(f"# {response.name}: {response}")
|
||||
thread = response.thread
|
||||
finally:
|
||||
await thread.delete() if thread else None
|
||||
|
||||
"""
|
||||
Sample output:
|
||||
|
||||
# User: 'Who won the 2025 NCAA basketball championship?'
|
||||
# WebSearchAgent: The Florida Gators won the 2025 NCAA men's basketball championship, defeating the Houston
|
||||
Cougars 65-63 on April 7, 2025, at the Alamodome in San Antonio, Texas. This victory marked Florida's
|
||||
third national title and their first since 2007. ([reuters.com](https://www.reuters.com/sports/basketball/florida-beat-houston-claim-third-ncaa-mens-basketball-title-2025-04-08/?utm_source=openai))
|
||||
|
||||
In the championship game, Florida overcame a 12-point deficit in the second half. Senior guard Walter Clayton
|
||||
Jr. was instrumental in the comeback, scoring all 11 of his points in the second half and delivering a
|
||||
crucial defensive stop in the final seconds to secure the win. Will Richard led the Gators with 18 points. ([apnews.com](https://apnews.com/article/74a9c790277595ce53ca130c5ec64429?utm_source=openai))
|
||||
|
||||
Head coach Todd Golden, in his third season, became the youngest coach to win the NCAA title since 1983. ([reuters.com](https://www.reuters.com/sports/basketball/florida-beat-houston-claim-third-ncaa-mens-basketball-title-2025-04-08/?utm_source=openai))
|
||||
|
||||
## Florida Gators' 2025 NCAA Championship Victory:
|
||||
- [Florida overcome Houston in massive comeback to claim third NCAA title](https://www.reuters.com/sports/basketball/florida-beat-houston-claim-third-ncaa-mens-basketball-title-2025-04-08/?utm_source=openai)
|
||||
- [Walter Clayton Jr.'s defensive stop gives Florida its 3rd national title with 65-63 win over Houston](https://apnews.com/article/74a9c790277595ce53ca130c5ec64429?utm_source=openai)
|
||||
- [Reports: National champion Florida sets White House visit](https://www.reuters.com/sports/reports-national-champion-florida-sets-white-house-visit-2025-05-18/?utm_source=openai)
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from semantic_kernel.agents import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import OpenAISettings
|
||||
from semantic_kernel.contents.binary_content import BinaryContent
|
||||
from semantic_kernel.contents.chat_message_content import ChatMessageContent
|
||||
from semantic_kernel.contents.text_content import TextContent
|
||||
from semantic_kernel.contents.utils.author_role import AuthorRole
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to upload PDF and text files using BinaryContent
|
||||
with an OpenAI Responses Agent. This shows how to create BinaryContent objects from files
|
||||
and compose multi-modal messages that combine text and binary content.
|
||||
|
||||
The sample demonstrates:
|
||||
1. Creating BinaryContent from a PDF file
|
||||
2. Creating BinaryContent from a text file
|
||||
3. Composing multi-modal messages with mixed content types (text + binary)
|
||||
4. Sending complex messages directly to the agent via the messages parameter
|
||||
5. Having the agent process and respond to questions about the uploaded files
|
||||
|
||||
This approach differs from simple string-based interactions by showing how to combine
|
||||
multiple content types within a single message, which is useful for rich media interactions.
|
||||
|
||||
Note: This sample uses the existing employees.pdf file from the resources directory.
|
||||
"""
|
||||
|
||||
# Sample follow-up questions to demonstrate continued conversation
|
||||
USER_INPUTS = [
|
||||
"What specific types of files did I just upload?",
|
||||
"Can you tell me about the content in the PDF file?",
|
||||
"What does the text file contain?",
|
||||
"Can you provide a summary of both documents?",
|
||||
]
|
||||
|
||||
|
||||
def create_sample_text_content() -> str:
|
||||
"""Create sample text content for demonstration purposes.
|
||||
|
||||
Returns:
|
||||
str: A sample company policy document in text format.
|
||||
"""
|
||||
return """Company Policy Document - Remote Work Guidelines
|
||||
|
||||
This document outlines our company's remote work policies and procedures.
|
||||
|
||||
Remote Work Eligibility:
|
||||
- Full-time employees with at least 6 months tenure
|
||||
- Managers approval required
|
||||
- Home office setup must meet security requirements
|
||||
|
||||
Work Schedule:
|
||||
- Core hours: 10 AM - 3 PM local time
|
||||
- Flexible start/end times outside core hours
|
||||
- Maximum 3 remote days per week for hybrid roles
|
||||
|
||||
Communication Requirements:
|
||||
- Daily check-ins with team lead
|
||||
- Weekly video conference participation
|
||||
- Response time: within 4 hours during business hours
|
||||
|
||||
Equipment and Security:
|
||||
- Company-provided laptop and VPN access
|
||||
- Secure Wi-Fi connection required
|
||||
- No public Wi-Fi for work activities
|
||||
|
||||
For questions about remote work policies, contact HR at hr@company.com
|
||||
"""
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Initialize the OpenAI client
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
# 2. Prepare file paths and create sample content
|
||||
pdf_file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))),
|
||||
"resources",
|
||||
"file_search",
|
||||
"employees.pdf",
|
||||
)
|
||||
|
||||
# Create a temporary text file for demonstration purposes
|
||||
with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as text_file:
|
||||
text_content = create_sample_text_content()
|
||||
text_file.write(text_content)
|
||||
text_file_path = text_file.name
|
||||
|
||||
try:
|
||||
# 3. Create BinaryContent objects from files using different methods
|
||||
print("Creating BinaryContent from files...")
|
||||
|
||||
# Method 1: Create BinaryContent from an existing PDF file
|
||||
pdf_binary_content = BinaryContent.from_file(file_path=pdf_file_path, mime_type="application/pdf")
|
||||
print(f"Created PDF BinaryContent: {pdf_binary_content.mime_type}, can_read: {pdf_binary_content.can_read}")
|
||||
|
||||
# Method 2: Create BinaryContent from the temporary text file
|
||||
text_binary_content = BinaryContent.from_file(file_path=text_file_path, mime_type="text/plain")
|
||||
print(f"Created text BinaryContent: {text_binary_content.mime_type}, can_read: {text_binary_content.can_read}")
|
||||
|
||||
# Method 3: Create BinaryContent directly from in-memory data
|
||||
# This approach allows creating BinaryContent without file I/O operations
|
||||
alternative_text_content = BinaryContent(
|
||||
data=text_content.encode("utf-8"), mime_type="text/plain", data_format="base64"
|
||||
)
|
||||
print(f"Alternative text BinaryContent: {alternative_text_content.mime_type}")
|
||||
|
||||
# 4. Initialize the OpenAI Responses Agent with file analysis capabilities
|
||||
# Configure the AI model for responses
|
||||
settings = OpenAISettings()
|
||||
responses_model = settings.responses_model_id or "gpt-4o"
|
||||
|
||||
agent = OpenAIResponsesAgent(
|
||||
ai_model_id=responses_model,
|
||||
client=client,
|
||||
instructions=(
|
||||
"You are a helpful assistant that can analyze uploaded files. "
|
||||
"When users upload files, examine their content and provide helpful insights. "
|
||||
"You can identify file types, summarize content, and answer questions about the files."
|
||||
),
|
||||
name="FileAnalyzer",
|
||||
)
|
||||
|
||||
# 5. Demonstrate multi-modal message composition
|
||||
# This showcases combining text and binary content in a single message
|
||||
|
||||
# Compose a message containing both text instructions and file attachments
|
||||
# This pattern is ideal for scenarios requiring rich, mixed-content interactions
|
||||
initial_message = ChatMessageContent(
|
||||
role=AuthorRole.USER,
|
||||
items=[
|
||||
TextContent(text="I'm uploading a PDF document and a text file for you to analyze."),
|
||||
pdf_binary_content,
|
||||
text_binary_content,
|
||||
],
|
||||
)
|
||||
|
||||
# 6. Conduct a conversation with the agent about the uploaded files
|
||||
thread = None
|
||||
|
||||
# Send the initial multi-modal message containing file uploads
|
||||
print("\n# User: 'I'm uploading a PDF document and a text file for you to analyze.'")
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(messages=initial_message, thread=thread):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print() # New line after response
|
||||
|
||||
# Continue the conversation with text-based follow-up questions
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"\n# User: '{user_input}'")
|
||||
|
||||
# Process follow-up questions using standard text input
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(messages=user_input, thread=thread):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print() # New line after response
|
||||
|
||||
finally:
|
||||
# 7. Clean up temporary resources
|
||||
if os.path.exists(text_file_path):
|
||||
os.unlink(text_file_path)
|
||||
|
||||
print("\n" + "=" * 60)
|
||||
print("Sample completed!")
|
||||
print("\nKey points about BinaryContent:")
|
||||
print("1. Use BinaryContent.from_file() to create from existing files")
|
||||
print("2. Use BinaryContent(data=...) to create from bytes/string data")
|
||||
print("3. Specify appropriate mime_type for proper handling")
|
||||
print("4. BinaryContent can be included in chat messages alongside text")
|
||||
print("5. The OpenAI Responses API will process supported file types")
|
||||
print("\nSupported file types include:")
|
||||
print("- PDF documents (application/pdf)")
|
||||
print("- Text files (text/plain)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
import os
|
||||
|
||||
from semantic_kernel.agents import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import OpenAISettings
|
||||
from semantic_kernel.contents.streaming_chat_message_content import StreamingChatMessageContent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent.
|
||||
The sample shows how to have the agent answer questions about the provided
|
||||
document with streaming responses.
|
||||
|
||||
The interaction with the agent is via the `get_response` method, which sends a
|
||||
user input to the agent and receives a response from the agent. The conversation
|
||||
history is maintained by the agent service, i.e. the responses are automatically
|
||||
associated with the thread. Therefore, client code does not need to maintain the
|
||||
conversation history.
|
||||
"""
|
||||
|
||||
|
||||
# Simulate a conversation with the agent
|
||||
USER_INPUTS = [
|
||||
"By birthday, who is the youngest employee?",
|
||||
"Who works in sales?",
|
||||
"I have a customer request, who can help me?",
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using OpenAI resources and configuration
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
pdf_file_path = os.path.join(
|
||||
os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "resources", "employees.pdf"
|
||||
)
|
||||
|
||||
with open(pdf_file_path, "rb") as file:
|
||||
file = await client.files.create(file=file, purpose="assistants")
|
||||
|
||||
vector_store = await client.vector_stores.create(
|
||||
name="step4_assistant_file_search",
|
||||
file_ids=[file.id],
|
||||
)
|
||||
|
||||
file_search_tool = OpenAIResponsesAgent.configure_file_search_tool(vector_store.id)
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = OpenAIResponsesAgent(
|
||||
ai_model_id=OpenAISettings().chat_model_id,
|
||||
client=client,
|
||||
instructions="Find answers to the user's questions in the provided file.",
|
||||
name="FileSearch",
|
||||
tools=[file_search_tool],
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
response_chunks: list[StreamingChatMessageContent] = []
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
# 4. Invoke the agent for the current message and print the response
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(messages=user_input, thread=thread):
|
||||
thread = response.thread
|
||||
response_chunks.append(response)
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
|
||||
"""
|
||||
# User: 'By birthday, who is the youngest employee?'
|
||||
# Agent: The youngest employee by birthday is Teodor Britton, born on January 9, 1997.
|
||||
# User: 'Who works in sales?'
|
||||
# Agent: The employees who work in sales are:
|
||||
|
||||
- Mariam Jaslyn, Sales Representative
|
||||
- Hicran Bea, Sales Manager
|
||||
- Angelino Embla, Sales Representative.
|
||||
# User: 'I have a customer request, who can help me?'
|
||||
# Agent: For a customer request, you could reach out to the following people in the sales department:
|
||||
|
||||
- Mariam Jaslyn, Sales Representative
|
||||
- Hicran Bea, Sales Manager
|
||||
- Angelino Embla, Sales Representative.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,115 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
from typing import Annotated
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AzureResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings
|
||||
from semantic_kernel.contents import AuthorRole, FunctionCallContent, FunctionResultContent
|
||||
from semantic_kernel.contents.chat_message_content import ChatMessageContent
|
||||
from semantic_kernel.functions import kernel_function
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI
|
||||
Responses Agent using either Azure OpenAI or OpenAI. The
|
||||
Responses Agent allow for function calling, the use of file search and a
|
||||
web search tool. Responses Agent Threads are used to manage the
|
||||
conversation state, similar to a Semantic Kernel Chat History.
|
||||
Additionally, the invoke configures a message callback
|
||||
to receive the conversation messages during invocation.
|
||||
"""
|
||||
|
||||
|
||||
# Define a sample plugin for the sample
|
||||
class MenuPlugin:
|
||||
"""A sample Menu Plugin used for the concept sample."""
|
||||
|
||||
@kernel_function(description="Provides a list of specials from the menu.")
|
||||
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
|
||||
return """
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
"""
|
||||
|
||||
@kernel_function(description="Provides the price of the requested menu item.")
|
||||
def get_item_price(
|
||||
self, menu_item: Annotated[str, "The name of the menu item."]
|
||||
) -> Annotated[str, "Returns the price of the menu item."]:
|
||||
return "$9.99"
|
||||
|
||||
|
||||
# This callback function will be called for each intermediate message,
|
||||
# which will allow one to handle FunctionCallContent and FunctionResultContent.
|
||||
# If the callback is not provided, the agent will return the final response
|
||||
# with no intermediate tool call steps.
|
||||
async def handle_intermediate_steps(message: ChatMessageContent) -> None:
|
||||
for item in message.items or []:
|
||||
if isinstance(item, FunctionResultContent):
|
||||
print(f"Function Result:> {item.result} for function: {item.name}")
|
||||
elif isinstance(item, FunctionCallContent):
|
||||
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
|
||||
else:
|
||||
print(f"{item}")
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using Azure OpenAI resources and configuration
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = AzureResponsesAgent(
|
||||
ai_model_id=AzureOpenAISettings().chat_deployment_name,
|
||||
client=client,
|
||||
name="Host",
|
||||
instructions="Answer questions about the menu.",
|
||||
plugins=[MenuPlugin()],
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
user_inputs = ["Hello", "What is the special soup?", "What is the special drink?", "How much is that?", "Thank you"]
|
||||
|
||||
try:
|
||||
for user_input in user_inputs:
|
||||
print(f"# {AuthorRole.USER}: '{user_input}'")
|
||||
async for response in agent.invoke(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
on_intermediate_message=handle_intermediate_steps,
|
||||
):
|
||||
thread = response.thread
|
||||
print(f"# {response.name}: {response.content}")
|
||||
finally:
|
||||
await thread.delete() if thread else None
|
||||
|
||||
"""
|
||||
Sample Output:
|
||||
|
||||
# AuthorRole.USER: 'Hello'
|
||||
# Host: Hi there! How can I assist you with the menu today?
|
||||
# AuthorRole.USER: 'What is the special soup?'
|
||||
Function Call:> MenuPlugin-get_specials with arguments: {}
|
||||
Function Result:>
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
for function: MenuPlugin-get_specials
|
||||
# Host: The special soup is Clam Chowder. Would you like to know more about any other specials?
|
||||
# AuthorRole.USER: 'What is the special drink?'
|
||||
# Host: The special drink is Chai Tea. Would you like any more information?
|
||||
# AuthorRole.USER: 'How much is that?'
|
||||
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Chai Tea"}
|
||||
Function Result:> $9.99 for function: MenuPlugin-get_item_price
|
||||
# Host: The Chai Tea is $9.99. Is there anything else you'd like to know?
|
||||
# AuthorRole.USER: 'Thank you'
|
||||
# Host: You're welcome! If you have any more questions, feel free to ask. Enjoy your day!
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
from typing import Annotated
|
||||
|
||||
from semantic_kernel.agents import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import OpenAISettings
|
||||
from semantic_kernel.contents import AuthorRole, FunctionCallContent, FunctionResultContent
|
||||
from semantic_kernel.contents.chat_message_content import ChatMessageContent
|
||||
from semantic_kernel.functions import kernel_function
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI
|
||||
Responses Agent using either Azure OpenAI or OpenAI. The
|
||||
Responses Agent allow for function calling, the use of file search and a
|
||||
web search tool. Responses Agent Threads are used to manage the
|
||||
conversation state, similar to a Semantic Kernel Chat History.
|
||||
Additionally, the invoke_stream configures a message callback
|
||||
to receive the conversation messages during streaming invocation.
|
||||
This sample also demonstrates the Responses Agent Streaming
|
||||
capability and how to manage a Responses Agent chat history.
|
||||
"""
|
||||
|
||||
|
||||
# Define a sample plugin for the sample
|
||||
class MenuPlugin:
|
||||
"""A sample Menu Plugin used for the concept sample."""
|
||||
|
||||
@kernel_function(description="Provides a list of specials from the menu.")
|
||||
def get_specials(self) -> Annotated[str, "Returns the specials from the menu."]:
|
||||
return """
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
"""
|
||||
|
||||
@kernel_function(description="Provides the price of the requested menu item.")
|
||||
def get_item_price(
|
||||
self, menu_item: Annotated[str, "The name of the menu item."]
|
||||
) -> Annotated[str, "Returns the price of the menu item."]:
|
||||
return "$9.99"
|
||||
|
||||
|
||||
# This callback function will be called for each intermediate message,
|
||||
# which will allow one to handle FunctionCallContent and FunctionResultContent.
|
||||
# If the callback is not provided, the agent will return the final response
|
||||
# with no intermediate tool call steps.
|
||||
async def handle_streaming_intermediate_steps(message: ChatMessageContent) -> None:
|
||||
for item in message.items or []:
|
||||
if isinstance(item, FunctionResultContent):
|
||||
print(f"Function Result:> {item.result} for function: {item.name}")
|
||||
elif isinstance(item, FunctionCallContent):
|
||||
print(f"Function Call:> {item.name} with arguments: {item.arguments}")
|
||||
else:
|
||||
print(f"{item}")
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using Azure OpenAI resources and configuration
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = OpenAIResponsesAgent(
|
||||
ai_model_id=OpenAISettings().chat_model_id,
|
||||
client=client,
|
||||
name="Host",
|
||||
instructions="Answer questions about the menu.",
|
||||
plugins=[MenuPlugin()],
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
user_inputs = ["Hello", "What is the special soup?", "What is the special drink?", "How much is that?", "Thank you"]
|
||||
|
||||
try:
|
||||
for user_input in user_inputs:
|
||||
print(f"# {AuthorRole.USER}: '{user_input}'")
|
||||
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(
|
||||
messages=user_input,
|
||||
thread=thread,
|
||||
on_intermediate_message=handle_streaming_intermediate_steps,
|
||||
):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
finally:
|
||||
await thread.delete() if thread else None
|
||||
|
||||
"""
|
||||
Sample Output:
|
||||
|
||||
# AuthorRole.USER: 'Hello'
|
||||
# Host: Hello! How can I assist you with the menu today?
|
||||
# AuthorRole.USER: 'What is the special soup?'
|
||||
Function Call:> MenuPlugin-get_specials with arguments: {}
|
||||
Function Result:>
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
for function: MenuPlugin-get_specials
|
||||
# Host: The special soup today is Clam Chowder. Would you like to know more about it or hear about other specials?
|
||||
# AuthorRole.USER: 'What is the special drink?'
|
||||
# Host: The special drink today is Chai Tea. Would you like more details or are you interested in ordering it?
|
||||
# AuthorRole.USER: 'How much is that?'
|
||||
Function Call:> MenuPlugin-get_item_price with arguments: {"menu_item":"Chai Tea"}
|
||||
Function Result:> $9.99 for function: MenuPlugin-get_item_price
|
||||
# Host: The special drink, Chai Tea, is $9.99. Would you like to order one or need information on something else?
|
||||
# AuthorRole.USER: 'Thank you'
|
||||
# Host: You're welcome! If you have any more questions or need help with the menu, just let me know. Enjoy your day!
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,100 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
from typing import Annotated
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AzureResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings
|
||||
from semantic_kernel.functions import kernel_function
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent.
|
||||
The sample shows how to have the agent answer questions about the sample menu
|
||||
with streaming responses.
|
||||
|
||||
The interaction with the agent is via the `get_response` method, which sends a
|
||||
user input to the agent and receives a response from the agent. The conversation
|
||||
history is maintained by the agent service, i.e. the responses are automatically
|
||||
associated with the thread. Therefore, client code does not need to maintain the
|
||||
conversation history.
|
||||
"""
|
||||
|
||||
|
||||
# Define a sample plugin for the sample
|
||||
class MenuPlugin:
|
||||
"""A sample Menu Plugin used for the concept sample."""
|
||||
|
||||
@kernel_function(description="Provides a list of specials from the menu.")
|
||||
def get_specials(self, menu_item: str) -> Annotated[str, "Returns the specials from the menu."]:
|
||||
return """
|
||||
Special Soup: Clam Chowder
|
||||
Special Salad: Cobb Salad
|
||||
Special Drink: Chai Tea
|
||||
"""
|
||||
|
||||
@kernel_function(description="Provides the price of the requested menu item.")
|
||||
def get_item_price(
|
||||
self, menu_item: Annotated[str, "The name of the menu item."]
|
||||
) -> Annotated[str, "Returns the price of the menu item."]:
|
||||
return "$9.99"
|
||||
|
||||
|
||||
# Simulate a conversation with the agent
|
||||
USER_INPUTS = [
|
||||
"Hello",
|
||||
"What is the special soup?",
|
||||
"What is the special drink?",
|
||||
"How much is it?",
|
||||
"Thank you",
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using OpenAI resources and configuration
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = AzureResponsesAgent(
|
||||
ai_model_id=AzureOpenAISettings().chat_deployment_name,
|
||||
client=client,
|
||||
instructions="Answer questions about the menu.",
|
||||
name="Host",
|
||||
plugins=[MenuPlugin()],
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
first_chunk = True
|
||||
# 4. Invoke the agent for the current message and print the response
|
||||
async for response in agent.invoke_stream(messages=user_input, thread=thread):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
|
||||
"""
|
||||
Sample Output:
|
||||
|
||||
# AuthorRole.USER: 'Hello'
|
||||
# Host: Hi there! How can I assist you with the menu today?
|
||||
# AuthorRole.USER: 'What is the special soup?'
|
||||
# Host: The special soup is Clam Chowder.
|
||||
# AuthorRole.USER: 'What is the special drink?'
|
||||
# Host: The special drink is Chai Tea.
|
||||
# AuthorRole.USER: 'How much is that?'
|
||||
# Host: The Chai Tea is $9.99. Would you like to know more about the menu?
|
||||
# AuthorRole.USER: 'Thank you'
|
||||
# Host: You're welcome! If you have any questions about the menu or need assistance, feel free to ask.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
@@ -0,0 +1,151 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
|
||||
from semantic_kernel.agents.open_ai.azure_responses_agent import AzureResponsesAgent
|
||||
from semantic_kernel.agents.open_ai.openai_responses_agent import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings, OpenAISettings
|
||||
from semantic_kernel.contents.reasoning_content import ReasoningContent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent
|
||||
with reasoning capabilities using either OpenAI or Azure OpenAI. The sample
|
||||
shows how to enable basic reasoning and reasoning with summaries, which exposes
|
||||
the agent's internal thought process via the on_intermediate_message callback.
|
||||
|
||||
Two reasoning configurations are demonstrated:
|
||||
|
||||
1. Basic reasoning:
|
||||
- Works for all OpenAI organizations
|
||||
- Reasoning happens internally but no intermediate thoughts are exposed
|
||||
- Still benefits from the model's reasoning process in final responses
|
||||
|
||||
2. Reasoning with summary:
|
||||
- Requires verified OpenAI organization access
|
||||
- Exposes the model's internal thought process via ReasoningContent
|
||||
- Shows step-by-step reasoning through the intermediate message callback
|
||||
|
||||
The reasoning content shows the internal thought process of models that
|
||||
support reasoning (like gpt-5, o3, o1-mini). This sample uses non-streaming
|
||||
invocation patterns.
|
||||
"""
|
||||
|
||||
|
||||
async def create_reasoning_agent():
|
||||
"""Create a reasoning-enabled agent without summary (works for all orgs)."""
|
||||
openai_settings = OpenAISettings()
|
||||
model_id = openai_settings.responses_model_id or openai_settings.chat_model_id
|
||||
if openai_settings.api_key and model_id:
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
return OpenAIResponsesAgent(
|
||||
ai_model_id=model_id,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high"},
|
||||
)
|
||||
|
||||
# Fallback to Azure OpenAI
|
||||
azure_settings = AzureOpenAISettings()
|
||||
if azure_settings.endpoint and azure_settings.responses_deployment_name:
|
||||
client = AzureResponsesAgent.create_client()
|
||||
return AzureResponsesAgent(
|
||||
ai_model_id=azure_settings.responses_deployment_name,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high"},
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
async def create_reasoning_agent_with_summary():
|
||||
"""Create a reasoning-enabled agent with summary (requires verified org)."""
|
||||
openai_settings = OpenAISettings()
|
||||
model_id = openai_settings.responses_model_id or openai_settings.chat_model_id
|
||||
if openai_settings.api_key and model_id:
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
return OpenAIResponsesAgent(
|
||||
ai_model_id=model_id,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high", "summary": "detailed"},
|
||||
)
|
||||
|
||||
azure_settings = AzureOpenAISettings()
|
||||
if azure_settings.endpoint and azure_settings.responses_deployment_name:
|
||||
client = AzureResponsesAgent.create_client()
|
||||
return AzureResponsesAgent(
|
||||
ai_model_id=azure_settings.responses_deployment_name,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high", "summary": "detailed"},
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
async def handle_reasoning_message(message):
|
||||
"""Handle reasoning content from the agent's intermediate messages.
|
||||
|
||||
This callback function will be called for each intermediate message
|
||||
when reasoning summaries are enabled, allowing access to the model's
|
||||
internal thought process via ReasoningContent items.
|
||||
|
||||
Args:
|
||||
message: The intermediate message containing potential ReasoningContent items.
|
||||
"""
|
||||
reasoning_items = [item for item in message.items if isinstance(item, ReasoningContent)]
|
||||
for reasoning in reasoning_items:
|
||||
if reasoning.text:
|
||||
print(f"\033[36m{reasoning.text}\033[0m", end="", flush=True)
|
||||
|
||||
|
||||
async def main():
|
||||
"""The main function that demonstrates OpenAI Reasoning responses."""
|
||||
# Define the query to test reasoning capabilities
|
||||
query = "Plan a birthday party for 15 people with a $500 budget. What are the key decisions I need to make?"
|
||||
|
||||
# 1. Create and use a basic reasoning agent
|
||||
try:
|
||||
reasoning_agent = await create_reasoning_agent()
|
||||
if not reasoning_agent:
|
||||
print("Failed to create reasoning agent. Please check your API configuration.")
|
||||
return
|
||||
|
||||
print("===== Basic Reasoning =====")
|
||||
print(f"Query: {query}")
|
||||
print("\nResponse:")
|
||||
await reasoning_agent.add_chat_message(content=query, role="user")
|
||||
reasoning_response = await reasoning_agent.invoke()
|
||||
print(f"{reasoning_response.content}")
|
||||
except Exception as e:
|
||||
print(f"Basic reasoning example failed. Error: {e}")
|
||||
print("Please check your API configuration and model availability.")
|
||||
return
|
||||
|
||||
# 2. Create and use a reasoning agent with summaries enabled
|
||||
try:
|
||||
reasoning_with_summary_agent = await create_reasoning_agent_with_summary()
|
||||
if not reasoning_with_summary_agent:
|
||||
print("Failed to create reasoning agent with summary. This requires verified OpenAI organization access.")
|
||||
print("===== Done! =====")
|
||||
return
|
||||
|
||||
print("\n\n===== Reasoning with Summaries =====")
|
||||
print(f"Query: {query}")
|
||||
print("\nReasoning summary:")
|
||||
await reasoning_with_summary_agent.add_chat_message(content=query, role="user")
|
||||
summary_response = await reasoning_with_summary_agent.invoke(handle_reasoning_message)
|
||||
print(f"\n\nAnswer: {summary_response.content}")
|
||||
except Exception as e:
|
||||
print(f"\nSummary examples require a verified organization. Error: {e}")
|
||||
print("The reasoning summary feature is only available to verified OpenAI organizations.")
|
||||
|
||||
print("\n\n===== Done! =====")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
|
||||
from semantic_kernel.agents.open_ai.azure_responses_agent import AzureResponsesAgent
|
||||
from semantic_kernel.agents.open_ai.openai_responses_agent import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings, OpenAISettings
|
||||
from semantic_kernel.contents.reasoning_content import ReasoningContent
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent
|
||||
with reasoning capabilities using streaming patterns with either OpenAI or
|
||||
Azure OpenAI. The sample shows how to enable basic reasoning and reasoning
|
||||
with summaries that stream the agent's internal thought process.
|
||||
|
||||
Two streaming reasoning configurations are demonstrated:
|
||||
|
||||
1. Basic reasoning streaming:
|
||||
- Works for all OpenAI organizations
|
||||
- Reasoning happens internally but no intermediate thoughts are exposed
|
||||
- Still benefits from the model's reasoning process in final responses
|
||||
- Uses invoke_stream for real-time response streaming
|
||||
|
||||
2. Reasoning with summary streaming:
|
||||
- Requires verified OpenAI organization access
|
||||
- Exposes the model's internal thought process via ReasoningContent
|
||||
- Shows step-by-step reasoning through the intermediate message callback
|
||||
- Streams both reasoning summaries and final responses in real-time
|
||||
|
||||
The reasoning content shows the internal thought process of models that
|
||||
support reasoning (like gpt-5, o3, o1-mini). This sample uses streaming
|
||||
invocation patterns with invoke_stream.
|
||||
"""
|
||||
|
||||
|
||||
async def create_reasoning_agent():
|
||||
"""Create a reasoning-enabled agent without summary (works for all orgs)."""
|
||||
openai_settings = OpenAISettings()
|
||||
model_id = openai_settings.responses_model_id or openai_settings.chat_model_id
|
||||
if openai_settings.api_key and model_id:
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
return OpenAIResponsesAgent(
|
||||
ai_model_id=model_id,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high"},
|
||||
)
|
||||
|
||||
azure_settings = AzureOpenAISettings()
|
||||
if azure_settings.endpoint and azure_settings.responses_deployment_name:
|
||||
client = AzureResponsesAgent.create_client()
|
||||
return AzureResponsesAgent(
|
||||
ai_model_id=azure_settings.responses_deployment_name,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high"},
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
async def create_reasoning_agent_with_summary():
|
||||
"""Create a reasoning-enabled agent with summaries (requires verified org)."""
|
||||
openai_settings = OpenAISettings()
|
||||
model_id = openai_settings.responses_model_id or openai_settings.chat_model_id
|
||||
if openai_settings.api_key and model_id:
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
return OpenAIResponsesAgent(
|
||||
ai_model_id=model_id,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high", "summary": "detailed"},
|
||||
)
|
||||
|
||||
azure_settings = AzureOpenAISettings()
|
||||
if azure_settings.endpoint and azure_settings.responses_deployment_name:
|
||||
client = AzureResponsesAgent.create_client()
|
||||
return AzureResponsesAgent(
|
||||
ai_model_id=azure_settings.responses_deployment_name,
|
||||
client=client,
|
||||
name="ReasoningAgent",
|
||||
instructions="You are a helpful assistant that thinks step-by-step.",
|
||||
reasoning={"effort": "high", "summary": "detailed"},
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
async def handle_reasoning_message(message):
|
||||
"""Handle reasoning content from the agent's intermediate messages during streaming.
|
||||
|
||||
This callback function will be called for each intermediate message
|
||||
when reasoning summaries are enabled, allowing access to the model's
|
||||
internal thought process via ReasoningContent items during streaming.
|
||||
|
||||
Args:
|
||||
message: The intermediate message containing potential ReasoningContent items.
|
||||
"""
|
||||
reasoning_items = [item for item in message.items if isinstance(item, ReasoningContent)]
|
||||
for reasoning in reasoning_items:
|
||||
if reasoning.text:
|
||||
print(f"\033[36m{reasoning.text}\033[0m", end="", flush=True)
|
||||
|
||||
|
||||
async def main():
|
||||
"""The main function that demonstrates OpenAI Reasoning responses with streaming."""
|
||||
print("OpenAI ResponsesAgent Reasoning (streaming)")
|
||||
print("=" * 60)
|
||||
|
||||
# 1. Create and use a basic reasoning agent with streaming
|
||||
try:
|
||||
agent = await create_reasoning_agent()
|
||||
if agent is None:
|
||||
print("No configuration detected. Set either OpenAI or Azure OpenAI environment variables:")
|
||||
print("- OpenAI: OPENAI_API_KEY and OPENAI_RESPONSES_MODEL_ID (or OPENAI_CHAT_MODEL_ID)")
|
||||
print("- Azure: AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_API_KEY and AZURE_OPENAI_RESPONSES_DEPLOYMENT_NAME")
|
||||
return
|
||||
|
||||
user_input = "Plan a weekend camping trip for 4 people. What essential items should we pack?"
|
||||
print(f"\n=== Basic reasoning (streaming, no summary) ===\n# User: '{user_input}'")
|
||||
thread = None
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(messages=user_input, thread=thread):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
except Exception as e:
|
||||
print(f"\nBasic reasoning example failed. Error: {e}")
|
||||
print("Please check your API configuration and model availability.")
|
||||
return
|
||||
|
||||
# 2. Create and use a reasoning agent with summaries and streaming
|
||||
try:
|
||||
agent_summary = await create_reasoning_agent_with_summary()
|
||||
if agent_summary is None:
|
||||
print("\nNo configuration available for reasoning summaries.")
|
||||
return
|
||||
|
||||
user_input2 = "Compare the benefits and drawbacks of renewable energy sources like solar and wind power."
|
||||
print(f"\n=== Reasoning with summaries (streaming) ===\n# User: '{user_input2}'")
|
||||
print("\nReasoning summary:")
|
||||
first_chunk = True
|
||||
async for response in agent_summary.invoke_stream(
|
||||
messages=user_input2, thread=thread, on_intermediate_message=handle_reasoning_message
|
||||
):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"\n# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
except Exception as e:
|
||||
print(f"\nSummary examples require a verified organization. Error: {e}")
|
||||
print("The reasoning summary feature is only available to verified OpenAI organizations.")
|
||||
|
||||
print("\n===== Done! =====")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
|
||||
from azure.identity import AzureCliCredential
|
||||
|
||||
from semantic_kernel.agents import AzureResponsesAgent, ResponsesAgentThread
|
||||
from semantic_kernel.connectors.ai.open_ai import AzureOpenAISettings
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent.
|
||||
The sample shows how to have the agent answer questions about the world.
|
||||
|
||||
Once initial questions are asked, the agent will continue to answer
|
||||
questions using the previous thread id. This is useful when you want to
|
||||
continue a conversation with the agent without having to create a new
|
||||
thread each time.
|
||||
"""
|
||||
|
||||
USER_INPUTS = [
|
||||
"My name is John Doe.",
|
||||
"Tell me a joke",
|
||||
"Explain why this is funny.",
|
||||
"What have we been talking about?",
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using Azure OpenAI resources and configuration
|
||||
client = AzureResponsesAgent.create_client(credential=AzureCliCredential())
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = AzureResponsesAgent(
|
||||
ai_model_id=AzureOpenAISettings().chat_deployment_name,
|
||||
client=client,
|
||||
instructions="Answer questions about from the user.",
|
||||
name="Joker",
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
# 4. Invoke the agent for the current message and print the response
|
||||
response = await agent.get_response(messages=user_input, thread=thread)
|
||||
print(f"# {response.name}: {response.content}")
|
||||
# 5. Update the thread so the previous response id is used
|
||||
thread = response.thread
|
||||
|
||||
# Continue with an existing thread id
|
||||
thread = ResponsesAgentThread(client=client, previous_response_id=thread.id)
|
||||
# 6. Ask the agent a new question to show the thread is still valid
|
||||
new_user_input = "What is my name?"
|
||||
print(f"# User: '{new_user_input}'")
|
||||
response = await agent.get_response(messages=new_user_input, thread=thread)
|
||||
print(f"# {response.name}: {response.content}")
|
||||
|
||||
"""
|
||||
You should see output similar to the following:
|
||||
|
||||
# User: 'My name is John Doe.'
|
||||
# Joker: Hello, John! How can I assist you today?
|
||||
# User: 'Tell me a joke'
|
||||
# Joker: Sure! Why don't scientists trust atoms?
|
||||
|
||||
Because they make up everything!
|
||||
# User: 'Explain why this is funny.'
|
||||
# Joker: The joke is funny because it plays on the double meaning of "make up." In one sense, atoms are the
|
||||
building blocks of all matter, so they literally "make up" everything. In another sense, "make up" can mean
|
||||
to fabricate or lie, humorously suggesting that atoms are untrustworthy because they "invent" or "fabricate"
|
||||
everything. This clever wordplay is what makes the joke amusing.
|
||||
# User: 'What have we been talking about?'
|
||||
# Joker: We've been discussing a joke about atoms and its humor, focusing on wordplay and double meanings.
|
||||
# User: 'What is my name?'
|
||||
# Joker: Your name is John Doe.
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
# Copyright (c) Microsoft. All rights reserved.
|
||||
import asyncio
|
||||
|
||||
from semantic_kernel.agents import OpenAIResponsesAgent
|
||||
from semantic_kernel.connectors.ai.open_ai import OpenAISettings
|
||||
|
||||
"""
|
||||
The following sample demonstrates how to create an OpenAI Responses Agent.
|
||||
The sample shows how to have the agent answer questions using the web search
|
||||
preview tool with streaming responses.
|
||||
|
||||
The interaction with the agent is via the `get_response` method, which sends a
|
||||
user input to the agent and receives a response from the agent. The conversation
|
||||
history is maintained by the agent service, i.e. the responses are automatically
|
||||
associated with the thread. Therefore, client code does not need to maintain the
|
||||
conversation history.
|
||||
"""
|
||||
|
||||
|
||||
# Simulate a conversation with the agent
|
||||
USER_INPUTS = [
|
||||
"Find me news articles about the latest technology trends.",
|
||||
]
|
||||
|
||||
|
||||
async def main():
|
||||
# 1. Create the client using OpenAI resources and configuration
|
||||
client = OpenAIResponsesAgent.create_client()
|
||||
|
||||
web_search_tool = OpenAIResponsesAgent.configure_web_search_tool()
|
||||
|
||||
# 2. Create a Semantic Kernel agent for the OpenAI Responses API
|
||||
agent = OpenAIResponsesAgent(
|
||||
ai_model_id=OpenAISettings().chat_model_id,
|
||||
client=client,
|
||||
instructions="Answer questions from the user.",
|
||||
name="Host",
|
||||
tools=[web_search_tool],
|
||||
)
|
||||
|
||||
# 3. Create a thread for the agent
|
||||
# If no thread is provided, a new thread will be
|
||||
# created and returned with the initial response
|
||||
thread = None
|
||||
|
||||
for user_input in USER_INPUTS:
|
||||
print(f"# User: '{user_input}'")
|
||||
# 4. Invoke the agent for the current message and print the response
|
||||
first_chunk = True
|
||||
async for response in agent.invoke_stream(messages=user_input, thread=thread):
|
||||
thread = response.thread
|
||||
if first_chunk:
|
||||
print(f"# {response.name}: ", end="", flush=True)
|
||||
first_chunk = False
|
||||
print(response.content, end="", flush=True)
|
||||
print()
|
||||
|
||||
"""
|
||||
You should see output similar to the following:
|
||||
|
||||
# User: 'Find me news articles about the latest technology trends.'
|
||||
# NewsSearcher: Recent developments in technology have highlighted several key trends shaping various industries:
|
||||
|
||||
**Artificial Intelligence (AI) Integration**: AI continues to revolutionize sectors by automating tasks,
|
||||
enhancing real-time analytics, and improving content delivery. At the 2025 NAB Show, AI's influence is
|
||||
evident across creator platforms, sports technology, streaming solutions, and cloud architectures.
|
||||
([tvtechnology.com](https://www.tvtechnology.com/news/nab-show-2025-exhibitor-insight-black-box?utm_source=openai))
|
||||
...
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
Reference in New Issue
Block a user