Skip to content

OpenClaw App SDK 提供两层 API:从 Gateway 协议 schema 生成的低级客户端,和包含 OpenClaw、Agent、Session、Run 等对象的高级包装器。开发者通过 oc.agents.list() 等命名空间操作资源,用 run.onApproval() 处理审批请求,并利用版本化事件流构建 UI。本文列出所有 API 方法、事件全集、结果格式、审批模型、Token 作用域,以及包结构和生成客户端策略。

OpenClaw App SDK API 设计:命名空间、事件与安全模型

本文是公开 OpenClaw App SDK 的详细 API 参考设计,与 Plugin SDK 分开定义。

::: note @openclaw/sdk 是面向外部应用/客户端的网关通信包。openclaw/plugin-sdk/* 是进程内插件创作契约。仅需运行智能体的应用不要从插件 SDK 的路径导入。 :::

App SDK 分为两层:

  1. 低级 Gateway 客户端(从版本化协议 schema 生成)。
  2. 高级易用包装器,包含 OpenClawAgentSessionRunTaskArtifactApprovalEnvironment 对象。

命名空间设计

低级命名空间紧密对应 Gateway 资源:

typescript
oc.agents.list();
oc.agents.get("main");
oc.agents.create(...);
oc.agents.update(...);

oc.sessions.list();
oc.sessions.create(...);
oc.sessions.resolve(...);
oc.sessions.send(...);
oc.sessions.messages(...);
oc.sessions.fork(...);
oc.sessions.compact(...);
oc.sessions.abort(...);

oc.runs.create(...);
oc.runs.get(runId);
oc.runs.events(runId, { after });
oc.runs.wait(runId);
oc.runs.cancel(runId);

oc.tasks.list({ status: "running" });
oc.tasks.get(taskId);
oc.tasks.cancel(taskId, { reason });
oc.tasks.events(taskId, { after }); // 未来 API

oc.models.list();
oc.models.status(); // Gateway models.authStatus

oc.tools.list();
oc.tools.invoke("tool-name", { sessionKey, idempotencyKey });

oc.artifacts.list({ runId });
oc.artifacts.get(artifactId, { runId });
oc.artifacts.download(artifactId, { runId });

oc.approvals.list();
oc.approvals.respond(approvalId, ...);

oc.environments.list();
oc.environments.create(...); // 未来 API: 当前 SDK 抛出 unsupported
oc.environments.status(environmentId);
oc.environments.delete(environmentId); // 未来 API: 当前 SDK 抛出 unsupported

高级包装器应返回对象,使常见流程更顺畅:

typescript
const run = await agent.run(inputOrParams);
await run.cancel();
await run.wait();

for await (const event of run.events()) {
  // 标准化事件流
}

const artifacts = await run.artifacts.list();
const session = await run.session();

事件契约

公共 SDK 应公开版本化、可重放、标准化的事件。

typescript
type OpenClawEvent = {
  version: 1;
  id: string;
  ts: number;
  type: OpenClawEventType;
  runId?: string;
  sessionId?: string;
  sessionKey?: string;
  taskId?: string;
  agentId?: string;
  data: unknown;
  raw?: unknown;
};

id 是重放游标。消费者可以通过 events({ after: id }) 重新连接,并在保留期限内接收错过的事件。

推荐的标准事件家族:

事件含义
run.created运行被接受。
run.queued运行正在等待会话通道、运行时或环境。
run.started运行时开始执行。
run.completed运行成功结束。
run.failed运行因错误结束。
run.cancelled运行被取消。
run.timed_out运行超时。
assistant.delta助手文本增量。
assistant.message完整的助手消息或替换。
thinking.delta推理或计划增量(策略允许时暴露)。
tool.call.started工具调用开始。
tool.call.delta工具调用流式进度或部分输出。
tool.call.completed工具调用成功返回。
tool.call.failed工具调用失败。
approval.requested运行或工具需要审批。
approval.resolved审批被批准、拒绝、过期或取消。
question.requested运行时向用户或宿主应用询问输入。
question.answered宿主应用提供了答案。
artifact.created新产物可用。
artifact.updated已有产物发生变化。
session.created会话被创建。
session.updated会话元数据改变。
session.compacted会话发生压缩。
task.updated后台任务状态改变。
git.branch运行时观察或改变了分支状态。
git.diff运行时产生或改变了差异。
git.pr运行时打开、更新或关联了拉取请求。

运行时的原生载荷通过 raw 可用,但应用不需要解析 raw 来支持普通 UI。

结果契约

Run.wait() 应返回稳定的结果信封:

typescript
type RunResult = {
  runId: string;
  status: "accepted" | "completed" | "failed" | "cancelled" | "timed_out";
  sessionId?: string;
  sessionKey?: string;
  taskId?: string;
  startedAt?: string | number;
  endedAt?: string | number;
  output?: {
    text?: string;
    messages?: SDKMessage[];
  };
  usage?: {
    inputTokens?: number;
    outputTokens?: number;
    totalTokens?: number;
    costUsd?: number;
  };
  artifacts?: ArtifactSummary[];
  error?: SDKError;
};

结果应保持简单稳定。时间戳值保留 Gateway 形状,因此当前生命周期支持的回通常报告毫秒级数字,而适配器可能仍返回 ISO 字符串。丰富的 UI、工具追踪和运行时原生细节应放在事件和产物中。

accepted 是非终态的等待结果:表示 Gateway 等待截止时间已过,而运行还未产生生命周期结束/错误。不能将其视为 timed_outtimed_out 仅用于运行本身超时。

审批和提问

审批必须是第一等公民,因为编码智能体经常跨越安全边界。

typescript
run.onApproval(async (request) => {
  if (request.kind === "tool" && request.toolName === "exec") {
    return request.approveOnce({ reason: "CI command allowed by policy" });
  }

  return request.askUser();
});

审批事件应携带:

  • 审批 ID
  • 运行 ID 和会话 ID
  • 请求类型
  • 请求操作摘要
  • 工具名称或环境操作
  • 风险等级
  • 可用决策
  • 过期时间
  • 决策是否可重用

提问与审批是分开的。提问要求用户或宿主应用提供信息;审批要求允许执行某个操作。

ToolSpace 模型

应用需要理解工具表面,而无需导入插件内部。

typescript
const tools = await run.toolSpace();

for (const tool of tools.list()) {
  console.log(tool.name, tool.source, tool.requiresApproval);
}

SDK 应公开:

  • 标准化的工具元数据
  • 来源:OpenClaw、MCP、plugin、channel、runtime 或 app
  • schema 摘要
  • 审批策略
  • 运行时兼容性
  • 工具是否隐藏、只读、可写或宿主可用

通过 SDK 调用工具应显式且有范围。大多数应用应运行智能体,而不是直接调用任意工具。

产物模型

产物应覆盖文件之外的范围。

typescript
type ArtifactSummary = {
  id: string;
  runId?: string;
  sessionId?: string;
  type:
    | "file"
    | "patch"
    | "diff"
    | "log"
    | "media"
    | "screenshot"
    | "trajectory"
    | "pull_request"
    | "workspace";
  title?: string;
  mimeType?: string;
  sizeBytes?: number;
  createdAt: string;
  expiresAt?: string;
};

常见示例:

  • 文件编辑和生成文件
  • 补丁包
  • VCS 差异
  • 截图和媒体输出
  • 日志和追踪包
  • 拉取请求链接
  • 运行时轨迹
  • 托管环境工作区快照

产物访问应支持编辑、保留和下载 URL,不假定每个产物都是普通本地文件。

安全模型

App SDK 必须显式声明权限。

推荐的 Token 作用域:

作用域允许的操作
agent.read列出和检查智能体。
agent.run启动运行。
session.read读取会话元数据和消息。
session.write创建、发送、分支、压缩和中止会话。
task.read读取后台任务状态。
task.write取消或修改任务通知策略。
approval.respond批准或拒绝请求。
tools.invoke直接调用暴露的工具。
artifacts.read列出和下载产物。
environment.write创建或销毁托管环境。
admin管理操作。

默认行为:

  • 默认不转发秘密
  • 默认不无限制传递环境变量
  • 使用秘密引用而非秘密值
  • 显式沙箱和网络策略
  • 显式远程环境保留
  • 除非策略证明相反,否则宿主执行需要审批
  • 原始运行时事件在离开 Gateway 前被编辑,除非调用者具有更强的诊断范围

托管环境提供者

托管智能体应实现为环境提供者。

typescript
type EnvironmentProvider = {
  id: string;
  capabilities: {
    checkout?: boolean;
    sandbox?: boolean;
    networkPolicy?: boolean;
    secrets?: boolean;
    artifacts?: boolean;
    logs?: boolean;
    pullRequests?: boolean;
    longRunning?: boolean;
  };
};

第一个实现不需要是托管的 SaaS。它可以针对已有的节点主机、临时工作区、CI 风格的运行器或 Testbox 风格环境。关键是契约:

  1. 准备工作区
  2. 绑定安全环境和秘密
  3. 启动运行
  4. 流式事件
  5. 收集产物
  6. 按策略清理或保留

一旦此契约稳定,托管的云服务可以实现相同提供者契约。

包结构

推荐的包:

用途
@openclaw/sdk公开的高级 SDK 和生成的低级 Gateway 客户端。
@openclaw/sdk-react可选的 React hooks,用于仪表盘和应用构建器。
@openclaw/sdk-testing测试助手和虚假 Gateway 服务器,用于应用集成测试。

仓库中已有 openclaw/plugin-sdk/* 用于插件。保持该命名空间独立,避免混淆插件作者和应用开发者。

生成客户端策略

低级客户端应从版本化 Gateway 协议 schema 生成,然后由手写的易用类包装。

分层:

  1. Gateway schema 真相源。
  2. 生成的低级 TypeScript 客户端。
  3. 外部输入和事件载荷的运行时验证器。
  4. 高级 OpenClawAgentSessionRunTaskArtifact 包装器。
  5. 示例代码和集成测试。

好处:

  • 协议漂移可见
  • 测试可以比较生成方法和 Gateway 导出
  • App SDK 保持独立于 Plugin SDK 内部
  • 低级消费者仍有完整协议访问
  • 高级消费者获得精简的产品 API

常见问题

OpenClaw SDK 和 Plugin SDK 有什么区别?

@openclaw/sdk 是面向外部应用的客户端包,用于与 Gateway 通信;openclaw/plugin-sdk/* 是进程内插件创作契约。应用开发者只应使用 App SDK,不要导入 Plugin SDK 的子路径。

审批事件怎么在 SDK 中处理?

通过 run.onApproval() 注册回调,根据 request.kindrequest.toolName 决定批准、驳回或转交用户。审批事件会携带风险等级、过期时间和可用决策,支持 approveOnceaskUser。提问与审批分离,提问用于获取信息,审批用于获取许可。

Token 作用域的核心限制有哪些?

默认不转发秘密、不无限制传递环境变量,使用秘密引用而非值。关键限制:approval.respond 作用域才能响应审批,environment.write 用于创建/销毁环境,admin 用于管理操作。原始运行时事件在离开 Gateway 前会被编辑,除非调用者具有更强的诊断范围。

相关文档