Skip to content

Commit

Permalink
Merge pull request #212 from Azure-Samples/gk/agents
Browse files Browse the repository at this point in the history
add function calling example and logic apps workflow
  • Loading branch information
thegovind committed Feb 13, 2024
2 parents c952c1d + fb8ca90 commit 8249754
Show file tree
Hide file tree
Showing 20 changed files with 1,101 additions and 487 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ tfplan
*.crt
*.pub
id_rsa
.vscode/

python/expense-classification-guidance/.env

python/expense-classification-guidance/.idea/
Expand All @@ -389,3 +389,5 @@ sandbox/usecases/rag/dotnet/.env
sandbox/notebooks/prompt-engineering/dotnet/.env

sandbox/prompt-engineering/notebooks/prompt-engineering/dotnet/.env

.vscode/settings.json
6 changes: 6 additions & 0 deletions .vscode/extensions.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"recommendations": [
"ms-azuretools.vscode-azurefunctions",
"ms-python.python"
]
}
39 changes: 39 additions & 0 deletions .vscode/launch.json
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"
}
]
}
69 changes: 69 additions & 0 deletions .vscode/tasks.json
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"
}
}
]
}
3 changes: 2 additions & 1 deletion sandbox/agents/assistants-api/azure-openai/.env.sample
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 sandbox/agents/assistants-api/azure-openai/azure_ai_util.py
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")
Loading

0 comments on commit 8249754

Please sign in to comment.