-
Notifications
You must be signed in to change notification settings - Fork 227
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #212 from Azure-Samples/gk/agents
add function calling example and logic apps workflow
- Loading branch information
Showing
20 changed files
with
1,101 additions
and
487 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"recommendations": [ | ||
"ms-azuretools.vscode-azurefunctions", | ||
"ms-python.python" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
{ | ||
"version": "0.2.0", | ||
"configurations": [ | ||
{ | ||
"name": ".NET Core Launch (web)", | ||
"type": "coreclr", | ||
"request": "launch", | ||
"preLaunchTask": "build", | ||
"program": "${workspaceFolder}/dotnet/recommendation-service/bin/Debug/net7.0/GBB.Miyagi.RecommendationService.dll", | ||
"args": [ | ||
"--verbose" | ||
], | ||
"cwd": "${workspaceFolder}/dotnet/recommendation-service", | ||
"stopAtEntry": false, | ||
"serverReadyAction": { | ||
"action": "openExternally", | ||
"pattern": "\\bNow listening on:\\s+(https?://\\S+)" | ||
}, | ||
"env": { | ||
"ASPNETCORE_ENVIRONMENT": "Development" | ||
}, | ||
"sourceFileMap": { | ||
"/Views": "${workspaceFolder}/Views" | ||
} | ||
}, | ||
{ | ||
"name": ".NET Core Attach", | ||
"type": "coreclr", | ||
"request": "attach" | ||
}, | ||
{ | ||
"name": "Attach to Python Functions", | ||
"type": "python", | ||
"request": "attach", | ||
"port": 9091, | ||
"preLaunchTask": "func: host start" | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
{ | ||
"version": "2.0.0", | ||
"tasks": [ | ||
{ | ||
"label": "build", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"build", | ||
"${workspaceFolder}/dotnet/recommendation-service/GBB.Miyagi.RecommendationService.csproj", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "publish", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"publish", | ||
"${workspaceFolder}/dotnet/recommendation-service/GBB.Miyagi.RecommendationService.csproj", | ||
"/property:GenerateFullPaths=true", | ||
"/consoleloggerparameters:NoSummary" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"label": "watch", | ||
"command": "dotnet", | ||
"type": "process", | ||
"args": [ | ||
"watch", | ||
"run", | ||
"--project", | ||
"${workspaceFolder}/dotnet/recommendation-service/GBB.Miyagi.RecommendationService.csproj" | ||
], | ||
"problemMatcher": "$msCompile" | ||
}, | ||
{ | ||
"type": "func", | ||
"label": "func: host start", | ||
"command": "host start", | ||
"problemMatcher": "$func-python-watch", | ||
"isBackground": true, | ||
"dependsOn": "pip install (functions)", | ||
"options": { | ||
"cwd": "${workspaceFolder}/sandbox\\agents\\plugins" | ||
} | ||
}, | ||
{ | ||
"label": "pip install (functions)", | ||
"type": "shell", | ||
"osx": { | ||
"command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt" | ||
}, | ||
"windows": { | ||
"command": "${config:azureFunctions.pythonVenv}\\Scripts\\python -m pip install -r requirements.txt" | ||
}, | ||
"linux": { | ||
"command": "${config:azureFunctions.pythonVenv}/bin/python -m pip install -r requirements.txt" | ||
}, | ||
"problemMatcher": [], | ||
"options": { | ||
"cwd": "${workspaceFolder}/sandbox\\agents\\plugins" | ||
} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
OPENAI_API_KEY=<your-api-key> | ||
OPENAI_MODEL_NAME=<your-model-name> | ||
OPENAI_ENDPOINT=<your-endpoint> | ||
OPENAI_ENDPOINT=<your-endpoint> | ||
DATA_COLLECTION_LOGIC_APPS_URI=<your-logic-app-workflow-uri> |
110 changes: 110 additions & 0 deletions
110
sandbox/agents/assistants-api/azure-openai/azure_ai_util.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
# azure_ai_utils.py | ||
import io | ||
import matplotlib.pyplot as plt | ||
from typing import Iterable | ||
from pathlib import Path | ||
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type | ||
|
||
# Import AzureOpenAI and assistant-related Message classes | ||
from openai import AzureOpenAI | ||
from openai.types.beta.threads.message_content_image_file import MessageContentImageFile | ||
from openai.types.beta.threads.message_content_text import MessageContentText | ||
from openai.types.beta.threads.messages import MessageFile | ||
|
||
|
||
class NotCompletedException(Exception): | ||
"""Custom exception for handling incomplete run statuses.""" | ||
pass | ||
|
||
|
||
class AzureAIUtils: | ||
""" | ||
A utility class for various Azure AI operations including | ||
message formatting, file uploading, and lifecycle status checking. | ||
""" | ||
|
||
def __init__(self, client: AzureOpenAI): | ||
""" | ||
Initialize the utility class with an AzureOpenAI client. | ||
Parameters: | ||
client (AzureOpenAI): An instance of the AzureOpenAI client. | ||
""" | ||
self.client = client | ||
|
||
def format_response(self, messages: Iterable[MessageFile]) -> None: | ||
""" | ||
Formats and prints the content of messages from AzureOpenAI. | ||
Parameters: | ||
messages (Iterable[MessageFile]): An iterable of MessageFile objects. | ||
""" | ||
message_list = [] | ||
|
||
for message in messages: | ||
message_list.append(message) | ||
if message.role == "user": | ||
break | ||
|
||
message_list.reverse() | ||
|
||
for message in message_list: | ||
for item in message.content: | ||
if isinstance(item, MessageContentText): | ||
print(f"{message.role}:\n{item.text.value}\n") | ||
elif isinstance(item, MessageContentImageFile): | ||
try: | ||
response_content = self.client.files.content( | ||
item.image_file.file_id | ||
) | ||
data_in_bytes = response_content.read() | ||
readable_buffer = io.BytesIO(data_in_bytes) | ||
image = plt.imread(readable_buffer, format="jpeg") | ||
plt.imshow(image) | ||
plt.axis("off") | ||
plt.show() | ||
except Exception as e: | ||
print(f"Exception: {e}") | ||
|
||
def upload_file(self, path: Path): | ||
""" | ||
Uploads a file to AzureOpenAI. | ||
Parameters: | ||
path (Path): The path to the file to be uploaded. | ||
Returns: | ||
FileObject: The file object created in AzureOpenAI. | ||
""" | ||
with path.open("rb") as f: | ||
return self.client.files.create(file=f, purpose="assistants") | ||
|
||
@retry( | ||
stop=stop_after_attempt(15), | ||
wait=wait_exponential(multiplier=1.5, min=4, max=20), | ||
retry=retry_if_exception_type(NotCompletedException), | ||
) | ||
def get_run_lifecycle_status(self, thread_id, run_id): | ||
""" | ||
Retrieves and prints the lifecycle status of a run and | ||
retries based on specific conditions. | ||
Parameters: | ||
thread_id: The ID of the thread. | ||
run_id: The ID of the run. | ||
Returns: | ||
The run object if its status is 'completed', 'failed', 'expired', or 'cancelled'. | ||
Raises: | ||
NotCompletedException: If the run is not yet completed. | ||
""" | ||
run = self.client.beta.threads.runs.retrieve(thread_id=thread_id, run_id=run_id) | ||
print(f"Run status: {run.status}") | ||
if run.status in ["completed", "failed", "expired", "cancelled"]: | ||
print(f"Run info: {run}") | ||
return run | ||
elif run.status == "requires_action": | ||
pass # Handle cases that require action differently | ||
else: | ||
raise NotCompletedException("Run not completed yet") |
Oops, something went wrong.