diff --git a/mateclaw-server/src/main/resources/docs/en/webchat.md b/mateclaw-server/src/main/resources/docs/en/webchat.md index 572f6fbb..0e4221b5 100644 --- a/mateclaw-server/src/main/resources/docs/en/webchat.md +++ b/mateclaw-server/src/main/resources/docs/en/webchat.md @@ -66,8 +66,9 @@ init({ apiKey: 'your-channel-api-key', server: 'https://' }) | Method | Path | Auth | Purpose | |---|---|---|---| -| POST | `/stream` | API Key | SSE streaming chat (issues visitorToken) | +| POST | `/stream` | API Key | SSE streaming chat (issues visitorToken); the body may include an optional `agentId` to override the channel's bound agent (must be in the same workspace as the channel) | | GET | `/config` | API Key | Get channel config (title/placeholder/...) | +| GET | `/skills` | + visitorToken | List skills visible to this agent (for building your own slash picker UI) | | POST | `/sessions` | API Key | Explicitly create an empty session thread | | GET | `/sessions` | + visitorToken | List sessions (excludes archived by default) | | GET | `/sessions/page` | + visitorToken | Paginated + keyword search | @@ -199,6 +200,37 @@ curl -X POST https://mate.example.com/api/v1/admin/webchat/revoked-visitor \ After revocation, all of that visitor's management endpoints return 401 (`/stream` is unaffected and can re-issue a fresh token). Revocation state is briefly cached, so under a multi-instance deployment it takes up to ~10 minutes to fully propagate. Un-revoke via `DELETE` on the same endpoint. +## Skill invocation (slash picker) + +The admin-console chat input shows a skill picker when you type `/`. This is a **pure frontend affordance** — selecting a skill rewrites the input box into a directive: + +- English: `Use the "" skill: ` +- Chinese: `使用「<技能名>」技能:<用户消息>` + +The directive goes out as a regular user message on `/stream`, and the LLM voluntarily calls the `load_skill` meta-tool when it sees it (see [skills.md](./skills.md#the-slash-menu)). The backend **does no `/` parsing**; webchat uses the exact same agent runtime as the admin console, so this path works out of the box for webchat callers. + +To build your own picker, first list the skills via the new endpoint: + +```bash +curl https://mate.example.com/api/v1/channels/webchat/skills?visitorId=v1 \ + -H "X-MC-Key: your-api-key" \ + -H "X-MC-Visitor-Token: " +# returns [{"id":..., "name":"news-summary", "nameZh":"News Summary", "description":"...", "icon":"..."}] +``` + +The `agentId` query parameter is optional (falls back to the channel's bound agent). Only skills **explicitly bound to the agent AND enabled** are returned, sorted by slug. The response carries display-level metadata only — **no** SKILL.md content, configJson, or security scan results (those stay admin-console-only). + +After a user picks a skill, construct the message: + +```bash +curl -N -X POST https://mate.example.com/api/v1/channels/webchat/stream \ + -H "X-MC-Key: your-api-key" \ + -H "Content-Type: application/json" \ + -d '{"visitorId":"v1","message":"Use the \"news-summary\" skill: summarize the top 3 AI stories today"}' +``` + +> Note: the directive text relies on the LLM "obeying" and calling `load_skill`. Under complex tasks it occasionally drifts; for production, bind the target skill to the agent and reinforce the system prompt in `AGENTS.md`. + ## curl examples **Step 1: send the first message** diff --git a/mateclaw-server/src/main/resources/docs/zh/webchat.md b/mateclaw-server/src/main/resources/docs/zh/webchat.md index 955aaff2..53b2478f 100644 --- a/mateclaw-server/src/main/resources/docs/zh/webchat.md +++ b/mateclaw-server/src/main/resources/docs/zh/webchat.md @@ -66,8 +66,9 @@ init({ apiKey: 'your-channel-api-key', server: 'https://<你的部署地址>' }) | 方法 | 路径 | 鉴权 | 用途 | |---|---|---|---| -| POST | `/stream` | API Key | SSE 流式对话(签发 visitorToken) | +| POST | `/stream` | API Key | SSE 流式对话(签发 visitorToken);请求体可选传 `agentId` 覆盖渠道绑定的 agent(必须与渠道同 workspace) | | GET | `/config` | API Key | 拿渠道配置(title/placeholder/...) | +| GET | `/skills` | + visitorToken | 列出该 agent 绑定的可见技能(供下游自建 slash picker UI) | | POST | `/sessions` | API Key | 显式创建空会话线程 | | GET | `/sessions` | + visitorToken | 列出会话(默认排除 archived) | | GET | `/sessions/page` | + visitorToken | 分页 + 关键词搜索 | @@ -204,6 +205,37 @@ curl -X POST https://mate.example.com/api/v1/admin/webchat/revoked-visitor \ 撤销后该 visitor 的所有管理端点调用返回 401(`/stream` 不受影响,可重新签发新 token)。撤销状态带短时缓存,多实例下最长约 10 分钟生效。取消撤销用 `DELETE` 同一端点。 +## 技能调用(slash picker) + +主控台前端在输入框键入 `/` 会弹出技能选择菜单。这是**纯前端 affordance**——选中后输入框被改写成指令文本: + +- 中文:`使用「<技能名>」技能:<用户消息>` +- 英文:`Use the "" skill: <用户消息>` + +指令文本作为普通 user message 发到 `/stream`,LLM 收到后调用 `load_skill` 元工具(详见 [skills.md](./skills.md#slash-菜单))。后端**不做 `/` 解析**,webchat 走的是和主控台完全一样的 agent runtime,所以这条路径对 webchat 调用方**开箱即用**。 + +下游集成方要自建 picker UI,先用新端点拿清单: + +```bash +curl https://mate.example.com/api/v1/channels/webchat/skills?visitorId=v1 \ + -H "X-MC-Key: your-api-key" \ + -H "X-MC-Visitor-Token: " +# 返回 [{"id":..., "name":"news-summary", "nameZh":"新闻摘要", "description":"...", "icon":"..."}] +``` + +可选 `agentId` 参数(默认回落到渠道绑定的 agent);只返回该 agent **显式绑定且 enabled** 的技能,按 slug 字母序排序。返回字段是展示级元数据,**不包含** SKILL.md 正文、configJson、安全扫描结果——这些只走管理控制台。 + +选中后构造消息: + +```bash +curl -N -X POST https://mate.example.com/api/v1/channels/webchat/stream \ + -H "X-MC-Key: your-api-key" \ + -H "Content-Type: application/json" \ + -d '{"visitorId":"v1","message":"使用「新闻摘要」技能:总结今天最重要的 3 条 AI 新闻"}' +``` + +> 注意:指令文本依赖 LLM "听话"调用 `load_skill`。复杂任务下偶发漂移,生产环境建议把目标技能**绑定**到 agent(`agentId` 对应的)并在 `AGENTS.md` 里强化系统提示。 + ## curl 示例 **第一步:发首条消息**