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 资源:

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

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

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 应公开版本化、可重放、标准化的事件。

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() 应返回稳定的结果信封:

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 仅用于运行本身超时。

审批和提问

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

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 模型

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

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 调用工具应显式且有范围。大多数应用应运行智能体,而不是直接调用任意工具。

产物模型

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

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 前被编辑,除非调用者具有更强的诊断范围

托管环境提供者

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

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 前会被编辑,除非调用者具有更强的诊断范围。

相关文档