zoowork-managed-agents

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Building on ZooWork Managed Agents

基于 ZooWork Managed Agents 构建

Start with the user's task, then read only the reference that owns it. The public API is a Developer Preview, so inspect the installed SDK before relying on a remembered signature.
先从用户任务入手,然后只阅读负责该任务的参考文档。公共 API 仍处于 Developer Preview 阶段,因此不要依赖记忆中的签名,编写代码前应先检查已安装的 SDK。

Four invariants

四项不变原则

These are the most common reasons code compiles but fails at runtime:
  1. createAgent
    creates a stopped Agent. Call
    startAgent(id)
    and wait for
    desired_state
    before opening a Session.
  2. Every Session method takes
    agentId
    first.
  3. Assistant text comes from
    agent.assistant
    through
    assistantText()
    /
    assistant_text()
    .
  4. A Session stream does not close at turn end. Break on
    run.finished
    through
    isRunFinished()
    /
    is_run_finished()
    .
以下是代码能够编译但运行时失败的最常见原因:
  1. createAgent
    创建的是已停止的 Agent。打开 Session 前,应调用
    startAgent(id)
    并等待
    desired_state
    。
  2. 每个 Session 方法都先将
    agentId
    作为第一个参数。
  3. Assistant 文本通过
    assistantText()
    /
    assistant_text()
    从
    agent.assistant
    获取。
  4. Session stream 不会在轮次结束时关闭。应通过
    isRunFinished()
    /
    is_run_finished()
    在
    run.finished
    时退出循环。

Preflight

预检查

Before writing code:
  1. Read
    package.json
    ,
    pyproject.toml
    , lockfiles, and existing imports.
  2. Determine whether the project uses
    @zoowork-ai/sdk
    or
    zoowork
    , and record its installed version. Do not upgrade it unless the user asks.
  3. Check whether
    ZOOWORK_API_KEY
    and
    ZOOWORK_BASE_URL
    are present without printing their values.
  4. Reuse the project's existing client and configuration style.
  5. Read the routed reference below. For an exact method or type, verify the installed declarations or Python source as the final authority.
If no project is present, state which package and runtime the example assumes. TypeScript requires Node.js 20+; Python requires Python 3.10+. Install the published package with
npm install @zoowork-ai/sdk
or
python -m pip install zoowork
. The public docs and these references assume
@zoowork-ai/sdk
0.10.0+ and
zoowork
0.5.0+; if an existing project pins an older release, say so and ask before upgrading.
编写代码前:
  1. 阅读
    package.json
    、
    pyproject.toml
    、lockfile 和现有 import。
  2. 确定项目使用的是
    @zoowork-ai/sdk
    还是
    zoowork
    ,并记录已安装的版本。除非用户要求,否则不要升级。
  3. 检查
    ZOOWORK_API_KEY
    和
    ZOOWORK_BASE_URL
    是否存在,但不要打印它们的值。
  4. 复用项目现有的 client 和配置风格。
  5. 阅读下方对应的参考文档。对于确切的方法或类型,应以已安装的声明文件或 Python 源码作为最终依据。
如果不存在项目,应说明示例假定使用哪个 package 和 runtime。TypeScript 需要 Node.js 20+;Python 需要 Python 3.10+。可通过
npm install @zoowork-ai/sdk
或
python -m pip install zoowork
安装已发布的 package。公共文档和这些参考资料假定
@zoowork-ai/sdk
0.10.0+ 和
zoowork
0.5.0+;如果现有项目锁定了更旧的版本,应说明情况,并在升级前询问用户。

Route by task

按任务选择参考文档

User intentRead before acting
TypeScript method, option, return shape, Agent config, model, MCP, permission, Environment, channel, schedule, approval, artifact,
exec
, or
wake
references/typescript-sdk.md
Python import, snake_case method, return shape, event helper, custom tool, Session cursor, Agent config, MCP, or channel
references/python-sdk.md
Text task inputs, file outputs, Database availability, Usage, webhook registration/verification/delivery diagnostics, Run Output, or action paging/detail
references/developer-api.md
Stream replies, reconnect, render events or tool calls, read/export history, or write Session events
references/events-and-streaming.md
Host an Agent built locally, select its Skills, deploy one Agent per user, or keep one Skill synchronized across a fleet
references/deploy-your-agent.md
— follow it in order
Upload, version, list, or delete a platform Skill ZIP
references/skill-registry.md
— check deployment support and the key's write scope
Credentials, binary file attachment, repository mount, worker queues, cross-Agent Session listing, rollback, or another uncertain capability
references/not-supported.md
— check before designing
Read more than one reference only when the request genuinely crosses those boundaries. For example, a basic streaming chat needs the language reference plus events; it does not need the deployment or capability-boundary documents.
用户意图动手前阅读
TypeScript 方法、选项、返回结构、Agent 配置、模型、MCP、权限、Environment、Channel、Schedule、审批、Artifact、
exec
或
wake
references/typescript-sdk.md
Python import、snake_case 方法、返回结构、事件 helper、自定义工具、Session cursor、Agent 配置、MCP 或 Channel
references/python-sdk.md
文本任务输入、文件输出、Database 可用性、Usage、webhook 注册、验证与投递诊断、Run Output,或 action 分页与详情
references/developer-api.md
流式回复、重新连接、渲染事件或工具调用、读取或导出会话历史,或写入 Session 事件
references/events-and-streaming.md
托管本地构建的 Agent、选择其 Skill、为每位用户部署一个 Agent,或让一个 Skill 在整个 Agent 集合中保持同步
references/deploy-your-agent.md
——请按顺序遵循该文档
上传、版本化、列出或删除平台 Skill ZIP
references/skill-registry.md
——检查部署支持情况以及 key 的写入 scope
凭据、二进制文件附件、repository mount、worker queue、跨 Agent Session 列举、回滚,或其他尚不确定的能力
references/not-supported.md
——设计前先检查
仅当请求确实跨越这些边界时,才阅读多份参考文档。例如,基础流式聊天需要语言参考和事件参考;不需要部署或能力边界文档。

Choose the path

选择实现路径

The user hasGive them
No API key or no running AgentThe setup flow below
A key and wants a chat UIThe official SDK on their backend, relaying the Session stream to their UI; follow
references/deploy-your-agent.md
Step 9
Their own backend, UI, or Agent designThe official SDK
A local persona and Skills that need hosted execution
references/deploy-your-agent.md
Build the UI in the user's own stack. The backend holds
ZOOWORK_API_KEY
, authorizes each end user, and re-emits Session events to the browser.
用户拥有提供
没有 API key,或没有运行中的 Agent下方的 setup 流程
有 key,并且需要聊天 UI在其 backend 上使用官方 SDK,将 Session stream 转发至 UI;遵循
references/deploy-your-agent.md
的 Step 9
自有 backend、UI 或 Agent 设计官方 SDK
需要托管执行的本地 persona 和 Skill
references/deploy-your-agent.md
应使用用户自己的技术栈构建 UI。backend 持有
ZOOWORK_API_KEY
、对每位终端用户进行授权,并向浏览器转发 Session 事件。

API key onboarding

API key 接入

Create a Project API key at https://platform.zoowork.ai. Agent and Session access is scoped to the selected Project. The secret is shown once; have the user save it in
ZOOWORK_API_KEY
themselves. Keep it on their backend, outside browser/mobile code, logs and chat.
Initialize Organization billing and bind owner credentials. If the API requests rebinding, sign in to Platform and rebind the key.
listModels()
/
list_models()
is a cheap read-only credential check; it does not prove runtime readiness or authorize a billable test.
在 https://platform.zoowork.ai 创建 Project API key。Agent 和 Session 访问权限限定在所选 Project 内。secret 仅显示一次;应让用户自行将其保存到
ZOOWORK_API_KEY
中。将其保存在 backend,避免放入浏览器或移动端代码、日志和聊天记录中。
初始化 Organization billing 并绑定 owner credentials。如果 API 请求重新绑定,应登录 Platform 并重新绑定 key。
listModels()
/
list_models()
是低成本的只读凭据检查;它不能证明 runtime 已就绪,也不代表已获准进行计费测试。

Minimal lifecycle

最小生命周期

Use this order:
  1. List models and select the platform's primary chat default: the row whose
    selectable
    value is not
    false
    and whose
    default_for
    includes
    model
    . Persist that explicit choice.
  2. Create the Agent once with a stable idempotency key.
  3. Persist
    agent_id
    .
  4. Start the Agent and wait for
    desired_state
    with the SDK helper.
  5. Create one Session per conversation.
  6. Post later turns into the same Session and resume streaming from the last processed cursor.
Do not create an Agent inside the function that answers every user message. Each Agent owns a persistent workspace and sandbox.
ts
import {
  assistantText,
  createZooworkClient,
  isRunFinished,
  runOutcome,
} from '@zoowork-ai/sdk'

const zc = createZooworkClient()
const models = await zc.listModels()
const model = models.find(
  (row) => row.selectable !== false && row.default_for?.includes('model'),
)?.model
if (!model) throw new Error('No selectable default ZooWork model')

const created = await zc.createAgent(
  { resource: { name: 'support-agent', model: { primary: model } } },
  'support-agent-v1',
)
const agentId = created.agent_id
await zc.startAgent(agentId)
await zc.waitUntilRunning(agentId)

const session = await zc.createSession(agentId, {
  initial_events: [{ type: 'user.message', content: 'Hello' }],
})

let cursor: string | undefined
for await (const event of zc.streamEvents(agentId, session.session_id)) {
  cursor = event.cursor ?? cursor
  process.stdout.write(assistantText(event))
  if (isRunFinished(event)) {
    if (runOutcome(event) !== 'succeeded') throw new Error(`run ${runOutcome(event)}`)
    break
  }
}
For Python, use the same lifecycle with
create_zoowork_client
,
list_models
,
create_agent
,
start_agent
,
wait_until_running
,
create_session
,
stream_events
,
assistant_text
, and
is_run_finished
. Read
references/python-sdk.md
before writing the exact call shapes; nested payloads retain public wire spelling where documented.
按以下顺序执行:
  1. 列出模型并选择平台的主要 chat 默认模型,即
    selectable
    值不为
    false
    且
    default_for
    包含
    model
    的那一行。持久保存这一明确选择。
  2. 使用稳定的 idempotency key 创建一次 Agent。
  3. 持久保存
    agent_id
    。
  4. 启动 Agent,并使用 SDK helper 等待
    desired_state
    。
  5. 为每段对话创建一个 Session。
  6. 将后续轮次发布到同一个 Session,并从最后处理的 cursor 恢复 stream。
不要在处理每条用户消息的函数内部创建 Agent。每个 Agent 都拥有独立的持久 workspace 和 sandbox。
ts
import {
  assistantText,
  createZooworkClient,
  isRunFinished,
  runOutcome,
} from '@zoowork-ai/sdk'

const zc = createZooworkClient()
const models = await zc.listModels()
const model = models.find(
  (row) => row.selectable !== false && row.default_for?.includes('model'),
)?.model
if (!model) throw new Error('No selectable default ZooWork model')

const created = await zc.createAgent(
  { resource: { name: 'support-agent', model: { primary: model } } },
  'support-agent-v1',
)
const agentId = created.agent_id
await zc.startAgent(agentId)
await zc.waitUntilRunning(agentId)

const session = await zc.createSession(agentId, {
  initial_events: [{ type: 'user.message', content: 'Hello' }],
})

let cursor: string | undefined
for await (const event of zc.streamEvents(agentId, session.session_id)) {
  cursor = event.cursor ?? cursor
  process.stdout.write(assistantText(event))
  if (isRunFinished(event)) {
    if (runOutcome(event) !== 'succeeded') throw new Error(`run ${runOutcome(event)}`)
    break
  }
}
对于 Python,使用相同的生命周期,并采用
create_zoowork_client
、
list_models
、
create_agent
、
start_agent
、
wait_until_running
、
create_session
、
stream_events
、
assistant_text
和
is_run_finished
。编写准确的调用形式前应阅读
references/python-sdk.md
;在已有文档说明的情况下,嵌套 payload 应保留公共 wire 拼写。

Session and event rules

Session 和事件规则

  • The event log contains user inputs, assistant replies, tool activity, and run completion.
  • Resume every subsequent turn with the last processed event's opaque
    cursor
    ; do not derive it from
    seq
    . Without a cursor the stream replays old turns. REST events and send receipts have no cursor, and the final REST continuation is null. There is no current-tail helper.
  • Checkpoint only after processing the event. Cursor resume does not make application side effects exactly-once.
  • listEvents()
    returns one page and drops pagination metadata. Use
    listAllEvents()
    for the full history or
    listEventsPage()
    for explicit cursor pagination.
  • toolCall().phase
    is
    start
    ,
    end
    , or
    blocked
    .
    blocked
    ends a call without execution; no
    end
    follows. Reasons include policy denial, approval denial/timeout/cancellation, or interruption; inspect the raw event payload's
    deniedReason
    . Approval waiting is
    agent.approval
    /
    requested
    .
  • A failed tool call does not necessarily fail the run.
    runOutcome()
    is the authority.
  • Retried writes should use a stable
    idempotency_key
    .
  • A valid
    user.interrupt
    with no active run can return
    accepted: false
    ; that is a normal no-op.
  • actor: { ref }
    selects memory attribution. It is not authentication, authorization, or sandbox isolation; derive it from authenticated backend state.
Application-executed custom tools pause the current run until the user's backend resolves them. They are not MCP tools and not a worker-registration API. Read both the language reference and the events reference before implementing recovery.
  • 事件日志包含用户输入、Assistant 回复、工具活动和运行完成事件。
  • 每个后续轮次都应使用最后一个已处理事件的不透明
    cursor
    恢复;不要根据
    seq
    推导。没有 cursor 时,stream 会重放旧轮次。REST 事件和发送回执没有 cursor,REST 的最终 continuation 为
    null
    。目前没有
    current-tail
    helper。
  • 仅在处理完事件后才执行 Checkpoint。通过 cursor 恢复并不能让应用副作用具备 exactly-once 保证。
  • listEvents()
    返回单页数据,并丢弃分页 metadata。获取完整历史记录应使用
    listAllEvents()
    ;显式进行 cursor 分页应使用
    listEventsPage()
    。
  • toolCall().phase
    的值为
    start
    、
    end
    或
    blocked
    。
    blocked
    表示调用未执行便已结束,之后不会出现
    end
    。原因包括策略拒绝、审批拒绝、超时、取消或中断;应检查原始事件 payload 中的
    deniedReason
    。等待审批的状态为
    agent.approval
    /
    requested
    。
  • 工具调用失败不一定会导致运行失败。
    runOutcome()
    是判断依据。
  • 重试写入操作时,应使用稳定的
    idempotency_key
    。
  • 在没有活跃运行的情况下,合法的
    user.interrupt
    可能返回
    accepted: false
    ;这是正常的 no-op。
  • actor: { ref }
    用于选择 memory 归属。它不是身份认证、授权或 sandbox 隔离机制;应从已通过认证的 backend 状态中派生。
由应用执行的自定义工具会暂停当前运行,直到用户的 backend 对其进行处理。它们不是 MCP 工具,也不是 worker-registration API。实现恢复逻辑前,应同时阅读语言参考和事件参考。

Platform Skills

平台 Skill

A ZooWork platform Skill is attached to a running Agent. It is different from this coding-agent skill, which teaches a developer's assistant how to call ZooWork.
  • New Agents receive global Skills by default. Set
    include_global_skills: false
    or an explicit empty Skill list to opt out.
  • Create bindings accept catalog
    name
    or
    skill_id
    ; inspect
    listAgentSkills
    /
    list_agent_skills
    to see the resolved assignment.
  • The source-reviewed Skill registry contract permits named Project keys to write
    project
    Skills and Default Project keys to write
    org
    Skills. Read
    references/skill-registry.md
    for upload, versioning, write permissions, SDK compatibility, and deployment verification.
  • Project keys do not administer root Environments or Channels. These are separate capabilities.
  • Use
    persona.docs
    for standing instructions and Session messages for text task inputs. Ask the Agent to create and publish output, then download it through the Artifact API. Read
    references/developer-api.md
    for this flow. A workspace file is not a registered Skill. Skill ZIP publishing has its own registry flow; it is not general binary task input upload.
  • Prove runtime behavior with an authorized real turn; attachment state alone does not prove use.
Follow
references/deploy-your-agent.md
for packaging, versioning, attachment verification, per-user isolation, scheduling, UI wiring, and teardown.
ZooWork 平台 Skill 依附于正在运行的 Agent。它与当前这个用于教开发者的 assistant 如何调用 ZooWork 的 coding-agent skill 不同。
  • 新 Agent 默认获得 global Skill。可设置
    include_global_skills: false
    ,或显式提供空 Skill 列表,以选择不使用。
  • 创建绑定时可以使用 catalog 的
    name
    或
    skill_id
    ;检查
    listAgentSkills
    /
    list_agent_skills
    ,查看解析后的分配结果。
  • 经 source-reviewed 的 Skill registry contract 允许具名 Project key 写入
    project
    Skill,并允许 Default Project key 写入
    org
    Skill。阅读
    references/skill-registry.md
    ,了解上传、版本管理、写入权限、SDK 兼容性和部署验证。
  • Project key 无权管理 root Environment 或 Channel。它们属于独立的能力。
  • 使用
    persona.docs
    存放长期指令,并使用 Session 消息传递文本任务输入。让 Agent 创建并发布输出,然后通过 Artifact API 下载。阅读
    references/developer-api.md
    以了解此流程。workspace 文件不是已注册的 Skill。Skill ZIP 发布采用独立的 registry 流程,不能作为通用的二进制任务输入上传。
  • 应通过经授权的真实轮次证明 runtime 行为;仅处于绑定状态并不能证明 Skill 已被使用。
有关打包、版本管理、绑定验证、逐用户隔离、调度、UI 接入和清理销毁,请遵循
references/deploy-your-agent.md
。

Capability and evidence boundary

能力与证据边界

“The SDK has no helper” and “the platform has no public contract” are different claims. Before saying a feature is absent, inspect the installed SDK, public docs,
references/developer-api.md
, and
references/not-supported.md
. A method in SDK declarations proves its signature, not that its endpoint works in production. Use the documented message-to-Artifact flow for text inputs and file outputs; do not add direct workspace Files calls as an input or download step.
Use these evidence labels:
  • Live-verified: exercised against a named deployment.
  • Source-reviewed: confirmed in public SDK source or declarations.
  • Offline-tested: covered by fixtures or unit tests without a live tenant.
  • Unknown: evidence is insufficient; do not invent a method or route.
Do not run live, billable, or tenant-mutating calls merely to answer a design question.
“SDK 没有 helper”和“平台没有 public contract”是两种不同的判断。在声称某项能力不存在之前,应检查已安装的 SDK、公共文档、
references/developer-api.md
和
references/not-supported.md
。SDK 声明中存在某个方法,只能证明其签名,不能证明对应 endpoint 可在生产环境中正常工作。文本输入和文件输出应使用有文档说明的 message-to-Artifact 流程;不要添加对 workspace Files 的直接调用来充当输入或下载步骤。
使用以下证据标签:
  • Live-verified: 已在指定的 deployment 上实际执行验证。
  • Source-reviewed: 已通过公共 SDK 源码或声明文件确认。
  • Offline-tested: 已通过 fixture 或单元测试覆盖,但未使用 live tenant。
  • Unknown: 证据不足;不要虚构方法或 route。
不要仅为回答设计问题而运行会产生费用或修改 tenant 状态的 live 调用。

Common pitfalls

常见陷阱

  • Wait on
    desired_state
    , never
    actual_state
    ; the latter is a chat-channel health projection.
  • Platform uses a managed Environment. Project keys do not administer root Environments.
  • createAgent
    and
    getAgent
    return different shapes.
  • Production Agent updates reject
    expected_config_version
    with
    400 invalid_declared_key
    . Omit it for ordinary last-write-wins updates and serialize competing writes in your backend. A GET followed by PUT is not atomic. The separate system-prompt upgrade precondition works.
  • MCP exposure, runtime context, and permission policy are separate controls.
  • Tool-policy wildcards allow an exact name, global
    *
    , or one trailing
    prefix*
    only.
  • There is no public credential store for an end user's secret.
  • Match
    ZooworkError.status
    and
    .type
    , not message text. Usage validation can return 422 with no business type; invalid timezone can return 400
    usage.invalid_query
    .
  • A cross-tenant or unknown identifier can return 404 rather than 403. Repeated Agent deletion also returns 404 after the first 204; treat it as cleanup complete only for your known Agent with unchanged key scope.
  • The production Database viewer is unavailable. Do not call its SDK helpers or HTTP routes. Ask the Agent to query via
    agent_db
    and return results or publish an Artifact.
  • A manual Schedule trigger requires
    enabled: true
    , which also enables automatic firings. Disabled triggers may acknowledge
    triggered: true
    but are skipped; this is not a test mode.
  • Create Agents one at a time within an Organization. Concurrent
    createAgent
    calls with the same key can fail with
    503 platform.runtime_credentials_unavailable
    ; no Agent is created, so retry with backoff and the same idempotency key.
  • For raw HTTP, use the SDK,
    curl
    ,
    requests
    or
    httpx
    . The public edge rejects Python's default
    urllib
    User-Agent (
    Python-urllib/...
    ) with
    403
    and the body
    error code: 1010
    . That is not an API-key error; set an explicit
    User-Agent
    header if you must use
    urllib
    .
  • exec(agentId, args)
    takes argv. A non-zero process exit can still be HTTP 200.
  • To remove a throwaway Agent, delete its schedules, call
    stopAgent
    , then
    deleteAgent
    . Deletion alone neither stops the sandbox nor removes schedules. If the stop fails, read
    getAgent
    and retry the stop before deleting; a deleted Agent cannot be stopped later.
  • Do not mix TypeScript camelCase with Python snake_case. Treat identifiers, cursors, and unknown response fields as opaque.
Public developer documentation is at https://zoowork.ai/docs/. For machine reading, use https://zoowork.ai/docs/llms.txt (an index of per-page Markdown) or https://zoowork.ai/docs/llms-full.txt (every page in one file).
  • 应等待
    desired_state
    ,绝不能等待
    actual_state
    ;后者是 chat channel 的健康状态投影。
  • Platform 使用受管理的 Environment。Project key 无权管理 root Environment。
  • createAgent
    和
    getAgent
    返回不同的数据结构。
  • 生产环境中的 Agent 更新会拒绝
    expected_config_version
    ,并返回
    400 invalid_declared_key
    。对于普通的 last-write-wins 更新,应省略该字段,并在 backend 中串行化相互竞争的写入。GET 后接 PUT 不是原子操作。单独用于 system-prompt 升级的前置条件仍然有效。
  • MCP exposure、runtime context 和 permission policy 是相互独立的控制机制。
  • Tool-policy 通配符仅允许精确名称、全局
    *
    ,或一个末尾的
    prefix*
    。
  • 没有用于保存终端用户 secret 的公共 credential store。
  • 应匹配
    ZooworkError.status
    和
    .type
    ,而不是匹配消息文本。Usage 校验可能返回没有业务 type 的 422;无效时区可能返回
    400 usage.invalid_query
    。
  • 跨 tenant 或未知 identifier 可能返回 404,而不是 403。首次删除返回 204 后,再次删除 Agent 也会返回 404;只有对于你已知且 key scope 未变化的 Agent,才能将其视为清理完成。
  • 生产 Database viewer 不可用。不要调用其 SDK helper 或 HTTP route。应让 Agent 通过
    agent_db
    查询并返回结果或发布 Artifact。
  • 手动触发 Schedule 需要
    enabled: true
    ,这也会启用自动触发。禁用状态的 trigger 可能仍确认
    triggered: true
    ,但实际会跳过执行;这不是测试模式。
  • 在 Organization 内应一次创建一个 Agent。使用相同 key 并发调用
    createAgent
    可能失败并返回
    503 platform.runtime_credentials_unavailable
    ;此时不会创建 Agent,因此应使用退避重试和相同的 idempotency key。
  • 对于原始 HTTP 请求,应使用 SDK、
    curl
    、
    requests
    或
    httpx
    。公共 edge 会拒绝 Python 默认的
    urllib
    User-Agent(
    Python-urllib/...
    ),返回 403 和
    error code: 1010
    。这不是 API key 错误;如果必须使用
    urllib
    ,应显式设置
    User-Agent
    header。
  • exec(agentId, args)
    接受 argv。进程以非零状态退出时,HTTP 响应仍可能为 200。
  • 要删除临时 Agent,应先删除其 schedule,再调用
    stopAgent
    ,最后调用
    deleteAgent
    。仅执行删除既不会停止 sandbox,也不会移除 schedule。如果停止失败,应读取
    getAgent
    并重试停止,然后才能删除;Agent 删除后将无法再停止。
  • 不要混用 TypeScript camelCase 和 Python snake_case。应以不透明方式处理 identifier、cursor 和未知响应字段。
公共开发者文档位于 https://zoowork.ai/docs/。如需供机器读取,可使用 https://zoowork.ai/docs/llms.txt(逐页 Markdown 索引)或 https://zoowork.ai/docs/llms-full.txt(包含所有页面的单一文件)。