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,46 @@
"""Barrel exports for all shared showcase tool implementations."""
from .types import (
SalesStage,
SalesTodo,
Flight,
WeatherResult,
)
from .get_weather import get_weather_impl
from .query_data import query_data_impl
from .sales_todos import (
INITIAL_TODOS,
manage_sales_todos_impl,
get_sales_todos_impl,
)
from .search_flights import search_flights_impl
from .generate_a2ui import (
DESIGN_A2UI_SURFACE_TOOL_SCHEMA,
generate_a2ui_impl,
build_a2ui_operations_from_tool_call,
)
from .schedule_meeting import schedule_meeting_impl
__all__ = [
# Types
"SalesStage",
"SalesTodo",
"Flight",
"WeatherResult",
# Weather
"get_weather_impl",
# Query data
"query_data_impl",
# Sales todos
"INITIAL_TODOS",
"manage_sales_todos_impl",
"get_sales_todos_impl",
# Flight search (fixed-schema A2UI)
"search_flights_impl",
# Dynamic A2UI
"DESIGN_A2UI_SURFACE_TOOL_SCHEMA",
"generate_a2ui_impl",
"build_a2ui_operations_from_tool_call",
# Schedule meeting (HITL)
"schedule_meeting_impl",
]
@@ -0,0 +1,138 @@
"""Dynamic A2UI tool: LLM-generated UI from conversation context.
This module provides the data preparation for a secondary LLM call that
generates v0.9 A2UI components. The actual LLM call is made by the
framework-specific wrapper (LangGraph, CrewAI, etc.) since each framework
has its own way of invoking LLMs.
"""
from __future__ import annotations
import logging
from typing import Any, Optional
_logger = logging.getLogger(__name__)
CUSTOM_CATALOG_ID = "copilotkit://app-dashboard-catalog"
# The _design_a2ui_surface tool schema that the secondary LLM is bound to.
DESIGN_A2UI_SURFACE_TOOL_SCHEMA = {
"name": "_design_a2ui_surface",
"description": (
"Render a dynamic A2UI v0.9 surface.\n\n"
"Args:\n"
" surfaceId: Unique surface identifier.\n"
' catalogId: The catalog ID (use "copilotkit://app-dashboard-catalog").\n'
" components: A2UI v0.9 component array (flat format). "
'The root component must have id "root".\n'
" data: Optional initial data model for the surface."
),
"parameters": {
"type": "object",
"properties": {
"surfaceId": {
"type": "string",
"description": "Unique surface identifier.",
},
"catalogId": {"type": "string", "description": "The catalog ID."},
"components": {
"type": "array",
"items": {"type": "object"},
"description": "A2UI v0.9 component array (flat format).",
},
"data": {
"type": "object",
"description": "Optional initial data model for the surface.",
},
},
"required": ["surfaceId", "catalogId", "components"],
},
}
def generate_a2ui_impl(
messages: list[dict[str, Any]],
context_entries: Optional[list[dict[str, Any]]] = None,
) -> dict[str, Any]:
"""Prepare inputs for a secondary LLM call that generates A2UI components.
Returns a dict with:
- system_prompt: The system prompt for the secondary LLM (built from context)
- tool_schema: The _design_a2ui_surface tool schema to bind to the LLM
- tool_choice: The tool name to force
- messages: The conversation messages to pass through
- catalog_id: The default catalog ID
The framework wrapper should:
1. Make an LLM call with these inputs
2. Extract the tool call args (surfaceId, catalogId, components, data)
3. Build a2ui_operations from the args and return them
"""
context_text = ""
if context_entries:
context_text = "\n\n".join(
entry.get("value", "")
for entry in context_entries
if isinstance(entry, dict) and entry.get("value")
)
return {
"system_prompt": context_text,
"tool_schema": DESIGN_A2UI_SURFACE_TOOL_SCHEMA,
"tool_choice": "_design_a2ui_surface",
"messages": messages,
"catalog_id": CUSTOM_CATALOG_ID,
}
def build_a2ui_operations_from_tool_call(args: dict[str, Any]) -> dict[str, Any]:
"""Build a2ui_operations dict from the secondary LLM's tool call args.
Call this after the framework wrapper extracts the tool call arguments.
The returned operations use the A2UI v0.9 NESTED shape (mirroring
`copilotkit.a2ui.create_surface` / `update_components` / `update_data_model`
from langgraph-python). The `@ag-ui/a2ui-middleware` extracts the
surfaceId via `op.createSurface?.surfaceId ?? op.updateComponents?.surfaceId
?? ...` — a flat `{"type": "create_surface", "surfaceId": ...}` shape leaves
every op under a "default" surface and the renderer never binds to the
registered catalog.
"""
surface_id = args.get("surfaceId", "dynamic-surface")
catalog_id = args.get("catalogId", CUSTOM_CATALOG_ID)
components = args.get("components", [])
if not components:
_logger.warning(
"build_a2ui_operations_from_tool_call received empty components list"
)
data = args.get("data")
ops: list[dict[str, Any]] = [
{
"version": "v0.9",
"createSurface": {
"surfaceId": surface_id,
"catalogId": catalog_id,
},
},
{
"version": "v0.9",
"updateComponents": {
"surfaceId": surface_id,
"components": components,
},
},
]
if data:
ops.append(
{
"version": "v0.9",
"updateDataModel": {
"surfaceId": surface_id,
"path": "/",
"value": data,
},
}
)
return {"a2ui_operations": ops}
@@ -0,0 +1,40 @@
"""Mock weather data tool implementation."""
import random
from .types import WeatherResult
_CONDITIONS = [
"Sunny",
"Partly Cloudy",
"Cloudy",
"Overcast",
"Light Rain",
"Heavy Rain",
"Thunderstorm",
"Snow",
"Foggy",
"Windy",
]
def get_weather_impl(city: str) -> WeatherResult:
"""Return mock weather data for the given city.
Uses a seeded random based on the city name so repeated calls
for the same city return consistent results within a session.
"""
rng = random.Random(city.lower())
temperature = rng.randint(20, 95)
humidity = rng.randint(30, 90)
wind_speed = rng.randint(2, 30)
feels_like = temperature + rng.randint(-5, 5)
conditions = rng.choice(_CONDITIONS)
return WeatherResult(
city=city,
temperature=temperature,
humidity=humidity,
wind_speed=wind_speed,
feels_like=feels_like,
conditions=conditions,
)
@@ -0,0 +1,60 @@
"""Query data tool implementation — reads db.csv at module load time."""
from __future__ import annotations
import csv
import logging
from pathlib import Path
from typing import Any
_logger = logging.getLogger(__name__)
_csv_path = Path(__file__).resolve().parent.parent / "data" / "db.csv"
_MOCK_DATA = [
{
"date": "2026-01-05",
"category": "Revenue",
"subcategory": "Enterprise Subscriptions",
"amount": "28000",
"type": "income",
"notes": "3 new enterprise customers",
},
{
"date": "2026-01-10",
"category": "Expenses",
"subcategory": "Engineering Salaries",
"amount": "42000",
"type": "expense",
"notes": "7 engineers + 2 contractors",
},
{
"date": "2026-02-03",
"category": "Revenue",
"subcategory": "Pro Tier Upgrades",
"amount": "22500",
"type": "income",
"notes": "31 upgrades + reduced churn",
},
]
try:
with open(_csv_path) as _f:
_cached_data: list[dict[str, Any]] = list(csv.DictReader(_f))
if not _cached_data:
_logger.warning("CSV at %s is empty, falling back to mock data", _csv_path)
_cached_data = _MOCK_DATA
except (FileNotFoundError, OSError) as exc:
_logger.warning(
"Could not load CSV at %s (%s), falling back to mock data", _csv_path, exc
)
_cached_data = _MOCK_DATA
def query_data_impl(query: str) -> list[dict[str, Any]]:
"""Query the database. Takes natural language.
Always call before showing a chart or graph. Returns the full
dataset as a list of dicts (rows from the CSV).
"""
return _cached_data
@@ -0,0 +1,63 @@
"""Sales todos tool implementation."""
from __future__ import annotations
import uuid
from typing import Optional
from .types import SalesTodo
INITIAL_TODOS: list[SalesTodo] = [
SalesTodo(
id="st-001",
title="Follow up with Acme Corp on enterprise proposal",
stage="proposal",
value=85000,
dueDate="2026-04-15",
assignee="Sarah Chen",
completed=False,
),
SalesTodo(
id="st-002",
title="Qualify lead from TechFlow demo request",
stage="prospect",
value=42000,
dueDate="2026-04-18",
assignee="Mike Johnson",
completed=False,
),
SalesTodo(
id="st-003",
title="Send contract to DataViz Inc for final review",
stage="negotiation",
value=120000,
dueDate="2026-04-20",
assignee="Sarah Chen",
completed=False,
),
]
def manage_sales_todos_impl(todos: list[dict]) -> list[SalesTodo]:
"""Assign UUIDs to any todos missing an ID, then return the updated list."""
result: list[SalesTodo] = []
for todo in todos:
result.append(
SalesTodo(
id=todo.get("id") or str(uuid.uuid4()),
title=todo.get("title", ""),
stage=todo.get("stage", "prospect"),
value=todo.get("value", 0),
dueDate=todo.get("dueDate", ""),
assignee=todo.get("assignee", ""),
completed=todo.get("completed", False),
)
)
return result
def get_sales_todos_impl(current_todos: Optional[list[dict]] = None) -> list[SalesTodo]:
"""Return current todos or initial defaults if none provided."""
if current_todos is not None:
return manage_sales_todos_impl(current_todos)
return list(INITIAL_TODOS)
@@ -0,0 +1,31 @@
"""Schedule meeting tool implementation.
The HITL gating happens on the frontend via useHumanInTheLoop.
This tool just returns a pending approval status for the framework
wrapper to surface.
"""
from __future__ import annotations
from typing import Any
def schedule_meeting_impl(
reason: str,
duration_minutes: int = 30,
) -> dict[str, Any]:
"""Schedule a meeting (requires human approval).
Returns a pending_approval status. The actual gating is done by the
frontend's useHumanInTheLoop hook — the agent pauses until the user
approves or rejects.
"""
return {
"status": "pending_approval",
"reason": reason,
"duration_minutes": duration_minutes,
"message": (
f"Meeting request: {reason} ({duration_minutes} min). "
"Awaiting human approval."
),
}
@@ -0,0 +1,122 @@
"""Fixed-schema A2UI tool: flight search results.
Packages flight data with an A2UI schema for rendering. The schema is loaded
from the shared frontend package's flight_schema.json.
"""
from __future__ import annotations
import json
import logging
from pathlib import Path
from typing import Any
from .types import Flight
_logger = logging.getLogger(__name__)
CATALOG_ID = "copilotkit://app-dashboard-catalog"
SURFACE_ID = "flight-search-results"
# Resolve the flight schema from the shared frontend package.
# Walk up from this file to showcase/shared/, then into frontend/src/a2ui/.
_SHARED_DIR = Path(__file__).resolve().parent.parent.parent # showcase/shared/
_SCHEMA_CANDIDATES = [
_SHARED_DIR / "frontend" / "src" / "a2ui" / "flight-schema.json",
_SHARED_DIR / "frontend" / "src" / "a2ui" / "flight_schema.json",
]
_flight_schema: list[dict[str, Any]] | None = None
for _candidate in _SCHEMA_CANDIDATES:
if _candidate.exists():
with open(_candidate) as _f:
_flight_schema = json.load(_f)
_logger.info("Loaded flight schema from shared frontend: %s", _candidate)
break
# Fallback: use the schema from the examples directory if present
if _flight_schema is None:
try:
_fallback = Path(__file__).resolve().parents[4] / (
"examples/integrations/langgraph-python/apps/agent/src/a2ui/schemas/flight_schema.json"
)
if _fallback.exists():
with open(_fallback) as _f:
_flight_schema = json.load(_f)
_logger.info("Loaded flight schema from examples fallback: %s", _fallback)
except IndexError:
# In Docker the file path is too shallow for parents[4]; skip this fallback.
pass
# Last resort: inline minimal schema
if _flight_schema is None:
_logger.warning("No flight schema file found, using inline minimal schema")
_flight_schema = [
{
"id": "root",
"component": "Row",
"children": {"componentId": "flight-card", "path": "/flights"},
"gap": 16,
},
{
"id": "flight-card",
"component": "FlightCard",
"airline": {"path": "airline"},
"airlineLogo": {"path": "airlineLogo"},
"flightNumber": {"path": "flightNumber"},
"origin": {"path": "origin"},
"destination": {"path": "destination"},
"date": {"path": "date"},
"departureTime": {"path": "departureTime"},
"arrivalTime": {"path": "arrivalTime"},
"duration": {"path": "duration"},
"status": {"path": "status"},
"price": {"path": "price"},
"action": {
"event": {
"name": "book_flight",
"context": {
"flightNumber": {"path": "flightNumber"},
"origin": {"path": "origin"},
"destination": {"path": "destination"},
"price": {"path": "price"},
},
}
},
},
]
def search_flights_impl(flights: list[Flight]) -> dict[str, Any]:
"""Package flight data with A2UI schema for rendering.
Returns a dict with a2ui_operations that the middleware detects in the
TOOL_CALL_RESULT and renders automatically.
Each flight should have: airline, airlineLogo, flightNumber, origin,
destination, date, departureTime, arrivalTime, duration, status,
statusColor, price, currency.
"""
return {
"a2ui_operations": [
{
"version": "v0.9",
"createSurface": {"surfaceId": SURFACE_ID, "catalogId": CATALOG_ID},
},
{
"version": "v0.9",
"updateComponents": {
"surfaceId": SURFACE_ID,
"components": _flight_schema,
},
},
{
"version": "v0.9",
"updateDataModel": {
"surfaceId": SURFACE_ID,
"path": "/",
"value": {"flights": flights},
},
},
]
}
@@ -0,0 +1,47 @@
"""Shared type definitions for showcase tools."""
from typing import TypedDict, Literal
SalesStage = Literal[
"prospect",
"qualified",
"proposal",
"negotiation",
"closed-won",
"closed-lost",
]
class SalesTodo(TypedDict):
id: str
title: str
stage: SalesStage
value: int
dueDate: str
assignee: str
completed: bool
class Flight(TypedDict):
airline: str
airlineLogo: str
flightNumber: str
origin: str
destination: str
date: str
departureTime: str
arrivalTime: str
duration: str
status: str
statusColor: str
price: str
currency: str
class WeatherResult(TypedDict):
city: str
temperature: int
humidity: int
wind_speed: int
feels_like: int
conditions: str