From ef00880960685eaa3cc927724452aa610c8749f1 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 1 Jan 2026 11:24:29 +0800 Subject: [PATCH] Update Agent Documentation and MCP Tool Configuration - Revised the API access endpoint in the agent documentation to reflect the new structure. - Expanded examples for agent hooks, database queries, and MCP tools, providing clearer guidance for users. - Updated MCP tool configuration to use 'label' instead of 'name' and refined transport types for better clarity. - Introduced input schema definitions for process transport tools, enhancing the documentation on tool mapping and error handling. --- agent/README.md | 103 ++++++++++++-- agent/docs/mcp.md | 78 ++++++----- agent/docs/pages.md | 324 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 464 insertions(+), 41 deletions(-) create mode 100644 agent/docs/pages.md diff --git a/agent/README.md b/agent/README.md index 588670fe..676097fc 100644 --- a/agent/README.md +++ b/agent/README.md @@ -78,7 +78,87 @@ yao agent test -i "Hello, how are you?" yao start ``` -Access via API: `POST /api/__yao/agent` +Access via API: `POST /v1/chat/completions` + +## Examples + +### Hook: Route to Specialist + +```typescript +// src/index.ts +function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create { + const last = messages[messages.length - 1]?.content || ""; + if (last.includes("refund")) { + return { delegate: { agent_id: "refund-specialist", messages } }; + } + return null; +} +``` + +### Database Query + +```json +// package.yao - Enable auto DB search +{ "db": { "models": ["orders", "products"] } } +``` + +```bash +# Test: Agent auto-generates QueryDSL and searches database +yao agent test -i "Find orders over $1000 from last month" +``` + +### MCP Tools (Process Transport) + +```json +// mcps/tools.mcp.yao - Define MCP server with Yao Processes +{ + "label": "Tools", + "transport": "process", + "tools": { + "search_orders": "models.order.Paginate", + "create_order": "models.order.Create" + } +} +``` + +```json +// mcps/mapping/tools/schemes/search_orders.in.yao - Input schema +{ + "type": "object", + "properties": { + "keyword": { "type": "string" }, + "page": { "type": "integer" } + }, + "x-process-args": [":arguments"] +} +``` + +```json +// package.yao +{ "mcp": { "servers": [{ "server_id": "tools" }] } } +``` + +### Sidebar Page (Display Data) + +Pages render in the right sidebar during conversation to display structured data: + +```html + +
+

{{ title }}

+ + + + + +
{{ row.name }}{{ row.value }}
+
+``` + +```bash +yao sui build agent # Build pages +# Rendered via ctx.Send({ type: "page", props: { page: "result", data: {...} } }) +``` ## Documentation @@ -88,6 +168,7 @@ Access via API: `POST /api/__yao/agent` - [Context API](docs/context-api.md) - Messaging, memory, trace, MCP - [MCP Integration](docs/mcp.md) - Tool servers and resources - [Search](docs/search.md) - Web, knowledge base, and database search +- [Pages](docs/pages.md) - Web UI for agents (SUI framework) - [Internationalization](docs/i18n.md) - Multi-language support - [Testing](docs/testing.md) - Agent testing framework @@ -136,13 +217,19 @@ flowchart LR ## API Endpoints -| Endpoint | Method | Description | -| ------------------------------- | ------ | ------------------- | -| `/api/__yao/agent` | POST | Chat with assistant | -| `/api/__yao/agent/history` | GET | Get chat history | -| `/api/__yao/agent/chats` | GET | List chat sessions | -| `/api/__yao/agent/assistants` | GET | List assistants | -| `/api/__yao/agent/upload/:type` | POST | Upload files | +OpenAPI endpoints (base URL: `/v1`): + +| Endpoint | Method | Description | +| -------------------------------------- | ------ | --------------------- | +| `/v1/chat/completions` | POST | Chat with assistant | +| `/v1/chat/sessions` | GET | List chat sessions | +| `/v1/chat/sessions/:chat_id` | GET | Get chat session | +| `/v1/chat/sessions/:chat_id/messages` | GET | Get messages | +| `/v1/agent/assistants` | GET | List assistants | +| `/v1/agent/assistants/:id` | GET | Get assistant details | +| `/v1/file/:uploaderID` | POST | Upload files | +| `/v1/file/:uploaderID/:fileID` | GET | Get file info | +| `/v1/file/:uploaderID/:fileID/content` | GET | Download file | ## License diff --git a/agent/docs/mcp.md b/agent/docs/mcp.md index 5b030384..5ed0914e 100644 --- a/agent/docs/mcp.md +++ b/agent/docs/mcp.md @@ -8,40 +8,43 @@ Create `mcps/tools.mcp.yao` in the assistant directory: ```json { - "name": "Tools", + "label": "Tools", "description": "Custom tools for the assistant", "transport": "process", - "process": { - "command": "node", - "args": ["server.js"] + "tools": { + "search": "scripts.tools.Search", + "create": "models.data.Create" } } ``` ### Transport Types -**Process (Local)** +**Process (Yao Internal)** + +Map Yao Processes directly to MCP tools: ```json { "transport": "process", - "process": { - "command": "python", - "args": ["mcp_server.py"], - "env": { "API_KEY": "$ENV.API_KEY" } + "tools": { + "search": "models.data.Paginate", + "create": "models.data.Create" + }, + "resources": { + "detail": "models.data.Find" } } ``` -**HTTP** +**STDIO (Local Server)** ```json { - "transport": "http", - "http": { - "url": "https://mcp.example.com", - "headers": { "Authorization": "Bearer $ENV.TOKEN" } - } + "transport": "stdio", + "command": "python", + "arguments": ["mcp_server.py"], + "env": { "API_KEY": "$ENV.API_KEY" } } ``` @@ -50,9 +53,8 @@ Create `mcps/tools.mcp.yao` in the assistant directory: ```json { "transport": "sse", - "sse": { - "url": "https://mcp.example.com/events" - } + "url": "https://mcp.example.com/events", + "authorization_token": "$ENV.TOKEN" } ``` @@ -159,27 +161,37 @@ const prompts = ctx.mcp.ListPrompts("server-id"); const prompt = ctx.mcp.GetPrompt("server-id", "system", { role: "helper" }); ``` -## Tool Mapping +## Tool Schema Mapping -Map MCP tools to Yao processes: +Define input schemas for process transport tools: ``` mcps/ └── mapping/ - └── tools/ - ├── search.yao - └── calculate.yao + └── / + └── schemes/ + ├── search.in.yao # Input schema + └── search.out.yao # Output schema (optional) ``` -**mapping/tools/search.yao** +**mapping/tools/schemes/search.in.yao** ```json { - "process": "scripts.search.Execute", - "args": ["{{input}}"] + "type": "object", + "description": "Search data", + "properties": { + "keyword": { "type": "string" }, + "page": { "type": "integer" } + }, + "x-process-args": [":arguments"] } ``` +The `x-process-args` maps MCP arguments to Yao Process parameters: +- `":arguments"` - Pass entire arguments object +- `"$args.field"` - Extract specific field + ## Error Handling ```typescript @@ -208,12 +220,12 @@ function Next(ctx: agent.Context, payload: agent.Payload): agent.Next { ```json { - "name": "Calculator", + "label": "Calculator", "description": "Math operations", "transport": "process", - "process": { - "command": "node", - "args": ["calc-server.js"] + "tools": { + "add": "scripts.math.Add", + "multiply": "scripts.math.Multiply" } } ``` @@ -226,7 +238,7 @@ function Next(ctx: agent.Context, payload: agent.Payload): agent.Next { "connector": "gpt-4o", "mcp": { "servers": [ - { "server_id": "agents.assistant.calculator", "tools": ["add", "multiply"] } + { "server_id": "calculator", "tools": ["add", "multiply"] } ] } } @@ -242,7 +254,7 @@ function Create(ctx: agent.Context, messages: agent.Message[]): agent.Create { // Enable calculator return { messages, - mcp_servers: [{ server_id: "agents.assistant.calculator" }] + mcp_servers: [{ server_id: "calculator" }] }; } return { messages }; @@ -252,7 +264,7 @@ function Next(ctx: agent.Context, payload: agent.Payload): agent.Next { const { tools } = payload; if (tools?.length > 0) { - const calcResult = tools.find(t => t.server.includes("calculator")); + const calcResult = tools.find(t => t.server === "calculator"); if (calcResult?.result) { return { data: { diff --git a/agent/docs/pages.md b/agent/docs/pages.md new file mode 100644 index 00000000..a497b26f --- /dev/null +++ b/agent/docs/pages.md @@ -0,0 +1,324 @@ +# Agent Pages + +Agent Pages provide a built-in SUI (Simple User Interface) framework for building web interfaces for AI agents. Pages are automatically loaded from the `/agent/template/` directory for global templates and `/assistants//pages/` for individual assistant pages. + +## Directory Structure + +``` +/ +├── agent/ +│ └── template/ # Global template directory +│ ├── __document.html # Document template +│ ├── __data.json # Global data +│ ├── __assets/ # Global assets +│ │ ├── css/ +│ │ ├── js/ +│ │ └── images/ +│ ├── pages/ # Global pages (login, error, etc.) +│ │ └── login/ +│ │ └── login.html +│ └── __locales/ # Internationalization +│ +└── assistants/ + └── my-assistant/ + ├── package.yao + └── pages/ # Assistant-specific pages + ├── index/ + │ ├── index.html + │ ├── index.css + │ ├── index.ts + │ └── index.backend.ts + └── __assets/ # Optional assistant assets +``` + +## Route Mapping + +| File Path | Public URL | +|-----------|------------| +| `/agent/template/pages/login/login.html` | `/agents/login` | +| `/assistants/demo/pages/index/index.html` | `/agents/demo/index` | +| `/assistants/demo/pages/chat/chat.html` | `/agents/demo/chat` | + +## Quick Start + +### 1. Create Document Template + +**`/agent/template/__document.html`**: + +```html + + + + + {{ $global.title }} + + + + +
{{ __page }}
+ + +``` + +### 2. Create Global Data + +**`/agent/template/__data.json`**: + +```json +{ + "title": "AI Agent", + "version": "1.0.0" +} +``` + +### 3. Create a Page + +**`/assistants/my-assistant/pages/index/index.html`**: + +```html +
+

{{ title }}

+
+
{{ msg.content }}
+
+ +
+``` + +**`/assistants/my-assistant/pages/index/index.json`**: + +```json +{ + "title": "Chat", + "messages": [] +} +``` + +**`/assistants/my-assistant/pages/index/index.css`**: + +```css +.page { + max-width: 800px; + margin: 0 auto; + padding: 24px; +} + +.messages { + display: flex; + flex-direction: column; + gap: 12px; +} + +.message.user { + align-self: flex-end; + background: #007bff; + color: white; +} + +.message.assistant { + align-self: flex-start; + background: #f0f0f0; +} +``` + +### 4. Add Backend Script + +**`/assistants/my-assistant/pages/index/index.backend.ts`**: + +```typescript +function BeforeRender(request: Request): Record { + const chatId = request.query.chat_id; + return { + messages: chatId ? Process("scripts.chat.GetHistory", chatId) : [], + user: request.authorized?.user_id + }; +} + +function ApiGetData(request: Request): any { + const { id } = request.payload; + return Process("models.data.Find", id, {}); +} +``` + +### 5. Add Frontend Script + +**`/assistants/my-assistant/pages/index/index.ts`**: + +```typescript +function index(component: HTMLElement) { + this.root = component; + this.store = new __sui_store(component); + + this.handleClick = async (event: Event) => { + const data = await this.backend.ApiGetData({ id: 1 }); + console.log(data); + }; +} +``` + +### 6. Build and Run + +```bash +# Build pages +yao sui build agent + +# Or watch for changes +yao sui watch agent + +# Start server +yao start +``` + +Access at: `http://localhost:5099/agents/my-assistant/index` + +## Template Syntax + +### Data Binding + +```html + +

{{ title }}

+ + +

{{ user.name }}

+ + +

{{ description || "No description" }}

+``` + +### Conditionals + +```html +
Welcome, {{ user.name }}!
+
Welcome, Guest!
+
Please log in
+``` + +### Loops + +```html +
    +
  • + {{ i + 1 }}. {{ item.name }} +
  • +
+``` + +### Events + +```html + + +``` + +### Components + +Pages can use other pages as components: + +```html + + + +
+
+
Content
+
+
+``` + +## Built-in Variables + +| Variable | Description | +|----------|-------------| +| `$global` | Global data from `__data.json` | +| `$query` | URL query parameters | +| `$param` | URL path parameters | +| `$payload` | POST request body | +| `$cookie` | Cookie values | +| `$url` | Current URL info | +| `$theme` | Current theme | +| `$locale` | Current locale | +| `$auth` | OAuth authorization info (if authenticated) | + +## Page Configuration + +Create `.config` for page settings: + +```json +{ + "title": "Page Title", + "guard": "bearer-jwt", + "cache": 3600, + "data": { + "key": "value" + } +} +``` + +## Asset Paths + +- **Global assets**: `/agents/assets/...` → `/agent/template/__assets/...` +- **Assistant assets**: `/agents//assets/...` → `/assistants//pages/__assets/...` + +## Build Output + +``` +/public/agents/ +├── assets/ +│ ├── libsui.min.js # SUI frontend SDK +│ ├── css/ # Global CSS +│ ├── js/ # Global JS +│ └── images/ # Global images +│ +├── login.sui # Global page +├── login.cfg +│ +└── my-assistant/ + ├── index.sui # Assistant page + └── index.cfg +``` + +## Authentication + +Pages default to public access. To require authentication: + +**`/assistants/my-assistant/pages/dashboard/dashboard.config`**: + +```json +{ + "guard": "bearer-jwt" +} +``` + +Available guards: + +| Guard | Description | +|-------|-------------| +| `-` | No authentication (default) | +| `bearer-jwt` | JWT token in Authorization header | +| `cookie-jwt` | JWT token in cookie | +| `oauth` | OAuth 2.0 authentication | + +## Frontend API + +The SUI frontend SDK provides: + +```typescript +// Backend calls +const data = await this.backend.ApiMethodName(payload); + +// State management +this.store.Set("key", value); +const value = this.store.Get("key"); + +// OpenAPI client (if using oauth guard) +const response = await OpenAPI.Get("/api/endpoint"); +await OpenAPI.Post("/api/endpoint", data); +``` + +## Related Documentation + +- [SUI Template Syntax](../../sui/docs/template-syntax.md) +- [SUI Data Binding](../../sui/docs/data-binding.md) +- [SUI Components](../../sui/docs/components.md) +- [SUI Frontend API](../../sui/docs/frontend-api.md)