跳转至

入口点

每个插件都会导出一个默认入口对象。SDK 为每种入口形态提供了对应的辅助函数:defineToolPlugin、definePluginEntry、defineChannelPluginEntry、defineSetupPluginEntry。

所有插件 API(包括这些入口辅助函数)均为实验性功能。请锁定并测试你的插件所支持的 OpenClaw 宿主版本。

Tip

需要分步指南? 请参阅工具插件、渠道插件或提供商插件获取逐步指南。

各部分的去向

单页版本中的每个部分现在都位于此页面或下方的八个子页面之一。来自单页版本的锚点在此处仍然有效。

插件形态

OpenClaw 根据已加载插件的注册行为对其进行分类:

形态 描述
plain-capability 单一能力类型(例如仅 provider)
hybrid-capability 多种能力类型(例如 provider + 语音)
hook-only 仅包含钩子,无能力
non-capability 包含工具/命令/服务,但无任何能力

使用 openclaw plugins inspect <id> 查看插件的形态。

Code Mode 执行器运行时

使用 openclaw/plugin-sdk/code-mode-executor-runtime 来实现 quickjs 执行器选项。Code Mode 有两个可选 ID:由核心拥有的 node,以及由执行器插件提供的 quickjs。插件的安装 ID 可以与其执行器 ID 不同。在 contracts.codeModeExecutors 中声明 quickjs,并从插件顶层的 code-mode-executor-api 构件中导出 codeModeExecutor。宿主仅在选择了 QuickJS 时才解析此构件;普通插件注册依然保持轻量。

即使全局禁用插件或设置了限制性允许列表,被选中的捆绑执行器仍能保持核心运行时可用。显式的所有者拒绝和已禁用条目仍然生效。外部执行器仍受完整插件策略的约束。

CodeModeExecutor.execute(input, options) 接收访客源代码、工具声明、命名空间描述符、资源限制以及作用域受限的宿主桥接器。返回一个有界的完成或失败结果,或一个包含执行器所有的 CodeModeExecutorContinuation 的等待结果。其 resume 方法仅转移一次保管权,retainedBytes 报告诊断用大小估算值,dispose 参与清理并保持失败的清理可重试。处理已消费的 continuation 不会产生任何效果。所选执行器在配置变更期间仍保持与该 continuation 的关联。

SDK 提供通用的访客控制器、源代码准备、结果捕获、有界错误文本和 Worker 协议类型。执行器拥有自己的引擎和挂起状态。核心拥有权限、审批、工具分发、结算收据、输出交付、过期和取消。缺失或被禁用的执行器会显式失败;宿主绝不会替换为隔离性较弱的执行器。

MCP 子进程运行时

导入: 打开连接时,使用动态 import() 从 openclaw/plugin-sdk/agent-harness-runtime 导入 mcpStdioRuntime。其冻结对象会延迟加载一个工厂:

const { mcpStdioRuntime } = await import("openclaw/plugin-sdk/agent-harness-runtime");
const { createMcpStdioClient } = await mcpStdioRuntime.load();

使用 createMcpStdioClient(params) 创建调用方所有的 MCP 代理子进程,作为状态化驱动程序的前端。OpenClaw 拥有该子进程及其后代进程、换行符分帧和 JSON-RPC 验证、初始化、请求准入、截止时间和关闭。工厂返回后,客户端即开始连接。请勿在插件注册以及不打开 MCP 连接的路径中使用此运行时。

提供 command、可选的 args 以及精确的 env。子进程不继承任何其他环境变量。设置 clientInfo(name 和 version)、必需的 protocolVersion、startupTimeoutMs、maxPendingRequests 和 maxFrameBytes。服务器必须返回与所请求完全一致的协议版本。OpenClaw 会保留固定的 32 KiB stderr 尾部,用于意外退出诊断。解码器对每条消息(包括其终止换行符)应用 maxFrameBytes,因此单个 stdout 块中可以包含多条有效消息。解码器会在保留该块中的任何字节之前拒绝超大帧,保留分片 UTF-8,跳过空行,并要求响应 ID 为安全整数。

The caller supplies errors.unavailable(message, cause?) and errors.protocol(message, cause?), each returning an Error. The first classifies process, lifecycle, admission, deadline, and cancellation failures. The second classifies malformed frames, non-timeout JSON-RPC errors, and handshake contract violations. Plugin-specific tool-result normalization stays with the caller.

The returned client exposes three methods:

  • isAvailable() synchronously reports whether initialization completed and the connection remains usable.
  • request(method, params, { timeoutMs, signal? }) waits for startup and returns the object result. An already-aborted signal or a full pending-request limit rejects only that call. After admission, cancellation or timeout retires the entire connection and rejects pending requests with the retained fatal error. The client suppresses SDK cancellation notifications because it terminates the process instead. A non-timeout JSON-RPC error response rejects only its matching request through errors.protocol.
  • stop() closes admission, retires pending requests, and awaits startup settlement and owned-process cleanup. It rejects through errors.unavailable with proxy cleanup could not be confirmed if cleanup is uncertain. It never stops a separately started service reached through the proxy's socket.

After successful stop(), the optional read-only cleanupResult records forced relay retirement: reason: "forced-relay-exit", signalRequested, the observed relay exit code and signal, durationMs, and escalationAfterMs. It retains signalError when signal delivery reported failure but exit was subsequently confirmed. It is absent for ordinary cleanup. Closed control/output/lineage pipes and a matching closing receipt admit escalation; pending force requests are reconsidered as closure and group-exit facts arrive. A live anchor is killed and reaped through its relay. Confirmed anchor-group absence permits direct native termination of an unresponsive relay. Actual relay exit and server-group disappearance must then be confirmed within the original hard deadline. Uncertain cleanup retains missing closure facts and timing or signal-delivery details in the error's cause chain.

Malformed frames, incompatible initialization, write failures, and unexpected process exit also retire the whole connection. The first fatal error is retained. Create a new client to reconnect. Timeout classification follows the SDK error code, so a timeout-coded server error also retires the connection.

工作区访问

使用 openclaw/plugin-sdk/agent-workspace-runtime 声明、注册并获取 AgentWorkspaceAccess,而无需加载代理执行运行时。在注册期间声明已配置的远程工作区,以便调用方在其服务启动前无法回退到本地文件。就绪时注册其桥接,服务停止时释放它。调用方保留其现有的文档授权。

桥接的可选 createFileExclusive 操作仅在其路径不存在时发布完整文件,并返回 "created" 或 "exists"。它必须使用原子独占创建操作,绝不能先进行单独的存在性检查,然后执行普通写入。工作区访问会转发此能力,并应用与其他桥接操作相同的服务生命周期检查。省略它的提供者仍支持其现有读取和写入,但带有 expectedMissing: true 的 agents.files.set 会明确拒绝创建而不更改文件。请更新提供者,或在其主机上创建该文件并在编辑前重新加载它。

createWorkspaceBootstrapFilePolicy({ workspaceDir, config }) 允许适配器将此桥接限制为原生引导文档以及已配置的 bootstrap-extra-files 模式。使用 canList 检查目录元数据,使用 canRead 检查文件字节,使用 canWrite 检查四个所有者可编辑文档。目录访问不会授予读取其他文件的权限。底层桥接仍会强制文件系统包含,并返回读取的规范来源。

未启动或已停止的工作区访问会抛出 WorkspaceAccessUnavailableError。使用 isWorkspaceAccessUnavailableError(error) 通过包装错误或多个 SDK 实例识别此条件。错误代码为 WORKSPACE_ACCESS_UNAVAILABLE;不要匹配消息文本。

可选的 memoryFiles 提供者将工作区 Memory 文件保留在主机上,同时原生索引、嵌入提供者和原始会话保留在 Gateway 上。它提供发现、文件检查、读取和变更通知。索引和 memory_get 都使用它;索引发布会重新检查主机文件。随读取返回的规范来源提供溯源信息,而不会解析过期的 Gateway 副本。停止工作区绑定会撤销保留的文件访问和订阅。Memory 文件 worker 支持 --files <workspace>,用于原生文件操作,而无需打开主机索引或接收嵌入凭据。提供者可以通过其现有子进程传输调用它。createWorkspaceMemoryFileClient 为这个 worker 映射 Gateway/主机路径并保留原生错误。提供 request 用于一次 JSON 交换,提供 subscribe 用于 --watch-files JSON 行流,以及绑定的中止信号。这两个回调都不依赖 Codex;提供者拥有传输和授权。

memoryFiles.maintenance 将现有的 dreaming、promotion、corpus 和 forget 文件操作路由到主机。复合写入复用原生原子发布和冲突处理;维护决策、锁和 SQLite 状态保留在 Gateway 上。不支持维护的远程绑定会失败,而不是使用 Gateway 文件。文件 worker 实现这些操作和原生变更通知。配对节点文件传输适配器通过现有服务拥有的节点通道和节点文件策略连接这些操作。

任务时 Skill 准备使用远程发现。通道原生菜单使用 Gateway 拥有的 Skills,而无需等待 Harness;远程菜单支持在 Enterprise #241 中跟踪。

The optional skillResources provider 将 Skill 读取与 Agent 文档访问分开处理。其 readInstructions 为 Code Mode 读取选定的指令文件;readSkillFiles 为 worker 交付提供 bundle。Gateway 拥有的 bundled、plugin、Library、Workshop 和用户级源保留其 Gateway 路径。工作区拥有的源使用远程 provider。Gateway 保留源优先级,并为 worker 使用现有资源交付。发现机制分配文件所有权;provider 不能通过返回源标签或 fileHost 值来请求 Gateway 本地读取。停止绑定会撤销保留的 host 读取器。

Skills worker 还运行安装和 ClawHub 操作。安装/移除使用已认证适配器的双工通道,以便在原生文件系统操作之前运行 Gateway 策略和变更检查。适配器允许源根目录和上传;worker 使用其 host 账户的权限。

对于远程工作区,依赖安装使用 installSkillDependencies。Gateway 选择配方并运行安装策略;host 通过 worker 的 installDependencies 操作运行现有安装器。请求包含 Skill 键、配方、安装偏好和超时。配方选择使用 host 的操作系统和二进制文件。缺少 host 支持时失败,而不在 Gateway 上安装。检查文件的 Gateway 策略从现有 Skill 资源读取器接收临时树;Gateway 拥有的源保持本地。资源包限制适用。

readWorkspaceSkillResources 惰性复用有界的原生 bundle 读取器。文件传输适配器可以在返回 bundle 之前检查每个文件请求的规范路径和已验证的规范路径;仅允许 Skill 目录本身并不会允许其所有子项。

Host 可以提供 watchSkills(request, onChange, signal),在已允许的 Skill 源发生变化时通知现有快照缓存。保持订阅存活直到中止,并在初始扫描以及后续编辑后发送 change。如果文件监视停止,则发送 unavailable:随后准备阶段会在每次调用时刷新,而不会重新打开订阅。恢复后,仅当所有已订阅源都具有经过验证的监视覆盖,并且中断期间发生的编辑已协调一致时,才发送 available。这会恢复快照复用,而不会增加内容修订。仅发送 change 永远不会清除不可用状态。仅发送 change 和 unavailable 的 host 在中断后仍保留准备回退。没有 watchSkills 的 host 始终使用该回退。skills.load.watch: false 禁用该订阅和此回退。Gateway 在相同的快照失效生命周期下本地监视 Workshop。

配对节点文件传输适配器还通过 workspace.skills 连接 Skill 发现、资源读取、监视和依赖安装。其原生 worker 启动器使用来自 agent-workspace-runtime 的 resolveWorkspaceWorkerArgv("memory" | "skills"),然后追加操作参数。在 Gateway 和 node 上使用相同的 OpenClaw 版本。

此适配器未实现远程 Skill 源安装/更新/移除或 ClawHub 生命周期操作;这些操作仍跟踪在 Enterprise #242。

Agent 工作区上下文

原生 harness 使用来自 openclaw/plugin-sdk/agent-harness-runtime 的 prepareAgentWorkspaceContext 来准备有界工作区上下文。共享所有者运行现有 bootstrap 钩子、隐私过滤器和字符预算。scope: "full" 分离 agent 指令快照、persona、剩余项目上下文和工具路由的 memory 引用。它通过活动 memory 插件准备召回指导,而不发明回退策略。scope: "instructions-only" 在预算之前选择已配置工作区的根 AGENTS.md,并且不准备 persona 或 memory 指导。

Provider 适配器拥有原生项目文档发现、可用 memory 工具、路径投影、上下文顺序、指令载体以及会话/轮次生命周期。可选 projectPath 在预算之后投影文件路径,而不改变其内容或个人用户来源。它描述现有执行放置;它不传输或挂载文件。完整上下文准备保留 Codex 的现有选择时序:将根指令路径从 workspaceDir 投影出去会产生空的根快照。准备源工作区指令的调用方应省略 projectPath。

buildAgentWorkspaceInstructionSnapshot(contextFiles, workspaceDir) 从已有界的上下文中选择并渲染该根指令文档,包括无钩子的子项准备。空指令字符串是成功捕获;准备失败必须保持可区分且可重试。

Agents API 可以在会话创建时消费仅指令快照。其当前客户端未实现每轮开发者指令、persona 和个人覆盖刷新、轮次范围的项目或 memory 指导、原生 fork,或 Gateway 到托管工作区的路径投影。这些仍是 MVP 集成缺口;共享准备不会启用这些操作。

工具失败诊断

Agent harness 可以从 openclaw/plugin-sdk/agent-harness-runtime 导入 readToolOperatorHint(error),以读取附加到工具失败的可选操作员建议。仅将其包含在操作员日志中。将其排除在模型响应、工具结果回调和序列化转录之外,并保留原始错误消息。未标注或不可变的错误不需要替代提示;当没有可用建议时,读取器返回 undefined。

ACP harness 轮次

将可选 currentInboundContext 传递给来自 openclaw/plugin-sdk/agent-harness-runtime 的 resolveAgentHarnessBeforePromptBuildResult。它在 prompt 钩子运行之前将 prompt 与其入站上下文以及通道提供的 joiner 组合。用散文部分标签框定普通聊天,使开头的文件路径不能成为原生斜杠命令。保持一个已允许的用户轮次,同时为每个 provider 尝试分配其自己的请求和回复标识。

Host requestApproval 会在共享显示边界内规范化标题和描述,并在 detail 中保留完整的操作证据。其响应会通过一个 ID 确认该请求。使用 waitForApproval 并传入该 ID 以获取决定,然后在允许执行原生操作之前,重新检查该轮次的信号和权限。

将插件审批超时与代理运行超时独立使用。经过身份验证的 Control UI 审阅者可以检查 detail,而频道消息保留受限描述。过大的 detail 会被现有请求模式拒绝。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw