本文档由英文原版机器翻译而成。如果翻译版本与英文原版之间存在任何冲突,请以英文原版为准。 阅读英文原版


公共 API

Caiioo 包含一个 REST API,让您可以通过程序控制一切:运行智能体、管理工具、安排任务等。该 API 运行在为桌面应用和浏览器桥接提供支持的同一个本地服务器上。

基础 URL: http://localhost:3847/v1

身份验证: 两种验证方式,均受设置中 API 开关的控制:

对于外部使用者(脚本、集成、curl): 在 设置 > API 访问 中设置 API 访问令牌,然后将其作为 Bearer 令牌使用:

curl -H "Authorization: Bearer YOUR_API_TOKEN" http://localhost:3847/v1/providers

对于本地应用(自动): Caiioo 桌面应用、浏览器扩展和移动应用通过现有的中继认证请求头 (X-Relay-Auth) 自动进行身份验证。无需手动设置 —— 应用会在后台处理。

设置:

  1. 打开 Caiioo 设置 > API 访问
  2. 启用公共 API 开关打开
  3. 设置一个 API 访问令牌(您选择的任何字符串 —— 请像对待密码一样对待它)
  4. 在所有 API 请求中使用该令牌

该 API 可在 localhost 和通过私有中继访问。查看 GET /v1/auth/info(无需验证)以获取当前状态和设置说明。

提供商与模型

发现已配置的 LLM 提供商以及可用的模型。

列出提供商:

GET /v1/providers

返回所有已配置的提供商类型(Anthropic, OpenAI, Google, OpenRouter, Ollama, Poe, MLX, Baseten 以及其他新增的),包含能力标志(supportsVision, supportsToolCalling, supportsStreaming 等)以及是否配置了 API 密钥。

列出提供商的模型:

GET /v1/providers/anthropic/models

返回该提供商的模型目录。每个模型包含 iddisplayName 以及可用的 contextLength

跨提供商的扁平化目录:

GET /v1/models

将每个已配置提供商的模型合并为一个列表。未配置 API 密钥的提供商将被跳过并列在 warnings 中。

智能体 (Agents)

智能体是 Caiioo 的核心。每个智能体都是一种 模式 (Mode) —— 一个配置好的个性,拥有自己的系统提示词、工具、变量和技能。

列出所有智能体:

GET /v1/agents

返回内置智能体(购物、工作、通用)以及您创建的任何自定义智能体。每个智能体都标记有 source: \"builtin\"source: \"custom\"

创建自定义智能体:

POST /v1/agents
Content-Type: application/json

{
  \"id\": \"my-research-agent\",
  \"branding\": {
    \"name\": \"研究助手\",
    \"description\": \"搜索网页并总结发现\"
  },
  \"defaultSettings\": {
    \"systemPrompt\": \"你是一名研究助手。务必注明来源。\",
    \"enabledTools\": { \"web_browsing\": true, \"search_tools\": true }
  },
  \"settingLevels\": {}
}

返回 201 及创建的智能体。系统会自动附加向量时钟用于同步。

更新智能体:

PATCH /v1/agents/my-research-agent
Content-Type: application/json

{ \"branding\": { \"name\": \"研究助手\", \"description\": \"更新后的描述\" } }

将补丁合并到现有智能体中并更新向量时钟。内置智能体返回 403 —— 它们是只读的。

删除智能体:

DELETE /v1/agents/my-research-agent

通过墓碑机制进行软删除(跨设备同步)。返回 204

运行智能体

这是核心功能 —— 调用智能体来处理消息。

同步模式

等待完整响应:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "input": { "message": "今天巴黎的天气怎么样?" },
  "mode": "sync"
}

智能体完成后返回 200{ content, usage, status: "completed" }。如果智能体出错,返回 500{ error, status: "error" }

异步模式

即发即弃 —— 适用于耗时较长的任务:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "my-research-agent",
  "input": { "message": "写一篇 2000 字的可再生能源趋势分析" },
  "mode": "async"
}

立即返回 202{ runId, threadId, status: "running" }

轮询状态:

GET /v1/runs/{runId}

返回 { run: { runId, threadId, agentId, status, createdAt, content?, usage?, error? } }。状态为 runningcompletederrorcancelled 之一。

实时流式传输事件 (SSE):

GET /v1/runs/{runId}/events

返回 text/event-stream,包含发生的每个智能体事件:GENERATION_STARTEDSTREAMING_CONTENT、工具调用、子智能体活动以及终端事件(GENERATION_COMPLETEGENERATION_ERRORGENERATION_CANCELLED)。流在终端事件后结束。

取消运行:

POST /v1/runs/{runId}/cancel

返回 { run: { ..., status: "cancelled" } }

Threads

Threads 即对话。每一次智能体运行都发生在 Thread 中,且 Thread 会跨会话持久保存。API 允许你通过编程方式列出、读取、创建和管理 Thread。

列出所有 Thread(仅元数据):

GET /v1/threads

返回当前 Profile 的 Thread 列表,为了性能已剔除具体消息内容。每个 Thread 包含 idtitlecreatedAtupdatedAtmodeIdarchived 以及使用统计。

获取包含完整消息的 Thread:

GET /v1/threads/{id}

返回完整的 Thread 对象,包括其 messages 数组 —— 包含每一条用户消息、助手响应、工具调用和工具结果。

仅获取消息:

GET /v1/threads/{id}/messages

仅返回 messages 数组 —— 当你只需要对话内容时,这比完整的 Thread 对象更轻量。

创建一个 Thread:

POST /v1/threads
Content-Type: application/json

{ "title": "Research project", "modeId": "general" }

返回 201 及新创建的 Thread。默认情况下,API 不会切换应用的当前活动 Thread —— 如果需要切换,请在请求体中传入 "setActive": true。新 Thread 会立即出现在侧边栏中(通过 WebSocket 广播)。

更新一个 Thread:

PATCH /v1/threads/{id}
Content-Type: application/json

{ "title": "Renamed project", "archived": true }

可更新的字段包括:titlemodeIdarchivedlastUsedModel。更改会实时广播到侧边栏。

删除一个 Thread:

DELETE /v1/threads/{id}

软删除该 Thread(用于同步的墓碑标记)。返回 204。删除的 Thread 会移动到垃圾箱,在清空垃圾箱前可以恢复。

活动 Thread:

GET /v1/threads/active            # 返回 { threadId }
PUT /v1/threads/active            # 请求体: { "threadId": "..." }

垃圾箱管理:

GET /v1/threads/trash/count       # 返回 { count }
POST /v1/threads/trash/empty      # 返回 { deletedCount, protectedCount }

受保护的 Thread(通过数据保留开关保留的内容)不会被清空垃圾箱操作删除。

通过 API 继续对话: 要向现有 Thread 发送后续消息,请使用 POST /v1/runs 并携带该 Thread 的 ID:

POST /v1/runs
Content-Type: application/json

{
  "agentId": "general",
  "threadId": "existing-thread-id",
  "input": { "message": "Follow up on that last point" },
  "mode": "sync"
}

智能体会看到该 Thread 中的完整对话历史。

附件

附件是链接到线程的文件 —— 屏幕截图、PDF、文档、上传的图像、生成的制品。API 允许你列出、上传、下载和管理它们。

列出所有附件(仅限元数据):

GET /v1/attachments

返回当前配置文件的附件元数据。大字段(dataUrl, extractedContent, extractedImages)已被剥离 —— 请使用详情或内容端点获取这些字段。

列出特定线程的附件:

GET /v1/threads/{threadId}/attachments

获取附件元数据:

GET /v1/attachments/{id}

返回完整元数据,包括 extractedContent(OCR 文本、解析后的 markdown)、contentTypefileNamesize 以及 hasContent 标志。原始二进制文件包含在内 —— 请使用 /content 端点获取。

下载附件二进制文件:

GET /v1/attachments/{id}/content

返回带有正确 Content-TypeContent-Disposition 标头的原始文件。将其通过管道传输到文件:

curl -o output.pdf \
  -H "Authorization: Bearer $API_TOKEN" \
  http://localhost:3847/v1/attachments/{id}/content

上传附件:

POST /v1/attachments
Content-Type: application/json

{
  "threadId": "thread-id",
  "type": "user_upload",
  "contentType": "application/pdf",
  "fileName": "report.pdf",
  "description": "季度报告",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ..."
}

dataUrl 是 base64 编码的数据 URL。返回 201 以及新的附件 ID。附件将链接到指定的线程。

更新附件元数据:

PATCH /v1/attachments/{id}
Content-Type: application/json

{ "description": "更新后的描述", "fileName": "new-name.pdf" }

删除附件:

DELETE /v1/attachments/{id}

通过墓碑机制进行软删除。返回 204

MCP Servers

管理您的 MCP (Model Context Protocol) 服务器连接 —— 这些服务器为智能体提供访问外部工具和数据源的权限。

列出已配置的服务器:

GET /v1/mcp-servers

返回当前配置文件中所有的 MCP 服务器配置。响应中会剔除敏感字段(authTokenenvcredentialId)。

获取特定服务器配置:

GET /v1/mcp-servers/{id}

添加新的 MCP 服务器:

POST /v1/mcp-servers
Content-Type: application/json

{
  "id": "my-server",
  "name": "My MCP Server",
  "command": "npx",
  "args": ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/files"],
  "serverType": "local"
}

对于远程 HTTP 服务器,请使用 "url" 代替 "command"

{
  "id": "remote-server",
  "name": "Remote API",
  "url": "https://my-mcp-server.example.com/sse",
  "serverType": "remote"
}

更新服务器:

PATCH /v1/mcp-servers/{id}
Content-Type: application/json

{ "name": "Renamed Server", "args": ["-y", "@mcp/server-v2"] }

启用/禁用服务器:

POST /v1/mcp-servers/{id}/toggle
Content-Type: application/json

{ "enabled": false }

删除服务器:

DELETE /v1/mcp-servers/{id}

进程管理

对于本地 (stdio) MCP 服务器,您可以直接管理服务器进程。

列出运行中的进程:

GET /v1/mcp-servers/processes

返回包含 pidstartedAtrunning 状态的运行中服务器进程。

启动服务器:

POST /v1/mcp-servers/{id}/start

从服务器配置中读取 command/args/env 并生成进程。返回进程状态。

停止服务器:

POST /v1/mcp-servers/{id}/stop

优雅地关闭服务器进程(先发送 SIGTERM,若无效则发送 SIGKILL)。

直接调用 JSON-RPC 方法:

POST /v1/mcp-servers/{id}/call
Content-Type: application/json

{ "method": "tools/list", "params": {} }

向服务器发送原始 JSON-RPC 2.0 请求并返回结果。适用于调试或调用未通过 tools API 公开的方法。

工具与工具包

浏览并调用智能体使用的工具 —— 网络浏览、搜索、日历、Gmail、Slate 等。

列出工具包(分组):

GET /v1/toolkits

返回按类别(生产力、搜索、实用工具等)分组的内置工具,以及作为独立工具包连接的任何 MCP 服务器,每个工具包都列出了其操作。

列出所有工具(扁平):

GET /v1/tools
GET /v1/tools?source=embedded   # 仅限内置工具
GET /v1/tools?source=mcp        # 仅限 MCP 服务器工具

获取带有输入架构的工具详情:

GET /v1/tools/calculator

返回工具输入参数的 JSON Schema,以便你在调用前进行验证。

直接调用工具:

POST /v1/tools/calculator/invoke
Content-Type: application/json

{ "input": { "expression": "sqrt(144) + 3^2" } }

返回 { result }。输入会根据工具的架构进行验证 —— 无效输入返回 422 及其详情。远程 MCP 工具返回 501 并建议改用 /v1/runs(它们需要智能体子进程传输)。

连接器

管理 OAuth 集成 —— Google、Microsoft、GitHub、Notion、Slack 等。

浏览可用集成:

GET /v1/connectors/catalog

返回所有已注册的 OAuth 提供商及其名称、类别和默认范围。

列出你的已连接账号:

GET /v1/connectors

返回当前配置文件的活动连接。令牌绝不会泄露 —— 仅公开元数据(提供商、电子邮件、状态、范围、时间戳)。

检查连接健康状况:

POST /v1/connectors/{id}/test

返回 { health: { status, isTokenExpired, canRefresh } }

移除连接:

DELETE /v1/connectors/{id}

创建新连接需要通过应用 UI 或 /auth/* 路由进行交互式 OAuth 流程。

触发器

调度智能体自动运行 —— 每日简报、每周报告、基于间隔的监控。

列出触发器:

GET /v1/triggers

创建调度触发器:

POST /v1/triggers
Content-Type: application/json

{
  "name": "早间简报",
  "prompt": "总结我的未读邮件和今天的日历",
  "modeId": "general",
  "schedule": { "type": "daily", "time": "08:00" }
}

支持的调度类型:

  • { "type": "interval", "minutes": 60 } — 每 N 分钟(最小 15,最大 1440)
  • { "type": "daily", "time": "09:00" } — 每天特定时间
  • { "type": "weekly", "day": "mon", "time": "09:00" } — 每周
  • { "type": "weekdays", "time": "08:30" } — 周一至周五
  • { "type": "daysOfWeek", "days": ["mon", "wed", "fri"], "time": "10:00" } — 特定日期
  • { "type": "monthly", "dayOfMonth": 1, "time": "09:00" } — 每月
  • { "type": "manual" } — 仅在通过 API 触发时运行

手动触发:

POST /v1/triggers/{id}/fire

返回 202 以及结果运行的 threadId

更新或删除:

PATCH /v1/triggers/{id}
DELETE /v1/triggers/{id}

Webhooks

Webhook 触发器允许外部服务(CI/CD、监控、表单构建器)通过 HTTP 触发智能体运行。

创建 Webhook 触发器:

POST /v1/triggers
Content-Type: application/json

{
  "name": "部署钩子",
  "prompt": "发生了一次部署:{{webhook.body}}",
  "modeId": "general",
  "kind": "webhook"
}

返回 201 以及 webhookSecretwebhookPath。请保存该密钥 —— 你将需要它来对有效负载进行签名。

发送 Webhook:

# 计算原始请求体的 HMAC-SHA256
SIGNATURE=$(echo -n '{"repo":"my-app","branch":"main"}' | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $2}')

POST /v1/webhooks/{triggerId}
Content-Type: application/json
X-Webhook-Signature: $SIGNATURE

{"repo": "my-app", "branch": "main"}

Webhook 端点不需要 Bearer 认证 —— 它使用 HMAC 验证。返回 202 以及分派运行的 threadId。触发器提示词中的 {{webhook.body}} 占位符将被替换为原始请求体。

自定义函数

创建智能体可以调用的自有工具。函数使用 JavaScript 或 Python 编写,并在沙箱中执行。

列出函数:

GET /v1/functions

创建函数:

POST /v1/functions
Content-Type: application/json

{
  "name": "calculate_bmi",
  "description": "根据身高和体重计算身体质量指数",
  "language": "javascript",
  "source": "return { bmi: (input.weightKg / (input.heightM * input.heightM)).toFixed(1) };",
  "inputSchema": {
    "type": "object",
    "properties": {
      "weightKg": { "type": "number" },
      "heightM": { "type": "number" }
    },
    "required": ["weightKg", "heightM"]
  }
}

JavaScript 函数接收 input 并必须返回结果。Python 函数设置 result 变量:

# Python 示例
result = {"bmi": round(input["weightKg"] / (input["heightM"] ** 2), 1)}

直接执行函数:

POST /v1/functions/{id}/execute
Content-Type: application/json

{ "input": { "weightKg": 75, "heightM": 1.80 } }

安全性: JavaScript 在 Node 的 vm 沙箱中运行(无文件系统或网络访问,10 秒超时)。Python 作为子进程运行,超时时间为 30 秒。两者在执行前都会验证输入。

更新或删除:

PATCH /v1/functions/{id}
DELETE /v1/functions/{id}

工作流

在 DAG(有向无环图)中编排多个智能体 —— 尽可能并行运行步骤,并将早期步骤的输出提供给后续步骤。

验证工作流图:

POST /v1/workflows/validate
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "研究可再生能源趋势" },
      { "id": "analyze", "agentId": "general", "prompt": "研究竞争对手定价" },
      { "id": "report", "agentId": "general", "prompt": "编写一份结合以下内容的报告:{{outputs.research}} 和 {{outputs.analyze}}", "dependsOn": ["research", "analyze"] }
    ]
  }
}

返回 { valid: true/false, errors: [...] }。检查循环引用、重复 ID 和缺失的依赖引用。

执行工作流:

POST /v1/workflows/execute
Content-Type: application/json

{
  "graph": {
    "nodes": [
      { "id": "research", "agentId": "general", "prompt": "研究可再生能源趋势" },
      { "id": "summarize", "agentId": "general", "prompt": "总结:{{outputs.research}}", "dependsOn": ["research"] }
    ]
  }
}

返回 { status: "completed", outputs: { research: "...", summarize: "..." }, nodeResults: {...} }

独立节点(无共享依赖)并行运行。节点提示词中的 {{outputs.nodeId}} 占位符将被替换为命名的上游节点的输出内容。每个节点都是一次完整的智能体运行,因此它可以使用工具、浏览网页并访问目标智能体的所有功能。

知识库

将文档组织成可搜索的集合,供智能体参考。

列出知识库:

GET /v1/knowledge/bases

创建知识库:

POST /v1/knowledge/bases
Content-Type: application/json

{ "name": "研究论文" }

返回 201 以及新的知识库 ID。

向知识库上传文档:

POST /v1/knowledge/bases/{id}/documents
Content-Type: application/json

{
  "fileName": "research-paper.pdf",
  "contentType": "application/pdf",
  "dataUrl": "data:application/pdf;base64,JVBERi0xLjQ...",
  "description": "2026 年可再生能源趋势"
}

dataUrl 字段是 base64 编码的数据 URL。返回 201 以及文档元数据。

列出知识库中的文档:

GET /v1/knowledge/bases/{id}/documents

在知识库中搜索:

POST /v1/knowledge/bases/{id}/search
Content-Type: application/json

{ "query": "可再生能源" }

根据文件名和描述返回匹配的文档。语义(向量)搜索将在未来版本中推出。

删除文档或知识库:

DELETE /v1/knowledge/bases/{id}/documents/{docId}
DELETE /v1/knowledge/bases/{id}

导出与导入智能体

将智能体作为便携式包进行分享 —— 跨设备、跨团队或在社区中心分享。

导出智能体:

POST /v1/agents/{id}/export

返回一个 JSON 包,包含智能体定义、工具需求(源自启用的工具)、连接器需求(需要哪些 OAuth 提供商)和触发器模板。同步元数据已被剥离 —— 该包是一个干净、自包含的蓝图。

导入智能体:

POST /v1/agents/import
Content-Type: application/json

{
  \"package\": {
    \"$schema\": \"caiioo.agent.package/v1\",
    \"agent\": {
      \"id\": \"shared-research-agent\",
      \"branding\": { \"name\": \"研究助手\", \"description\": \"来自团队\" },
      \"defaultSettings\": { \"systemPrompt\": \"你负责研究事物。\" },
      \"settingLevels\": {}
    },
    \"toolRequirements\": [
      { \"toolId\": \"web_browsing\", \"enabled\": true },
      { \"toolId\": \"search_tools\", \"enabled\": true }
    ]
  }
}

返回 201 及安装的智能体。与内置或现有智能体的 ID 冲突将返回 409

错误处理

API 使用标准 HTTP 状态码:

代码 含义
200 成功
201 已创建
202 已接受(异步操作已启动)
204 已删除(无内容)
400 错误请求 —— 检查 error 字段获取详情
401 未授权 —— 缺失或无效的会话密钥
403 禁止访问 —— 例如:尝试修改内置智能体
404 未找到
409 冲突 —— 例如:智能体 ID 已存在
422 验证错误 —— 输入不符合工具架构
500 服务器错误 —— 检查 error 字段
501 未实现 —— 功能存在但无法通过此方式使用
503 服务不可用 —— 存储或提供商未就绪

所有错误响应均包含 { "error": "人类可读的消息" }

快速入门示例

这是一个完整的工作流:创建一个智能体,运行它,并流式传输结果。

# 1. 创建自定义智能体
curl -X POST http://localhost:3847/v1/agents \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "id": "quick-summarizer",
    "branding": { "name": "快速总结器" },
    "defaultSettings": {
      "systemPrompt": "用 3 个要点简洁地总结任何输入。",
      "enabledTools": { "web_browsing": true }
    },
    "settingLevels": {}
  }'

# 2. 异步运行
RUN=$(curl -s -X POST http://localhost:3847/v1/runs \
  -H "Authorization: Bearer $API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "agentId": "quick-summarizer", "input": { "message": "总结 https://en.wikipedia.org/wiki/Artificial_intelligence" }, "mode": "async" }')

RUN_ID=$(echo $RUN | jq -r '.runId')

# 3. 流式传输事件
curl -N http://localhost:3847/v1/runs/$RUN_ID/events \
  -H "Authorization: Bearer $API_TOKEN"

# 4. 导出智能体以供共享
curl -X POST http://localhost:3847/v1/agents/quick-summarizer/export \
  -H "Authorization: Bearer $API_TOKEN"

This guide is maintained by the Caiioo team using Slate, our built-in editor.