mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
Python: Add load_dotenv() to samples for .env file support (#4043)
* Initial plan * Add load_dotenv() to 303 Python samples for environment variable loading Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Update SAMPLE_GUIDELINES.md to document load_dotenv() requirement Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Update samples README.md to document .env file usage Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Run ruff format on all changed sample files Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Clarify load_dotenv() usage in README - local dev vs production Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Remove deprecated getting_started folder as requested Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Document env_file_path parameter for per-client configuration Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Merge main branch to resolve conflicts Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Fix run_evaluation.py file that was empty in merge commit Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Remove dotnet changes from merge - out of scope for this PR Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Remove package and test changes from merge - only sample changes needed Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Remove test_func_utils.py - only sample changes needed Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Revert sample files not in original changeset - keep only load_dotenv additions Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Move load_dotenv() outside snippet tag in 06_host_your_agent.py Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Fix comment placement - move load_dotenv before code comments Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Fix load_dotenv() placement across all samples - after docstring, before code comments Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Merge latest main branch with load_dotenv changes Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Remove non-sample changes from merge - keep only load_dotenv additions Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Revert non-load_dotenv sample changes from merge Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Fix run_evaluation.py - use main's improved version (file already had load_dotenv) Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> * Manual update * Manual update 2 * Fix Role usage and load_dotenv placement per PR review feedback Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Fix Role usage - use string literals not enum attributes Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Fix SAMPLE_GUIDELINES.md example - load_dotenv before docstring per guidance Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Move load_dotenv() before docstrings in all samples per SAMPLE_GUIDELINES ordering Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Address PR review: rename files, fix placement, add session usage, remove note Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> * Update Redis README to reference renamed file redis_history_provider.py Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: TaoChenOSU <12570346+TaoChenOSU@users.noreply.github.com> Co-authored-by: Tao Chen <taochen@microsoft.com> Co-authored-by: eavanvalkenburg <13749212+eavanvalkenburg@users.noreply.github.com> Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
This commit is contained in:
co-authored by
TaoChenOSU
eavanvalkenburg
copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Tao Chen
Eduard van Valkenburg
parent
3ea9c5fa5d
commit
b05fc9e849
@@ -51,6 +51,7 @@ from chatkit.types import (
|
||||
WidgetItem,
|
||||
)
|
||||
from chatkit.widgets import WidgetRoot
|
||||
from dotenv import load_dotenv
|
||||
from fastapi import FastAPI, File, Request, UploadFile
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import FileResponse, JSONResponse, Response, StreamingResponse
|
||||
@@ -64,6 +65,9 @@ from weather_widget import (
|
||||
weather_widget_copy_text,
|
||||
)
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
# ============================================================================
|
||||
# Configuration Constants
|
||||
# ============================================================================
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.ai.agentserver.agentframework import from_agent_framework # pyright: ignore[reportUnknownVariableType]
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -9,6 +9,7 @@ from agent_framework import AgentSession, BaseContextProvider, Message, SessionC
|
||||
from agent_framework.azure import AzureOpenAIChatClient
|
||||
from azure.ai.agentserver.agentframework import from_agent_framework # pyright: ignore[reportUnknownVariableType]
|
||||
from azure.identity import DefaultAzureCredential
|
||||
from dotenv import load_dotenv
|
||||
|
||||
if sys.version_info >= (3, 12):
|
||||
from typing import override
|
||||
@@ -16,6 +17,10 @@ else:
|
||||
from typing_extensions import override
|
||||
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
|
||||
@dataclass
|
||||
class TextSearchResult:
|
||||
source_name: str
|
||||
@@ -94,11 +99,7 @@ class TextSearchContextProvider(BaseContextProvider):
|
||||
|
||||
context.extend_messages(
|
||||
self.source_id,
|
||||
[
|
||||
Message(
|
||||
role="user", text="\n\n".join(json.dumps(result.__dict__, indent=2) for result in results)
|
||||
)
|
||||
],
|
||||
[Message(role="user", text="\n\n".join(json.dumps(result.__dict__, indent=2) for result in results))],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@ from agent_framework.azure import AzureOpenAIChatClient
|
||||
from agent_framework_orchestrations import ConcurrentBuilder
|
||||
from azure.ai.agentserver.agentframework import from_agent_framework
|
||||
from azure.identity import DefaultAzureCredential # pyright: ignore[reportUnknownVariableType]
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
@@ -22,6 +22,7 @@ from agent_framework import Agent, tool
|
||||
from agent_framework.openai import OpenAIChatClient
|
||||
from aiohttp import web
|
||||
from aiohttp.web_middlewares import middleware
|
||||
from dotenv import load_dotenv
|
||||
from microsoft_agents.activity import load_configuration_from_env
|
||||
from microsoft_agents.authentication.msal import MsalConnectionManager
|
||||
from microsoft_agents.hosting.aiohttp import CloudAdapter, start_agent_process
|
||||
@@ -36,6 +37,9 @@ from microsoft_agents.hosting.core import (
|
||||
)
|
||||
from pydantic import Field
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
"""
|
||||
Demo application using Microsoft Agent 365 SDK.
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ from azure.identity import (
|
||||
CertificateCredential,
|
||||
InteractiveBrowserCredential,
|
||||
)
|
||||
from dotenv import load_dotenv
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
|
||||
JOKER_NAME = "Joker"
|
||||
JOKER_INSTRUCTIONS = "You are good at telling jokes. Keep responses concise."
|
||||
@@ -164,9 +168,7 @@ async def run_with_agent_middleware() -> None:
|
||||
print("First response (agent middleware):\n", first)
|
||||
|
||||
second: AgentResponse = await agent.run(
|
||||
Message(
|
||||
role="user", text="That was funny. Tell me another one.", additional_properties={"user_id": user_id}
|
||||
)
|
||||
Message(role="user", text="That was funny. Tell me another one.", additional_properties={"user_id": user_id})
|
||||
)
|
||||
print("Second response (agent middleware):\n", second)
|
||||
|
||||
@@ -252,9 +254,7 @@ async def run_with_custom_cache_provider() -> None:
|
||||
print("Using SimpleDictCacheProvider")
|
||||
|
||||
first: AgentResponse = await agent.run(
|
||||
Message(
|
||||
role="user", text="Tell me a joke about a programmer.", additional_properties={"user_id": user_id}
|
||||
)
|
||||
Message(role="user", text="Tell me a joke about a programmer.", additional_properties={"user_id": user_id})
|
||||
)
|
||||
print("First response (custom provider):\n", first)
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ def search_hotels(
|
||||
"distance_to_eiffel_tower": "0.3 miles",
|
||||
"amenities": ["WiFi", "Breakfast", "Eiffel Tower View", "Concierge"],
|
||||
"availability": "Available",
|
||||
"address": "35 Rue Benjamin Franklin, 16th arr., Paris"
|
||||
"address": "35 Rue Benjamin Franklin, 16th arr., Paris",
|
||||
},
|
||||
{
|
||||
"name": "Mercure Paris Centre Tour Eiffel",
|
||||
@@ -47,7 +47,7 @@ def search_hotels(
|
||||
"distance_to_eiffel_tower": "0.5 miles",
|
||||
"amenities": ["WiFi", "Restaurant", "Bar", "Gym", "Air Conditioning"],
|
||||
"availability": "Available",
|
||||
"address": "20 Rue Jean Rey, 15th arr., Paris"
|
||||
"address": "20 Rue Jean Rey, 15th arr., Paris",
|
||||
},
|
||||
{
|
||||
"name": "Pullman Paris Tour Eiffel",
|
||||
@@ -57,8 +57,8 @@ def search_hotels(
|
||||
"distance_to_eiffel_tower": "0.2 miles",
|
||||
"amenities": ["WiFi", "Spa", "Gym", "Restaurant", "Rooftop Bar", "Concierge"],
|
||||
"availability": "Limited",
|
||||
"address": "18 Avenue de Suffren, 15th arr., Paris"
|
||||
}
|
||||
"address": "18 Avenue de Suffren, 15th arr., Paris",
|
||||
},
|
||||
]
|
||||
else:
|
||||
mock_hotels = [
|
||||
@@ -67,7 +67,7 @@ def search_hotels(
|
||||
"rating": 4.5,
|
||||
"price_per_night": "$150",
|
||||
"amenities": ["WiFi", "Pool", "Gym", "Restaurant"],
|
||||
"availability": "Available"
|
||||
"availability": "Available",
|
||||
}
|
||||
]
|
||||
|
||||
@@ -78,7 +78,7 @@ def search_hotels(
|
||||
"guests": guests,
|
||||
"hotels_found": len(mock_hotels),
|
||||
"hotels": mock_hotels,
|
||||
"note": "Hotel search results matching your query"
|
||||
"note": "Hotel search results matching your query",
|
||||
})
|
||||
|
||||
|
||||
@@ -104,10 +104,10 @@ def get_hotel_details(
|
||||
"recent_comments": [
|
||||
"Amazing location! Walked to Eiffel Tower in 5 minutes.",
|
||||
"Staff was incredibly helpful with restaurant recommendations.",
|
||||
"Rooms are cozy and clean with great views."
|
||||
]
|
||||
"Rooms are cozy and clean with great views.",
|
||||
],
|
||||
},
|
||||
"nearby_attractions": ["Eiffel Tower (0.3 mi)", "Trocadéro Gardens (0.2 mi)", "Seine River (0.4 mi)"]
|
||||
"nearby_attractions": ["Eiffel Tower (0.3 mi)", "Trocadéro Gardens (0.2 mi)", "Seine River (0.4 mi)"],
|
||||
},
|
||||
"Mercure Paris Centre Tour Eiffel": {
|
||||
"description": "Modern hotel with contemporary rooms and excellent dining options. Close to metro stations.",
|
||||
@@ -119,10 +119,10 @@ def get_hotel_details(
|
||||
"recent_comments": [
|
||||
"Great value for money, clean and comfortable.",
|
||||
"Restaurant had excellent French cuisine.",
|
||||
"Easy access to public transportation."
|
||||
]
|
||||
"Easy access to public transportation.",
|
||||
],
|
||||
},
|
||||
"nearby_attractions": ["Eiffel Tower (0.5 mi)", "Champ de Mars (0.4 mi)", "Les Invalides (0.8 mi)"]
|
||||
"nearby_attractions": ["Eiffel Tower (0.5 mi)", "Champ de Mars (0.4 mi)", "Les Invalides (0.8 mi)"],
|
||||
},
|
||||
"Pullman Paris Tour Eiffel": {
|
||||
"description": "Luxury hotel offering panoramic views, upscale amenities, and exceptional service. Ideal for a premium experience.",
|
||||
@@ -134,27 +134,27 @@ def get_hotel_details(
|
||||
"recent_comments": [
|
||||
"Rooftop bar has the best Eiffel Tower views in Paris!",
|
||||
"Luxurious rooms with every amenity you could want.",
|
||||
"Worth the price for the location and service."
|
||||
]
|
||||
"Worth the price for the location and service.",
|
||||
],
|
||||
},
|
||||
"nearby_attractions": ["Eiffel Tower (0.2 mi)", "Seine River Cruise Dock (0.3 mi)", "Trocadéro (0.5 mi)"]
|
||||
}
|
||||
"nearby_attractions": ["Eiffel Tower (0.2 mi)", "Seine River Cruise Dock (0.3 mi)", "Trocadéro (0.5 mi)"],
|
||||
},
|
||||
}
|
||||
|
||||
details = hotel_details.get(hotel_name, {
|
||||
"name": hotel_name,
|
||||
"description": "Comfortable hotel with modern amenities",
|
||||
"check_in_time": "3:00 PM",
|
||||
"check_out_time": "11:00 AM",
|
||||
"cancellation_policy": "Standard cancellation policy applies",
|
||||
"reviews": {"total": 0, "recent_comments": []},
|
||||
"nearby_attractions": []
|
||||
})
|
||||
details = hotel_details.get(
|
||||
hotel_name,
|
||||
{
|
||||
"name": hotel_name,
|
||||
"description": "Comfortable hotel with modern amenities",
|
||||
"check_in_time": "3:00 PM",
|
||||
"check_out_time": "11:00 AM",
|
||||
"cancellation_policy": "Standard cancellation policy applies",
|
||||
"reviews": {"total": 0, "recent_comments": []},
|
||||
"nearby_attractions": [],
|
||||
},
|
||||
)
|
||||
|
||||
return json.dumps({
|
||||
"hotel_name": hotel_name,
|
||||
"details": details
|
||||
})
|
||||
return json.dumps({"hotel_name": hotel_name, "details": details})
|
||||
|
||||
|
||||
# Mock flight search tool
|
||||
@@ -185,7 +185,7 @@ def search_flights(
|
||||
"duration": "7h 45m",
|
||||
"aircraft": "Boeing 777-300ER",
|
||||
"class": "Economy",
|
||||
"price": "$520"
|
||||
"price": "$520",
|
||||
},
|
||||
"return": {
|
||||
"flight_number": "AF008",
|
||||
@@ -195,11 +195,11 @@ def search_flights(
|
||||
"duration": "8h 15m",
|
||||
"aircraft": "Airbus A350-900",
|
||||
"class": "Economy",
|
||||
"price": "Included"
|
||||
"price": "Included",
|
||||
},
|
||||
"total_price": "$520",
|
||||
"stops": "Nonstop",
|
||||
"baggage": "1 checked bag included"
|
||||
"baggage": "1 checked bag included",
|
||||
},
|
||||
{
|
||||
"outbound": {
|
||||
@@ -210,7 +210,7 @@ def search_flights(
|
||||
"duration": "7h 50m",
|
||||
"aircraft": "Airbus A330-900neo",
|
||||
"class": "Economy",
|
||||
"price": "$485"
|
||||
"price": "$485",
|
||||
},
|
||||
"return": {
|
||||
"flight_number": "DL265",
|
||||
@@ -220,11 +220,11 @@ def search_flights(
|
||||
"duration": "8h 15m",
|
||||
"aircraft": "Airbus A330-900neo",
|
||||
"class": "Economy",
|
||||
"price": "Included"
|
||||
"price": "Included",
|
||||
},
|
||||
"total_price": "$485",
|
||||
"stops": "Nonstop",
|
||||
"baggage": "1 checked bag included"
|
||||
"baggage": "1 checked bag included",
|
||||
},
|
||||
{
|
||||
"outbound": {
|
||||
@@ -235,7 +235,7 @@ def search_flights(
|
||||
"duration": "7h 50m",
|
||||
"aircraft": "Boeing 767-400ER",
|
||||
"class": "Economy",
|
||||
"price": "$560"
|
||||
"price": "$560",
|
||||
},
|
||||
"return": {
|
||||
"flight_number": "UA58",
|
||||
@@ -245,15 +245,17 @@ def search_flights(
|
||||
"duration": "8h 15m",
|
||||
"aircraft": "Boeing 787-10",
|
||||
"class": "Economy",
|
||||
"price": "Included"
|
||||
"price": "Included",
|
||||
},
|
||||
"total_price": "$560",
|
||||
"stops": "Nonstop",
|
||||
"baggage": "1 checked bag included"
|
||||
}
|
||||
"baggage": "1 checked bag included",
|
||||
},
|
||||
]
|
||||
else:
|
||||
mock_flights = [{"flight_number": "XX123", "airline": "Generic Air", "price": "$400", "note": "Generic route"}]
|
||||
mock_flights = [
|
||||
{"flight_number": "XX123", "airline": "Generic Air", "price": "$400", "note": "Generic route"}
|
||||
]
|
||||
else:
|
||||
mock_flights = [
|
||||
{
|
||||
@@ -264,10 +266,10 @@ def search_flights(
|
||||
"arrival": f"{departure_date} at 2:30 PM",
|
||||
"duration": "5h 30m",
|
||||
"class": "Economy",
|
||||
"price": "$350"
|
||||
"price": "$350",
|
||||
},
|
||||
"total_price": "$350",
|
||||
"stops": "Nonstop"
|
||||
"stops": "Nonstop",
|
||||
}
|
||||
]
|
||||
|
||||
@@ -279,7 +281,7 @@ def search_flights(
|
||||
"passengers": passengers,
|
||||
"flights_found": len(mock_flights),
|
||||
"flights": mock_flights,
|
||||
"note": "Flight search results for JFK to Paris CDG"
|
||||
"note": "Flight search results for JFK to Paris CDG",
|
||||
})
|
||||
|
||||
|
||||
@@ -302,25 +304,20 @@ def get_flight_details(
|
||||
"airport": "JFK International Airport",
|
||||
"terminal": "Terminal 4",
|
||||
"gate": "B23",
|
||||
"time": "08:00 AM"
|
||||
"time": "08:00 AM",
|
||||
},
|
||||
"arrival": {
|
||||
"airport": "Charles de Gaulle Airport",
|
||||
"terminal": "Terminal 2E",
|
||||
"gate": "K15",
|
||||
"time": "11:30 AM local time"
|
||||
"time": "11:30 AM local time",
|
||||
},
|
||||
"duration": "3h 30m",
|
||||
"baggage_allowance": {
|
||||
"carry_on": "1 bag (10kg)",
|
||||
"checked": "1 bag (23kg)"
|
||||
},
|
||||
"amenities": ["WiFi", "In-flight entertainment", "Meals included"]
|
||||
"baggage_allowance": {"carry_on": "1 bag (10kg)", "checked": "1 bag (23kg)"},
|
||||
"amenities": ["WiFi", "In-flight entertainment", "Meals included"],
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"flight_details": mock_details
|
||||
})
|
||||
return json.dumps({"flight_details": mock_details})
|
||||
|
||||
|
||||
# Mock activity search tool
|
||||
@@ -328,7 +325,9 @@ def get_flight_details(
|
||||
def search_activities(
|
||||
location: Annotated[str, Field(description="City or region to search for activities.")],
|
||||
date: Annotated[str | None, Field(description="Date for the activity (e.g., 'December 16, 2025').")] = None,
|
||||
category: Annotated[str | None, Field(description="Activity category (e.g., 'Sightseeing', 'Culture', 'Culinary').")] = None,
|
||||
category: Annotated[
|
||||
str | None, Field(description="Activity category (e.g., 'Sightseeing', 'Culture', 'Culinary').")
|
||||
] = None,
|
||||
) -> str:
|
||||
"""Search for available activities and attractions at a destination.
|
||||
|
||||
@@ -348,7 +347,7 @@ def search_activities(
|
||||
"description": "Skip-the-line access to all three levels including the summit. Best views of Paris!",
|
||||
"availability": "Daily 9:30 AM - 11:00 PM",
|
||||
"best_time": "Early morning or sunset",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Louvre Museum Guided Tour",
|
||||
@@ -359,7 +358,7 @@ def search_activities(
|
||||
"description": "Expert-guided tour covering masterpieces including Mona Lisa and Venus de Milo.",
|
||||
"availability": "Daily except Tuesdays, 9:00 AM entry",
|
||||
"best_time": "Morning entry recommended",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Seine River Cruise",
|
||||
@@ -370,7 +369,7 @@ def search_activities(
|
||||
"description": "Scenic cruise past Notre-Dame, Eiffel Tower, and historic bridges.",
|
||||
"availability": "Every 30 minutes, 10:00 AM - 10:00 PM",
|
||||
"best_time": "Evening for illuminated monuments",
|
||||
"booking_required": False
|
||||
"booking_required": False,
|
||||
},
|
||||
{
|
||||
"name": "Musée d'Orsay Visit",
|
||||
@@ -381,7 +380,7 @@ def search_activities(
|
||||
"description": "Impressionist masterpieces in a stunning Beaux-Arts railway station.",
|
||||
"availability": "Tuesday-Sunday 9:30 AM - 6:00 PM",
|
||||
"best_time": "Weekday mornings",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Versailles Palace Day Trip",
|
||||
@@ -392,7 +391,7 @@ def search_activities(
|
||||
"description": "Explore the opulent palace and stunning gardens of Louis XIV (includes transport).",
|
||||
"availability": "Daily except Mondays, 8:00 AM departure",
|
||||
"best_time": "Full day trip",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Montmartre Walking Tour",
|
||||
@@ -403,7 +402,7 @@ def search_activities(
|
||||
"description": "Discover the artistic heart of Paris, including Sacré-Cœur and artists' square.",
|
||||
"availability": "Daily at 10:00 AM and 2:00 PM",
|
||||
"best_time": "Morning or late afternoon",
|
||||
"booking_required": False
|
||||
"booking_required": False,
|
||||
},
|
||||
{
|
||||
"name": "French Cooking Class",
|
||||
@@ -414,7 +413,7 @@ def search_activities(
|
||||
"description": "Learn to make classic French dishes like coq au vin and crème brûlée, then enjoy your creations.",
|
||||
"availability": "Tuesday-Saturday, 10:00 AM and 6:00 PM sessions",
|
||||
"best_time": "Morning or evening sessions",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Wine & Cheese Tasting",
|
||||
@@ -425,7 +424,7 @@ def search_activities(
|
||||
"description": "Sample French wines and artisanal cheeses with expert sommelier guidance.",
|
||||
"availability": "Daily at 5:00 PM and 7:30 PM",
|
||||
"best_time": "Evening sessions",
|
||||
"booking_required": True
|
||||
"booking_required": True,
|
||||
},
|
||||
{
|
||||
"name": "Food Market Tour",
|
||||
@@ -436,8 +435,8 @@ def search_activities(
|
||||
"description": "Explore authentic Parisian markets and taste local specialties like cheeses, pastries, and charcuterie.",
|
||||
"availability": "Tuesday, Thursday, Saturday mornings",
|
||||
"best_time": "Morning (markets are freshest)",
|
||||
"booking_required": False
|
||||
}
|
||||
"booking_required": False,
|
||||
},
|
||||
]
|
||||
|
||||
activities = [act for act in all_activities if act["category"] == category] if category else all_activities
|
||||
@@ -450,7 +449,7 @@ def search_activities(
|
||||
"price": "$45",
|
||||
"rating": 4.7,
|
||||
"description": "Explore the historic downtown area with an expert guide",
|
||||
"availability": "Daily at 10:00 AM and 2:00 PM"
|
||||
"availability": "Daily at 10:00 AM and 2:00 PM",
|
||||
}
|
||||
]
|
||||
|
||||
@@ -460,7 +459,7 @@ def search_activities(
|
||||
"category": category,
|
||||
"activities_found": len(activities),
|
||||
"activities": activities,
|
||||
"note": "Activity search results for Paris with sightseeing, culture, and culinary options"
|
||||
"note": "Activity search results for Paris with sightseeing, culture, and culinary options",
|
||||
})
|
||||
|
||||
|
||||
@@ -489,56 +488,68 @@ def get_activity_details(
|
||||
"languages": ["English", "French", "Spanish", "German", "Italian"],
|
||||
"max_group_size": "No limit",
|
||||
"rating": 4.8,
|
||||
"reviews_count": 15234
|
||||
"reviews_count": 15234,
|
||||
},
|
||||
"Louvre Museum Guided Tour": {
|
||||
"name": "Louvre Museum Guided Tour",
|
||||
"description": "Expert-guided tour of the world's largest art museum, focusing on must-see masterpieces including Mona Lisa, Venus de Milo, and Winged Victory.",
|
||||
"duration": "3 hours",
|
||||
"price": "$55 per person",
|
||||
"included": ["Skip-the-line entry", "Expert art historian guide", "Headsets for groups over 6", "Museum highlights map"],
|
||||
"included": [
|
||||
"Skip-the-line entry",
|
||||
"Expert art historian guide",
|
||||
"Headsets for groups over 6",
|
||||
"Museum highlights map",
|
||||
],
|
||||
"meeting_point": "Glass Pyramid main entrance, look for guide with 'Louvre Tours' sign",
|
||||
"what_to_bring": ["Photo ID", "Comfortable shoes", "Camera (no flash)", "Water bottle"],
|
||||
"cancellation_policy": "Free cancellation up to 48 hours in advance",
|
||||
"languages": ["English", "French", "Spanish"],
|
||||
"max_group_size": 20,
|
||||
"rating": 4.7,
|
||||
"reviews_count": 8921
|
||||
"reviews_count": 8921,
|
||||
},
|
||||
"French Cooking Class": {
|
||||
"name": "French Cooking Class",
|
||||
"description": "Hands-on cooking experience where you'll learn to prepare classic French dishes like coq au vin, ratatouille, and crème brûlée under expert chef guidance.",
|
||||
"duration": "3 hours",
|
||||
"price": "$120 per person",
|
||||
"included": ["All ingredients", "Chef instruction", "Apron and recipe booklet", "Wine pairing", "Lunch/dinner of your creations"],
|
||||
"included": [
|
||||
"All ingredients",
|
||||
"Chef instruction",
|
||||
"Apron and recipe booklet",
|
||||
"Wine pairing",
|
||||
"Lunch/dinner of your creations",
|
||||
],
|
||||
"meeting_point": "Le Chef Cooking Studio, 15 Rue du Bac, 7th arrondissement",
|
||||
"what_to_bring": ["Appetite", "Camera for food photos"],
|
||||
"cancellation_policy": "Free cancellation up to 72 hours in advance",
|
||||
"languages": ["English", "French"],
|
||||
"max_group_size": 12,
|
||||
"rating": 4.9,
|
||||
"reviews_count": 2341
|
||||
}
|
||||
"reviews_count": 2341,
|
||||
},
|
||||
}
|
||||
|
||||
details = activity_details_map.get(activity_name, {
|
||||
"name": activity_name,
|
||||
"description": "An immersive experience that showcases the best of local culture and attractions.",
|
||||
"duration": "3 hours",
|
||||
"price": "$45 per person",
|
||||
"included": ["Professional guide", "Entry fees"],
|
||||
"meeting_point": "Central meeting location",
|
||||
"what_to_bring": ["Comfortable shoes", "Camera"],
|
||||
"cancellation_policy": "Free cancellation up to 24 hours in advance",
|
||||
"languages": ["English"],
|
||||
"max_group_size": 15,
|
||||
"rating": 4.5,
|
||||
"reviews_count": 100
|
||||
})
|
||||
details = activity_details_map.get(
|
||||
activity_name,
|
||||
{
|
||||
"name": activity_name,
|
||||
"description": "An immersive experience that showcases the best of local culture and attractions.",
|
||||
"duration": "3 hours",
|
||||
"price": "$45 per person",
|
||||
"included": ["Professional guide", "Entry fees"],
|
||||
"meeting_point": "Central meeting location",
|
||||
"what_to_bring": ["Comfortable shoes", "Camera"],
|
||||
"cancellation_policy": "Free cancellation up to 24 hours in advance",
|
||||
"languages": ["English"],
|
||||
"max_group_size": 15,
|
||||
"rating": 4.5,
|
||||
"reviews_count": 100,
|
||||
},
|
||||
)
|
||||
|
||||
return json.dumps({
|
||||
"activity_details": details
|
||||
})
|
||||
return json.dumps({"activity_details": details})
|
||||
|
||||
|
||||
# Mock booking confirmation tool
|
||||
@@ -566,13 +577,11 @@ def confirm_booking(
|
||||
"next_steps": [
|
||||
"Check your email for booking details",
|
||||
"Arrive 30 minutes before scheduled time",
|
||||
"Bring confirmation number and valid ID"
|
||||
]
|
||||
"Bring confirmation number and valid ID",
|
||||
],
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"confirmation": confirmation_data
|
||||
})
|
||||
return json.dumps({"confirmation": confirmation_data})
|
||||
|
||||
|
||||
# Mock hotel availability check tool
|
||||
@@ -602,12 +611,10 @@ def check_hotel_availability(
|
||||
"status": availability_status,
|
||||
"available_rooms": 8,
|
||||
"price_per_night": "$185",
|
||||
"last_checked": datetime.now().isoformat()
|
||||
"last_checked": datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"availability": availability_data
|
||||
})
|
||||
return json.dumps({"availability": availability_data})
|
||||
|
||||
|
||||
# Mock flight availability check tool
|
||||
@@ -635,12 +642,10 @@ def check_flight_availability(
|
||||
"status": availability_status,
|
||||
"available_seats": 45,
|
||||
"price_per_passenger": "$520",
|
||||
"last_checked": datetime.now().isoformat()
|
||||
"last_checked": datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"availability": availability_data
|
||||
})
|
||||
return json.dumps({"availability": availability_data})
|
||||
|
||||
|
||||
# Mock activity availability check tool
|
||||
@@ -668,12 +673,10 @@ def check_activity_availability(
|
||||
"status": availability_status,
|
||||
"available_spots": 15,
|
||||
"price_per_person": "$45",
|
||||
"last_checked": datetime.now().isoformat()
|
||||
"last_checked": datetime.now().isoformat(),
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"availability": availability_data
|
||||
})
|
||||
return json.dumps({"availability": availability_data})
|
||||
|
||||
|
||||
# Mock payment processing tool
|
||||
@@ -701,12 +704,10 @@ def process_payment(
|
||||
"last_4_digits": payment_method.get("last_4", "****"),
|
||||
"booking_reference": booking_reference,
|
||||
"timestamp": datetime.now().isoformat(),
|
||||
"receipt_url": f"https://payments.travelagency.com/receipt/{transaction_id}"
|
||||
"receipt_url": f"https://payments.travelagency.com/receipt/{transaction_id}",
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"payment_result": payment_result
|
||||
})
|
||||
return json.dumps({"payment_result": payment_result})
|
||||
|
||||
|
||||
# Mock payment validation tool
|
||||
@@ -742,9 +743,7 @@ def validate_payment_method(
|
||||
"payment_method_type": method_type,
|
||||
"validation_messages": validation_messages if not is_valid else ["Payment method is valid"],
|
||||
"supported_currencies": ["USD", "EUR", "GBP", "JPY"],
|
||||
"processing_fee": "2.5%"
|
||||
"processing_fee": "2.5%",
|
||||
}
|
||||
|
||||
return json.dumps({
|
||||
"validation_result": validation_result
|
||||
})
|
||||
return json.dumps({"validation_result": validation_result})
|
||||
|
||||
@@ -162,15 +162,13 @@ def run_evaluation(
|
||||
"data_mapping": {"response_id": "{{item.resp_id}}"},
|
||||
"source": {
|
||||
"type": "file_content",
|
||||
"content": [{"item": {"resp_id": resp_id}} for resp_id in selected_response_ids]
|
||||
"content": [{"item": {"resp_id": resp_id}} for resp_id in selected_response_ids],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
eval_run = openai_client.evals.runs.create(
|
||||
eval_id=eval_object.id,
|
||||
name="Multi-Agent Response Evaluation",
|
||||
data_source=data_source
|
||||
eval_id=eval_object.id, name="Multi-Agent Response Evaluation", data_source=data_source
|
||||
)
|
||||
|
||||
print(f"Evaluation run created: {eval_run.id}")
|
||||
@@ -183,10 +181,7 @@ def monitor_evaluation(openai_client: OpenAI, eval_object: EvalCreateResponse, e
|
||||
print("Waiting for evaluation to complete...")
|
||||
|
||||
while eval_run.status not in ["completed", "failed"]:
|
||||
eval_run = openai_client.evals.runs.retrieve(
|
||||
run_id=eval_run.id,
|
||||
eval_id=eval_object.id
|
||||
)
|
||||
eval_run = openai_client.evals.runs.retrieve(run_id=eval_run.id, eval_id=eval_object.id)
|
||||
print(f"Status: {eval_run.status}")
|
||||
time.sleep(5)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user