Files
wehub-resource-sync 85742ab165
Deploy Documentation / deploy (push) Has been cancelled
CPU Test / Test (Utilities, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (LLM proxy, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Others, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, latest, Python 3.13) (push) Has been cancelled
Dashboard / Chromatic (push) Has been cancelled
CPU Test / Lint - fast (push) Has been cancelled
CPU Test / Lint - next (push) Has been cancelled
CPU Test / Lint - slow (push) Has been cancelled
CPU Test / Lint - JavaScript (push) Has been cancelled
CPU Test / Build documentation (push) Has been cancelled
CPU Test / Test (AgentOps, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (LLM proxy, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Others, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Store, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (Weave, legacy, Python 3.10) (push) Has been cancelled
CPU Test / Test (AgentOps, stable, Python 3.11) (push) Has been cancelled
CPU Test / Test (Store, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Utilities, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (Weave, stable, Python 3.12) (push) Has been cancelled
CPU Test / Test (AgentOps, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (LLM proxy, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Others, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Store, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (Utilities, latest, Python 3.13) (push) Has been cancelled
CPU Test / Test (JavaScript) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:44:17 +08:00

177 lines
5.5 KiB
Python

# Copyright (c) Microsoft. All rights reserved.
"""An example of agent using Azure OpenAI with tool calls to look up capital cities.
Running this script directly will run a few sample tasks using the `capital_agent`,
which will test the healthiness of your Azure OpenAI setup.
Remember to have the following environment variables set:
- `AZURE_OPENAI_API_KEY`: Your Azure OpenAI API key.
- `AZURE_OPENAI_ENDPOINT`: Your Azure OpenAI endpoint URL.
"""
import asyncio
import json
import os
from typing import List, TypedDict, cast
import openai
import pandas as pd
from openai.types.chat import (
ChatCompletionMessageFunctionToolCallParam,
ChatCompletionMessageParam,
ChatCompletionToolMessageParam,
ChatCompletionToolParam,
)
from rich.console import Console
from agentlightning import LLM, AgentOpsTracer, InMemoryLightningStore, LitAgentRunner, rollout
CAPITALS = {
"japan": "Tokyo",
"france": "Paris",
"canada": "Ottawa",
"australia": "Canberra",
"brazil": "Brasília",
"egypt": "Cairo",
"kenya": "Nairobi",
"spain": "Madrid",
"italy": "Rome",
"germany": "Berlin",
"south korea": "Seoul",
"india": "New Delhi",
}
console = Console()
def country_capital_lookup(country: str) -> str:
return CAPITALS.get(country.strip().lower(), "Unknown")
class CapitalTask(TypedDict):
input: str
output: str
TOOLS: List[ChatCompletionToolParam] = [
{
"type": "function",
"function": {
"name": "country_capital_lookup",
"description": "Get the capital city of a given country.",
"parameters": {"type": "object", "properties": {"country": {"type": "string"}}, "required": ["country"]},
},
}
]
SYSTEM = (
"You are a concise assistant. "
"If the user asks for a country's capital, ALWAYS call the tool 'country_capital_lookup'. "
"Otherwise, answer briefly."
)
@rollout
def capital_agent(task: CapitalTask, llm: LLM) -> float:
"""Run one evaluation task with capital agent.
Returns 1.0 if output contains expected substring, else 0.0.
"""
console.print("[bold blue]======== Runner Start ========[/bold blue]")
console.print("[bold blue]Runner[/bold blue] [Step 1] Running task with input:", task)
prompt = task["input"]
expected = task["output"]
openai_client = openai.OpenAI(base_url=llm.endpoint, api_key=os.getenv("AZURE_OPENAI_API_KEY", ""))
messages: List[ChatCompletionMessageParam] = [
{"role": "system", "content": SYSTEM},
{"role": "user", "content": prompt},
]
# --- Call #1 ---
first = openai_client.chat.completions.create(
model=llm.model,
messages=messages,
tools=TOOLS,
tool_choice="auto",
temperature=1.0,
)
msg = first.choices[0].message
console.print("[bold blue]Runner[/bold blue] [Step 2] First call response:", msg)
if msg.tool_calls:
assistant_tool_calls: List[ChatCompletionMessageFunctionToolCallParam] = []
tool_results: List[ChatCompletionToolMessageParam] = []
for tc in msg.tool_calls:
if tc.type == "function" and tc.function.name == "country_capital_lookup":
args = json.loads(tc.function.arguments or "{}")
result = country_capital_lookup(args.get("country", ""))
assistant_tool_calls.append(
{
"id": tc.id,
"type": "function",
"function": {
"name": tc.function.name,
"arguments": tc.function.arguments,
},
}
)
tool_results.append(
{
"role": "tool",
"tool_call_id": tc.id,
"content": result,
}
)
messages.append(
{
"role": "assistant",
"content": msg.content or "",
"tool_calls": assistant_tool_calls,
}
)
messages.extend(tool_results)
console.print("[bold blue]Runner[/bold blue] [Step 3] Messages after tool call:", messages)
# --- Call #2 ---
second = openai_client.chat.completions.create(
model=llm.model,
messages=messages,
temperature=1.0,
)
final_text = second.choices[0].message.content or ""
console.print("[bold blue]Runner[/bold blue] [Step 4] Second call response:", final_text)
else:
console.print("[bold blue]Runner[/bold blue] [Step 3] No tool calls made.")
final_text = msg.content or ""
final_text = final_text.strip()
reward = 1.0 if expected.lower() in final_text.lower() else 0.0
console.print(f"[bold blue]Runner[/bold blue] [Step Final] Final output: {final_text} | Reward: {reward}")
return reward
async def main():
# We don't put API key in LLM object for security reasons.
llm = LLM(
endpoint=os.getenv("AZURE_OPENAI_ENDPOINT", ""),
model="gpt-4.1-mini",
)
data = pd.read_csv("capital_samples.csv") # type: ignore
tracer = AgentOpsTracer()
runner = LitAgentRunner[CapitalTask](tracer=tracer)
store = InMemoryLightningStore()
with runner.run_context(agent=capital_agent, store=store):
for index in range(5):
sample = cast(CapitalTask, data.iloc[index].to_dict()) # type: ignore
await runner.step(sample, resources={"main_llm": llm})
if __name__ == "__main__":
asyncio.run(main())