后台工作
在后台启动代理工作:用于外部内容的钩子分派轮次以及子代理运行。属于 插件运行时辅助 参考的一部分。
后台工作命名空间¶
api.runtime.hooks
为不受信任的外部内容触发器分派隔离的代理轮次,例如邮件监视器。与 api.runtime.subagent.run(...) 不同,钩子分派会包装外部内容,对同一会话的运行进行串行化,并通过 Gateway 报告完成状态。插件轮次共享 cron 执行预算,而无需使用 HTTP 钩子端点。当启用 HTTP 钩子时,该共享预算中仍有一个槽位保留给 HTTP 工作。
const result = await api.runtime.hooks.dispatchHookAgentTurn({
name: "IMAP inbox",
agentId: "mail",
sessionKey: "hook:imap:account:123:456",
message: "Summarize the new email and identify any requested actions.",
externalContentSource: "email",
deliver: true,
thinking: "low", // optional
timeoutSeconds: 60, // optional
idempotencyKey: "account:123:456", // optional
});
if (!result.ok) {
api.logger.warn(`Hook agent turn was rejected: ${result.reason}`);
}
agentId 是必填项,sessionKey 必须以 hook: 开头,且不能包含空白字符或控制字符。externalContentSource 目前仅接受 "email";无法禁用外部内容包装。将 deliver 设置为 false 可记录完成状态而不进行通告。成功接纳返回 { ok: true, runId };被拒绝的接纳返回 { ok: false, reason }。
此功能仅对捆绑插件和受信任的官方插件安装可用。它不需要启用或配置 HTTP 钩子端点。
api.runtime.subagent
启动并管理后台子代理运行。
对于无需保留会话或回复投递的无工具完成,请使用 `complete(...)`:
```typescript
const { text } = await api.runtime.subagent.complete({
agentId: "research", // required configured agent that owns this work
message: "Summarize these notes.",
extraSystemPrompt: "Return a concise summary.", // optional
timeoutMs: 30_000, // optional; defaults to 30 seconds
// model: "openai/gpt-5.6-luna", // optional authorized override
// signal: abortController.signal, // optional cancellation
});
```
`agentId` 和 `message` 是必填项。`extraSystemPrompt`、`model`、`timeoutMs` 和 `signal` 是可选的。当省略 `model` 时,所选代理提供其配置的默认模型和凭据所有者。结果是 `{ text: string }`;无需创建会话、轮询消息、删除或投递完成。配置的运行时必须支持全新的、无工具的隔离推理;不支持的运行时会在推理前失败。
完成使用 [共享后台队列](../../concepts/queue.md#background-work),在三次运行的总预算内,每个插件最多三次运行。取消会立即移除排队中的工作。正在运行的工作会保留其槽位,直到底层运行时清理完成,然后拒绝;在取消、超时或运行时退役之后,迟到的输出不会返回。调用需要活动的 Gateway 绑定和插件身份。请求范围内的调用保留调用者的操作员范围和代理访问权限;在操作员工具调用内启动的完成会在该调用结束时取消。模型覆盖保留
现有的子代理授权和下文中的 `allowedModels` 策略。
当你需要会话或代理工具界面时,请使用 `run(...)`:
```typescript
// Start a subagent run
const { runId, sessionKey } = await api.runtime.subagent.run({
sessionKey: "agent:main:subagent:search-helper",
message: "Expand this query into focused follow-up searches.",
toolsAlsoAllow: ["my_plugin_progress"],
promptMode: "minimal", // optional bounded subagent prompt
provider: "openai", // optional override
model: "gpt-6-astra", // optional override
deliver: false,
completionDelivery: "current-requester", // optional, before_dispatch hooks only
});
// Wait for completion
const result = await api.runtime.subagent.waitForRun({ runId, timeoutMs: 30000 });
// Read session messages
const { messages } = await api.runtime.subagent.getSessionMessages({
sessionKey: "agent:main:subagent:search-helper",
limit: 10,
});
// Delete a session
await api.runtime.subagent.deleteSession({
sessionKey: "agent:main:subagent:search-helper",
});
```
由 Gateway 支持的运行会返回规范接受的 `sessionKey` 以及 `runId`。该字段在 TypeScript 结果中仅为可选,以便显式自定义运行时保持兼容。
`waitForRun(...)` 返回规范的 Gateway 等待结果。`status` 为 `"ok"`、`"error"`、`"timeout"` 或 `"pending"`;pending 是正常的非终态观察,而不是异常。可选的 `error`、`startedAt`、`endedAt`、`stopReason`、`livenessState`、`yielded`、`pendingError`、`timeoutPhase`、`providerStarted` 和 `terminalReply` 元数据会被保留,以便调用者区分观察超时和终态结果。`timeoutMs` 限定等待调用;它不会取消运行。
Warning
在授权 Gateway 请求之外,模型覆盖需要通过配置中的 plugins.entries.<id>.subagent.allowModelOverride: true 获得操作员选择加入。未选择加入的插件可以使用配置的模型,但覆盖请求会被拒绝。
plugins.entries.<id>.subagent.allowedModels 可以将覆盖限制为规范的 provider/model 目标。相同策略适用于 complete;请求范围内的调用保留其已认证客户端的覆盖权限。该检查使用目标代理的模型配置,包括精确配置的模型 ID,并适用于插件的初始覆盖。配置的默认值、操作员安装的模型路由钩子以及自动模型回退保留其自身的选择策略。
toolsAlsoAllow 会将调用插件注册的、精确且唯一拥有的工具添加到 worker 的常规工具面。运行时拒绝核心工具以及与其他插件共享的名称。配置文件和 operator 工具策略仍然适用,包括显式允许列表和拒绝列表。
所有者授权的命令启动可以将其捕获的断言作为 subagent.run({ ..., assertCurrent }) 传递;Gateway 会在运行准入时应用它。受管理的 worktrees.create({ ..., commitGuard }) 通过其现有创建所有者接受相同的断言。撤销会阻止待处理的启动或 worktree 写入,而已接受的工作仍保留其清理和完成职责。
promptMode: "minimal" 会选择受限的 subagent prompt,而不是完整的对话 prompt。插件运行时仅暴露此模式;省略时会保留完整 prompt。当运行必须具有精确的空工具面时,也请使用 disableTools: true。
completionDelivery: "current-requester" 默认关闭,并且仅在 before_dispatch 钩子正在处理经过身份验证的入站请求时可用。OpenClaw 在调用插件之前捕获规范的请求者会话和投递路由,然后通过常规 announce 路径投递 subagent 完成。插件不能提供或覆盖请求者来源链或目标字段。在该请求者绑定的钩子上下文之外的调用会被拒绝。
deleteSession(...) 可以删除同一插件通过 api.runtime.subagent.run(...) 创建的会话。删除任意用户或 operator 会话仍需要具有管理员范围的 Gateway 请求。
原生 harness 完成投递¶
内置 harness 使用 openclaw/plugin-sdk/agent-harness-completion 通过现有的请求者完成投递所有者路由原生子结果。deliverAgentHarnessCompletion 需要主机签发的 AgentHarnessCompletionScope 和一个有效的 isSourceSessionAdmissionAllowed 回调。保持该回调绑定到精确的原生分配及其当前父级。请求者身份和准入会在等待路由之后、产生新副作用之前重新检查。原生运行时历史、取消和提交回执仍由 harness 拥有;没有通用任务注册表或受管理流程 API。
对于分离的原生工作,请在准入父级注册期间、发布注册或启动原生子工作之前,等待 captureAgentHarnessCompletionCustody(scope)。准备阶段会保留原始请求者生命周期,并在返回保管权之前拒绝替换或撤销。每个已接受的子分配都会通过 retain() 保留其自身的持有,并在投递其结果时将其作为 completionCustody 传递。当其注册或分配结束时,释放每个持有。该持有会保留原始 operator 上限和请求者生命周期;它不会授予通用工具访问权限,也不会在撤销或 Gateway 关闭后继续有效。
将 createAgentHarnessCompletionEventSink(...) 绑定到相同的完成保管权,以及用于精确原生分配的 isSourceCurrent 回调。在原生终端持久化和首次完成交接稳定后,请在休眠投递重试之前调用 completionCustody.settleExecution()。这会释放执行排空义务,同时保留完成投递权限。重启后,恢复必须从有效注册中捕获新的保管权并验证其请求者;存储的历史记录从不授予权限。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/openclaw