description: "面向插件、UI 与编排器的 Agent 句柄、实时注册表、进程本地发起方作用域,以及 agent/* 事件词汇。"
English | 中文
使用 dsh-agent 创建或恢复实时 agent(智能体)、发送后续或 steering(中途引导)输入、注入面向模型的上下文、取消工作,并等待 agent 进入空闲状态。插件、UI、钩子与编排器还可以观察或拦截 agent 活动,并仅为一个 agent 应用能力而不影响其他 agent。当代码需要通过公开 Agent API 控制或扩展实时 agent 时,请选择本包。请将它与 dsh-agent-loop 等 agent 驱动器配合使用;本包本身不会创建模型请求。发起方归因仅存在于进程内,跨 worker、进程、持久队列与重启时必须显式传递。
在存在实时 agent 的任何地方挂载 dsh-agent:它提供 ctx.agents 以及插件、UI、钩子和编排器所面向编程的 Agent 句柄。在没有驱动器注册工厂之前,该服务保持惰性——随附驱动器是 dsh-agent-loop,因此最小的可用组合需要同时加载两者。
ctx.agents.create() 在一个身份下构建全新 agent 与会话;ctx.agents.resume() 加载持久化会话并在此基础上重建 agent。两者都委托给已注册工厂,并返回 AgentHandle——唯一能拆除该 agent 的对象。在任一操作的 options 中设置 parentAgent,可使结果成为运行时子级;省略它则得到运行时根级。get(id)、list() 与 roots() 用于查找实时 agent;isOwnedBy(id, parent) 用于检验这项确切的实时所有权关系。
const handle = await ctx.agents.create({
sessionId,
agentOptions: { provider: 'deepseek', model: 'deepseek-chat' },
})
// later:
await handle.dispose() // stops the loop, unregisters, removes the session, unwinds the scope
AgentOptions 提供初始提供方/模型路由、可选的由适配器定义的 reasoningEffort,以及可选的正数 maxTokens 输出上限。循环会校验确切模型的推理(reasoning)支持、解析适配器默认值、把生效值记录在请求头中,并将它们应用到每个对话请求。可选的 setup(agentCtx, agent) 回调会在 agent 发布之前组合其作用域世界:agentCtx 拥有注册,显式的未发布 Agent 则提供其 Session;Context 不含反向 Agent 属性。作用域工具、提示词段与监听器在任何创建公告之前就已存在。Setup 只做组合:创建完成后才能驱动 agent。
句柄的方法把带标识的 user 角色消息路由进 agent 的收件箱。followup() 排队一条普通的下一个轮次提示词并唤醒驱动器;steer() 提交下一步输入并唤醒它;inject() 添加面向模型的上下文但不唤醒驱动器,因此它落在下一个被接纳的步骤中。cancel(cause) 中止当前活动,并在未设置 keepInbox 时清除待处理工作;whenIdle() 会在整个 agent 达到完全停稳后完成。
handle.agent.followup({
content: [{ type: 'text', text: 'Summarize this workspace.' }],
source: { kind: 'user' },
})
handle.agent.steer({
content: [{ type: 'text', text: 'Focus on the tests.' }],
source: { kind: 'plugin', plugin: 'my-plugin' },
})
await handle.agent.whenIdle()
Agent.ctx 是该 agent 的作用域上下文:通过它进行的注册(工具、提示词段、变量、事件监听器、限制)只对该 agent 生效,并在 dispose(资源释放)时全部撤销。同一机制也是 agent preset 用来让一个会话获得不同能力集、同时不影响其邻居的方式。
agent/* 事件让插件无需依赖循环包即可作用于实时工作。agent/pre-step 可以拒绝拟进入的步骤或替换进入它的消息;agent/request-error 让监听器重试失败的模型请求;agent/turn-stopping 在本可完成的轮次关闭前运行,并可通过 steer 使其保持打开。agent/assistant-stream 携带一个进程本地 Assistant attempt 的有序 start、瞬态分片与 end frame。start 给出该 attempt 的轮次与步骤,分片索引从零开始密集递增,end.index 则是下一个分片位置。loop 会在 committed end frame 前把完整紧凑流提交为一个 assistant/message 或 assistant/attempt,因此实时事件仍是呈现数据而非回放来源。agent/status、agent/created 与 agent/disposed 驱动 UI 与协调状态,逐消息的 agent/inbox/* 通知则让收件箱投影保持同步。确切签名、分发 mode 与 payload 约定见 core 子系统页 的生成区块。
包级约定对大多数消费方已经足够;需要周边领域与设计原理时再阅读以下页面。
Agent 句柄、拦截决策与生成的服务 API。followup、steer 与 inject 以带标识的 user 角色消息馈送所属会话;被接纳的内容成为模型在后续步骤中读取的派生历史的一部分。agent/pre-step 与其他已声明事件让插件能够拒绝拟进入的步骤或添加持久请求材料。installModelSelection 会在首次为不同提供方/模型路由组装且原本会发出模型请求的步骤中加入 [model changed: assistant turns above this point were generated by <previous>; the session continues with <next>];仅跨提供方切换时显示提供方名称,只改变推理强度时不添加消息。第一个决策为空时,以及某个决策移除候选消息后为空时,都不会产生请求。如果请求步骤在记录请求头前失败,持久记录中的先前路由没有变化,所以下一个请求步骤会再次收到提示。
被接纳内容成为保留历史,或成为每次请求重复的会话前缀;被阻止内容不贡献请求 token。每条实际发出的模型切换提示都会把对应文本加入保留历史。大小取决于调用方与插件。
被接纳历史与 steering 只追加;被阻止的提交不发送请求。会话前缀在循环实例内保持稳定,而新建或恢复的实例可能建立不同前缀。
通过 agent.ctx 进行的注册可以遮蔽提示词段或工具,也可以在未发布 setup 期间安装仅适用于该 agent 的拦截器,因此一个 agent 看到的提示词与工具集会与其邻居不同。模型选择会在提示词组装前捕获一次提供方/模型/推理强度值,并将其应用到同一步骤的请求;之后发生的并发变更等待下一个步骤。
每次提供方/模型切换会增加一条简短且保留在历史中的 user 角色提示。其他带作用域贡献只影响该 agent,并在 dispose 时消失。
切换提示追加在先前历史之后,因此保留该前缀;路由变更可能使新的提供方或模型无法复用此前缀。改变提示词段、工具定义或请求监听器的 setup 或 reload,可能从第一个受影响的请求 token 起使复用失效。
这些限制说明本包何时需要特别留意。它们是当前包约束,不是任务积压。
agent.status、取消状态和所属能力约定。agent/session-start 不能为启动设置门禁:它仍是同步且不可 veto 的通知;必须在发布前完成的异步组合属于工厂的 setup(agentCtx, agent) 事务。cancel() 默认清空收件箱:它会中止正在处理的轮次以及排队和 steering 工作;cancel(cause, { keepInbox: true }) 只中止轮次并保留待处理项,且不存在让轮次继续运行、只中止步骤的操作。UserMessage 恰好携带一个 MessageSource:多个插件合并到一条消息上的贡献会归入同一来源,因此该消息无法列出多个生产者。