HTTP API

🔵 服务器提供 HTTP 控制平面以及一个流式传输 Server-Sent Events (SSE) 的聊天端点。端点列表在启动时打印到日志中。


8.1 端点

页面与静态资源(公开)

Endpoint 描述
GET / markdown 站点(落地页)
GET /site/ · GET /site/:page 同一站点位于子路径下
GET /sessions · /budgets · /teams · /users · /cron · /workflows · /dashboard 管理 UI
GET /agents/:name 单个代理页面
GET /widget · /widget.js · /dist/* 小部件及其资源
GET /demo · /demo/overlay 小部件演示 / 覆盖在真实站点上的浮层
GET /distrib/* 发行版归档(linux/windows zip + sha256、android apk)
GET /proxy?url=… · /proxy/content?url=… 前端 HTTP 代理
GET /login · POST /login · POST /logout 管理 UI 的 web 登录
GET /login/oidc/:provider · GET /login/oidc/:provider/callback 管理 UI 的 OIDC 登录(Google/Яндекс/Тинькофф)
GET /v1/login/methods 已启用的 OIDC 提供方列表
GET /v1/login/widget/:provider · GET /v1/login/widget/:provider/callback 小部件中最终用户的 OIDC 登录(popup)
POST /v1/login/widget/password 最终用户通过 auth.users 登录(签发 x-user-token)
GET /v1/connectors/callback OAuth 连接器的回调(Google Drive 等)
GET /v1/allowed-senders/:template · POST /v1/allowed-senders/:template 发送方动态 allowlist(列表 · 添加)🔒
DELETE /v1/allowed-senders/:template/:identity 从 allowlist 中删除发送方 🔒

公开 API

Endpoint 描述
GET /health healthcheck
GET /v1/models 可用模型
GET /v1/templates 代理模板(welcome、tools;tools_declared/loaded/failed 和 hooks_* — 实际加载的内容)
POST /v1/chat/completions 与代理聊天(SSE,自有格式)
POST /v1/continuations 懒加载分页表格的下一页
POST /v1/uploads 将附件(文件/截图/照片)上传到会话的 scratch 中
POST /v1/input-response 对代理附件请求的响应(request_attachment)
POST /v1/approval-response 最终用户对 inline 审批的响应(小部件)
POST /v1/sessions/:id 关闭会话(公开 — 小部件发送 sendBeacon)
POST /v1/inbound/:template 来自外部系统的单次代理回合(JSON,可选 bearer)
POST /v1/user-ticket 签发 HMAC 签名的身份令牌
POST /v1/feedback 对回答的 like/dislike
POST /v1/workflows/:name/webhook 工作流 webhook 触发器(由工作流令牌保护)
/ext/**(自定义) http_route / static_route — 全局(config/routes/)或由代理(route_files:)添加的用户自定义 REST 端点与静态资源;路由上的 auth public/bearer/token_env/user(见 §21)

管理 API 🔒

Endpoint 描述
GET /v1/agents · POST /v1/agents 代理列表 · 创建代理
GET /v1/agents/:name 单个代理的快照
DELETE /v1/agents/:pid 杀死代理及其子代理
POST /v1/agents/:pid/signal steering:pause / resume / interrupt / terminate(body {"signal":"…"})🔒
POST /v1/agents/:pid/reset 解除监督隔离(unpause + 删除 dead-letters)🔒
GET /v1/dead-letters?limit=N 被隔离的代理输入(dead-letter)
POST /v1/agents/:name/bench/run 运行模板基准测试
GET /v1/agents/:name/bench/runs · /bench/runs/:id 基准测试历史与详情
GET /v1/sessions 会话列表(?user_id= — 单个用户的会话 + user_stats)
GET /v1/sessions/:id · DELETE /v1/sessions/:id 会话详情 · 关闭
GET /v1/budgets 预算组与进程
GET /v1/machines · POST /v1/machines 受管机器清单 · 创建/更新(模块 remote)🔒
GET /v1/machines/:slug · PUT /v1/machines/:slug · DELETE /v1/machines/:slug 机器 · 更新(slug 来自路径)· 删除 🔒
GET /v1/kernels · POST /v1/kernels 远程 Agent OS 内核注册表 · 创建/更新(模块 kernels)🔒
GET /v1/kernels/:slug · PUT /v1/kernels/:slug · DELETE /v1/kernels/:slug 内核 · 更新 · 删除 🔒
GET /v1/kernels/:slug/health 通过 HTTP 对远程内核进行健康探测 🔒
GET /v1/cron · DELETE /v1/cron/:name cron 任务与历史 · 删除
GET /v1/workflows · POST /v1/workflows/:name/run 工作流 · 运行
GET /v1/workflows/runs/:id · /runs/:id/events 工作流运行 · 其事件
GET /v1/dashboard 系统仪表盘(负载、token、序列)
GET /v1/feedback/stats 评分统计
GET /v1/users 渠道 → 用户映射(带别名/操作员备注)
PATCH /v1/users/:id 设置/清除规范用户的 {alias, note}
POST /v1/users/link · POST /v1/users/:id/unlink 合并/拆分身份
GET /v1/memory/:scope 检查作用域长期记忆
GET /v1/hooks/metrics 钩子指标:按 (hook, point) 的调用/panic/超时/耗时
GET /v1/circuit-breakers 提供方 breaker 状态(status、failures、opened)+ 配置
POST /v1/circuit-breakers/:name/reset 强制闭合已断开的 breaker
GET /v1/approvals 待审批队列(操作员 inbox)
POST /v1/approvals/:request_id 批准/拒绝 {approved, comment}
GET/POST /v1/approvals/roles 审批者的逻辑角色 · 创建/更新
DELETE /v1/approvals/roles/:name 删除角色
POST/DELETE /v1/approvals/roles/:name/members… 添加/删除角色成员
GET /v1/system/tree 平台内省;按片段导航:?view=summary|modules|types|graph、?module=、?type=、?registry=(无参数 — 整棵树)
GET /v1/system/modules · /registries · /types · /routes · /services 内省切片
POST /v1/platform/modules/:id/enable · /disable 启用/禁用模块(重启后生效)
POST /v1/platform/restart 重启服务器以应用模块集合
GET /v1/builder/agents 代理配置列表(名称、是否有 agent.yaml、文件数、protected)
GET /v1/builder/agents/:name 包元数据:agent.yaml + 文件列表 {path,size}(不含内容)
GET/PUT/PATCH/DELETE /v1/builder/agents/:name/file?path= 单个文件:读取 · 写入(原始 body)· 替换行 {old,new,replace_all} · 删除
PUT /v1/builder/agents/:name 创建/部分更新包(agent_yaml? 和/或 files?)
DELETE /v1/builder/agents/:name 删除代理目录
POST /v1/builder/agents/:name/yaml?path= 对文件 {op,key,value} 进行 YAML 编辑,op = set|append|remove
POST /v1/builder/validate 不写入的包校验(包括检查每个文件 tool_files/hook_files 是否存在 kind)
GET /v1/tools · GET /v1/tools/:name · POST /v1/tools/:name/call · POST /v1/tools/run 工具注册表:列表 · 模式 · 按名称运行 · 运行 inline-YAML
POST /v1/agents/:name/tools/:tool/call 在代理 :name 的环境中执行工具(其 scope/state,若存活则 session),body {args}
GET /v1/state/:scope/:id :id 的 scoped-state :scope(agent|user|session|team)键
GET/PUT/DELETE /v1/state/:scope/:id/:key 读取 · 写入 {value} · 删除单个状态键
GET/POST /v1/teams · GET/DELETE /v1/teams/:id 命令:列表(?user_id= — 用户命令 + 角色)· 创建 · 详情(成员+授权)· 删除(级联 state)
POST/DELETE /v1/teams/:id/members… · /grants… 团队成员与授权(管理员)
POST/DELETE /v1/my/teams/:id/… 团队 owner 自助管理(仅限自身授权范围内)
GET /v1/docs 文档目录(JSON 格式)(语言、章节/页面 {id,title})
GET /v1/docs/page?id=&lang= 文档页面(markdown 格式){id,title,lang,markdown}
GET /v1/bench/runs · /v1/bench/catalog 所有模板的运行记录 · 已配置场景的模板

🔒 = 当配置了管理员认证时,需要 Authorization: Bearer <токен> (见 §8.3)。

分页

列表类端点(/v1/sessions、/v1/agents、/v1/templates、 /v1/budgets)接受 ?limit=N&offset=M。limit — 页大小(截断至 1–1000,默认 100),offset — 跳过多少行(默认 0)。 响应包含 total(而 /v1/sessions — 还有 history_total)。/v1/sessions 当历史会话超过当前页时,添加 history_truncated: true。


8.2 Chat completions

POST /v1/chat/completions 以 Server-Sent Events(SSE)方式流式传输。路径和请求 形式与 OpenAI 类似,但响应格式是自定义的 — 它与 OpenAI-SDK 不兼容(没有 choices[].delta,没有 data: [DONE])。

curl http://127.0.0.1:3000/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "ngu-agent",
    "messages": [{"role": "user", "content": "Как поступить в НГУ?"}]
  }'

请求字段:

字段 必填 含义
model 是 模板名称(ngu-agent、drom-agent、……)或内置的 assistant
messages 是 {role, content} 列表;进入上下文的是 user 和 system 角色
session 否 会话令牌 — 一个会话 = 一个隔离的 agent。省略则进入 legacy 模式(模板的共享 agent)
attachments 否 已通过 POST /v1/uploads 上传到会话 scratch 的 [{name, mime, size}] 文件列表 — 服务器会注入一条包含其描述的消息
stream 否 为兼容性而接受,被忽略 — 始终流式传输
temperature 否 接受,被忽略
max_tokens 否 接受,被忽略

请求头 X-User-Id 为 per-user 预算和记忆作用域设置 user_id。 当配置了 auth.web_user_secret_env 时,服务器要求 HMAC 签名的 X-User-Token(来自 POST /v1/user-ticket);见 §8.8。

响应(SSE 事件)

响应体是命名 SSE 事件流;done 是唯一始终存在的事件。

event 载荷 data
token {"content": "<токен>", "final": bool}
tool_call {"name": "<инструмент>", "body": "<рендер вызова>"}
tool_progress {"name": "<инструмент>", "body": "<прогресс>"}
tool_result {"name": "<инструмент>", "body": "<рендер результата>"}
result_blocks `{"name": "<инструмент>", "blocks": [ {type: "text"
input_request {"request_id": "<id>", "kind": "file"|"screenshot"|"photo", "description": "..."} — agent 请求附件;通过 POST /v1/input-response 回复
budget {"tokens": n, "prompt": n, "completion": n, "cached": n, "total": n, "cost": "$x.xxxx"}
done {} — 流已结束

result_blocks 承载工具的可视化层(图表、表格、文本、 文件);table 块可以包含 continuation: {id} — 使用该 id 的 POST /v1/continuations 会返回下一页的块,而 file 块承载 name、mime 和 data(base64)以供下载。见公共字段。

错误(未知模型、会话错误、预算耗尽、rate-limit) 以 token 事件的形式在 200 内报告,而不是通过 HTTP 错误码。

8.2.1 附件(uploads / input-response)

将用户文件(widget、Android)上传到会话的 scratch 目录 — POST /v1/uploads(multipart/form-data):

响应为 {"session_id": "...", "files": [{"name", "mime", "size"}, …]}。 文件写入 <scratch>/<session>/,之后 agent 按名称读取它们 (file_tool temp、shell_tool {{temp_dir}}、vision_tool)。会考虑 模板的 attachments.enabled/max_size;当附件被禁用时 — 400。

Agent 的附件请求(工具 request_attachment)以 SSE 事件 input_request 的形式到达;widget 显示提示,用户附加文件, 文件通过 /v1/uploads 上传,之后 widget 解析该请求:

curl http://127.0.0.1:3000/v1/input-response \
  -H 'Content-Type: application/json' \
  -d '{"request_id": "<id>", "files": [{"name": "photo.jpg", "mime": "image/jpeg", "size": 12345}]}'

空的 files = 用户拒绝。未知/过期的 request_id — 404;默认等待 300 秒(工具的 timeout_secs 字段)。

8.2.2 注意力(attention)与 push

当 agent 调用 notify_tool(或触发 push 同步)时,服务器 向该用户所有已连接的客户端发布注意力事件。

GET /v1/attention/stream — 长生命周期的注意力事件 SSE 流 (x-user-id / x-user-token,与聊天相同)。客户端(Android 前台服务、 Web widget)保持连接并自行绘制通知;这是 live 路径。

event: attention
data: {"title":"...","body":"...","level":"alert","require_ack":false,"session_id":"...","template":"...","channels":[]}

level 级别:silent | notify | alert | alarm | call。alarm/call (或 require_ack: true)表示“重复直到确认” — Android 显示全屏闹钟/来电,widget — 带声音的横幅。

方法 路径 含义
GET /v1/attention/stream 用户的注意力 SSE 流
POST /v1/push/register {kind, endpoint} — 注册设备的 push-endpoint(UnifiedPush/ntfy)用于 wakeup
POST /v1/push/unregister {kind, endpoint} — 删除 endpoint

如果在发布时刻没有任何 live 订阅者,服务器会向 已注册的 endpoint 发送 wakeup(不经过 Google — 通过 UnifiedPush/ntfy),被杀死的 应用会醒来并显示通知。详情与示例 — config/agents/notify-demo/README.md。


8.3 Auth

🔒 端点接受 Authorization: Bearer <токен>(用于 API 客户端), 或 cookie agentos_session(用于 web 登录后的浏览器)。

如果 auth 已配置,但没有任何 credential 被允许——管理 API 对每个请求 返回 401(fail-closed)。没有令牌和用户时,管理 API 是开放的 (dev 模式)。

# API-клиент (bearer)
curl -H 'Authorization: Bearer <token>' http://127.0.0.1:3000/v1/sessions

# Web-логин (браузерный поток)
curl -c cookies.txt -H 'Content-Type: application/json' \
  -d '{"username":"admin","password":"<password>"}' \
  http://127.0.0.1:3000/login
curl -b cookies.txt http://127.0.0.1:3000/v1/sessions

8.4 嵌入小组件

<script src="http://127.0.0.1:3000/widget.js"></script>

小组件由 /widget 提供,与 /v1/chat/completions 通信,并通过 POST /v1/sessions/:id(sendBeacon) 关闭会话。小组件的完整解析 (配置、模型选择、演示)——见 §19。


8.5 代理

/proxy 和 /proxy/content 为前端下载 URL。限制:


8.6 健康检查

curl http://127.0.0.1:3000/health

8.7 HTTPS / TLS

设置 AGENT_OS_TLS_CERT 和 AGENT_OS_TLS_KEY(PEM 路径)——服务器将启用 HTTPS。否则——在 AGENT_OS_BIND 上使用普通 HTTP(默认 127.0.0.1:3000)。


8.8 传入 webhook 与身份

传入 webhook

POST /v1/inbound/:template —— 外部系统(CRM、ERP、监控、表单 后端……)启动一次 agent 运行并同步读取响应——无 SSE,无 messages 数组。

curl -X POST http://127.0.0.1:3000/v1/inbound/ngu-agent \
  -H 'Content-Type: application/json' \
  -d '{"message":"какие общежития у НГУ?","session_id":"crm-123"}'

请求:

字段 必填 含义
message 是 用户消息
session_id 否 用于复用上下文的稳定 id;省略 = 新会话
user_id 否 最终用户的身份(Origin::Webhook);省略 = 匿名

响应:{"answer": "...", "status": "success", "session_id": "...", "cost_usd": 0.0, "prompt_tokens": n, "completion_tokens": n, "data": null}。

Auth —— 在设置了 inbound.token_env 时使用 bearer 令牌(空 = 开放,dev)。

最终用户身份令牌

当 auth.web_user_secret_env 指向带有 HMAC 密钥的 env 时,小组件会获得 签名令牌,并将其作为 X-User-Token 发送,而不是自报的 X-User-Id:

curl -X POST http://127.0.0.1:3000/v1/user-ticket \
  -H 'Content-Type: application/json' -d '{"user_id":"cw-browser-id"}'
# → {"user_id":"cw-browser-id","token":"cw-browser-id.<hmac>"}

没有密钥时,服务器直接信任 X-User-Id(dev 模式)。

用户规范身份

GET /v1/users 列出 (origin, external_id) → canonical_id 的对应关系; 操作员可以合并两个渠道 id(例如 web-id 和 Telegram-id),使 它们共享记忆、预算和状态:

curl -X POST http://127.0.0.1:3000/v1/users/link \
  -H 'Authorization: Bearer <token>' \
  -d '{"survivor":"cw-browser-id","merged":"tg:123"}'

合并会迁移 scoped state store、长期记忆和内存预算桶; 两个渠道后续的会话都会解析为 survivor。


8.9 反馈(feedback)

小组件将回答评分(like / dislike / cleared)发送到 POST /v1/feedback (公开),而统计数据发送到 GET /v1/feedback/stats(🔒)。

评分闭合质量循环:memory 钩子在点赞/点踩时提升/降低 本次运行中回忆起的 importance 事实(§6.6)。请求体包含 value、user_text、session。