chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 12:58:18 +08:00
commit 6d5d58c1a9
18293 changed files with 3502153 additions and 0 deletions
@@ -0,0 +1,7 @@
[project]
name = "agent"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = ["agent-framework-ag-ui>=1.0.0b251117", "python-dotenv"]
@@ -0,0 +1,126 @@
from __future__ import annotations
from textwrap import dedent
from typing import Annotated
from agent_framework import ChatAgent, ChatClientProtocol, ai_function
from agent_framework_ag_ui import AgentFrameworkAgent
from pydantic import Field
STATE_SCHEMA: dict[str, object] = {
"proverbs": {
"type": "array",
"items": {"type": "string"},
"description": "Ordered list of the user's saved proverbs.",
}
}
PREDICT_STATE_CONFIG: dict[str, dict[str, str]] = {
"proverbs": {
"tool": "update_proverbs",
"tool_argument": "proverbs",
}
}
@ai_function(
name="update_proverbs",
description=(
"Replace the entire list of proverbs with the provided values. "
"Always include every proverb you want to keep."
),
)
def update_proverbs(
proverbs: Annotated[
list[str],
Field(
description=(
"The complete source of truth for the user's proverbs. "
"Maintain ordering and include the full list on each call."
)
),
],
) -> str:
"""Persist the provided set of proverbs."""
return f"Proverbs updated. Tracking {len(proverbs)} item(s)."
@ai_function(
name="get_weather",
description="Share a quick weather update for a location. Use this to render the frontend weather card.",
)
def get_weather(
location: Annotated[
str,
Field(
description="The city or region to describe. Use fully spelled out names."
),
],
) -> str:
"""Return a short natural language weather summary."""
normalized = location.strip().title() or "the requested location"
return (
f"The weather in {normalized} is mild with a light breeze. "
"Skies are mostly clear—perfect for planning something fun."
)
@ai_function(
name="go_to_moon",
description="Request a playful human-in-the-loop confirmation before launching a mission to the moon.",
approval_mode="always_require",
)
def go_to_moon() -> str:
"""Request human approval before continuing."""
return "Mission control requested. Awaiting human approval for the lunar launch."
def create_agent(chat_client: ChatClientProtocol) -> AgentFrameworkAgent:
"""Instantiate the CopilotKit demo agent backed by Microsoft Agent Framework."""
base_agent = ChatAgent(
name="proverbs_agent",
instructions=dedent(
"""
You help users brainstorm, organize, and refine proverbs while coordinating UI updates.
State sync:
- The current list of proverbs is provided in the conversation context.
- When you add, remove, or reorder proverbs, call `update_proverbs` with the full list.
Never send partial updates—always include every proverb that should exist.
- CRITICAL: When asked to "add" a proverb, you must:
1. First, identify ALL existing proverbs from the conversation history
2. Create EXACTLY ONE new proverb (never more than one unless explicitly requested)
3. Call update_proverbs with: [all existing proverbs] + [the one new proverb]
Example: Current: ["A", "B"] -> After adding: ["A", "B", "C"] (NOT ["A", "B", "C", "D", "E"])
- When asked to "remove" a proverb, remove exactly ONE item unless user specifies otherwise.
Tool usage rules:
- When user asks to go to the moon, you MUST call the `go_to_moon` tool immediately. Do NOT ask for approval
yourself—the tool's approval workflow and the client UI will handle it.
Frontend integrations:
- `get_weather` renders a weather card in the UI. Only call this tool when the user explicitly
asks for weather. Do NOT call it after unrelated tasks or approvals.
- `go_to_moon` requires explicit user approval before you proceed. Only use it when a
user asks to launch or travel to the moon. Always call the tool instead of asking manually.
Conversation tips:
- Reference the latest proverb list before suggesting changes.
- Keep responses concise and friendly unless the user requests otherwise.
- After you finish executing tools for the user's request, provide a brief, final assistant
message summarizing exactly what changed. Do NOT call additional tools or switch topics
after that summary unless the user asks. ALWAYS send this conversational summary so the message persists.
""".strip()
),
chat_client=chat_client,
tools=[update_proverbs, get_weather, go_to_moon],
)
return AgentFrameworkAgent(
agent=base_agent,
name="CopilotKitMicrosoftAgentFrameworkAgent",
description="Manages proverbs, weather snippets, and human-in-the-loop moon launches.",
state_schema=STATE_SCHEMA,
predict_state_config=PREDICT_STATE_CONFIG,
require_confirmation=False, # Allow immediate state updates with follow-up messages
)
@@ -0,0 +1,79 @@
from __future__ import annotations
import os
import uvicorn
from agent_framework._clients import ChatClientProtocol
from azure.identity import DefaultAzureCredential
from agent_framework.azure import AzureOpenAIChatClient
from agent_framework.openai import OpenAIChatClient
from agent_framework_ag_ui import add_agent_framework_fastapi_endpoint
from dotenv import load_dotenv
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from agent import create_agent
load_dotenv()
def _build_chat_client() -> ChatClientProtocol:
try:
if bool(os.getenv("AZURE_OPENAI_ENDPOINT")):
# Azure OpenAI setup - uses environment variables by default
# Optionally can pass deployment_name explicitly
deployment_name = os.getenv(
"AZURE_OPENAI_CHAT_DEPLOYMENT_NAME", "gpt-4o-mini"
)
return AzureOpenAIChatClient(
credential=DefaultAzureCredential(),
deployment_name=deployment_name,
endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
)
if bool(os.getenv("OPENAI_API_KEY")):
# OpenAI setup - requires explicit model_id and api_key
return OpenAIChatClient(
model_id=os.getenv("OPENAI_CHAT_MODEL_ID", "gpt-4o-mini"),
api_key=os.getenv("OPENAI_API_KEY"),
)
raise ValueError(
"Either AZURE_OPENAI_ENDPOINT or OPENAI_API_KEY environment variable is required"
)
except Exception as exc: # pragma: no cover
raise RuntimeError(
"Unable to initialize the chat client. Double-check your API credentials as documented in README.md."
) from exc
chat_client = _build_chat_client()
my_agent = create_agent(chat_client)
app = FastAPI(title="CopilotKit + Microsoft Agent Framework (Python)")
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
add_agent_framework_fastapi_endpoint(
app=app,
agent=my_agent,
path="/",
)
@app.get("/health")
async def health():
return {"status": "ok"}
if __name__ == "__main__":
host = os.getenv("AGENT_HOST", "0.0.0.0")
port = int(os.getenv("AGENT_PORT", "8000"))
uvicorn.run("main:app", host=host, port=port, reload=True)
File diff suppressed because it is too large Load Diff