把 subagent/manager 的协议无关观察钩子翻译成 lane 事件。
分层在这里合拢:clj-agent-client 那侧只知道「有四个可选钩子」
(manager 的 ns docstring),AG-UI 的知识一个字都没有;本 ns 负责给每次
spawn 现造一条 lane 的发射器,并把四个钩子接上去。
用法(用户在自己的 agent-fn 里):
(rt/runtime
{:subagent-events? true
:agent-fn (fn [{:keys [conversation-id tools subagent-observer]}]
(agent/create-agent
{:provider p
:tools (conj (vec tools)
(delegate/delegate-tool
{:name "deep_research"
:subagent-fn (fn [_ _] {:provider p})
:observer subagent-observer}))}))})
:subagent-observer 在开关关闭时是 nil,delegate-tool 于是走今天的老路径
——「不塞就什么都不会发生」是这条链路每一跳的性质(设计文档 §1.3)。
把 `subagent/manager` 的**协议无关观察钩子**翻译成 lane 事件。
分层在这里合拢:`clj-agent-client` 那侧只知道「有四个可选钩子」
(`manager` 的 ns docstring),AG-UI 的知识一个字都没有;本 ns 负责给每次
spawn 现造一条 lane 的发射器,并把四个钩子接上去。
用法(用户在自己的 `agent-fn` 里):
```clojure
(rt/runtime
{:subagent-events? true
:agent-fn (fn [{:keys [conversation-id tools subagent-observer]}]
(agent/create-agent
{:provider p
:tools (conj (vec tools)
(delegate/delegate-tool
{:name "deep_research"
:subagent-fn (fn [_ _] {:provider p})
:observer subagent-observer}))}))})
```
`:subagent-observer` 在开关关闭时是 **nil**,`delegate-tool` 于是走今天的老路径
——「不塞就什么都不会发生」是这条链路每一跳的性质(设计文档 §1.3)。(observer-factory parent)给一个发射器造观察者工厂——就是 runtime 交给 agent-fn 的那个 :subagent-observer。
每次 spawn 调一次(契约由 manager 保证),因此每条 lane 一个发射器实例:
10 路并发共用一个实例会共用 :current-message,token 于是交错进同一条消息
(设计文档 §3.3 契约 4)。
嵌套(子 agent 再委派)已接线:观察者多交出一个 :child-observer
——以本 lane 为父再造的同一个工厂。subagent/manager 在 worker 线程上把它钉进
子 agent 的 ToolContext(:subagent/observer),子 agent 里那把 delegate-tool
在 handler 期取用(工具声明里显式给的 :observer 优先)。于是孙子 lane 开在
这条 lane 底下,parentSubagentRunId 有值。
没有走 :subagent-fn 的签名变更:那条路走不通——subagent-fn 在 lane 还不
存在时就被调了(handler → subagent-fn → spec → spawn → observer-of → lane)。
ToolContext 这条路顺序才对:lane 先造,agent 后建。
给一个发射器造观察者工厂——就是 runtime 交给 `agent-fn` 的那个 `:subagent-observer`。 每次 spawn 调一次(契约由 manager 保证),因此**每条 lane 一个发射器实例**: 10 路并发共用一个实例会共用 `:current-message`,token 于是交错进同一条消息 (设计文档 §3.3 契约 4)。 **嵌套(子 agent 再委派)已接线**:观察者多交出一个 `:child-observer` ——以本 lane 为父再造的同一个工厂。`subagent/manager` 在 worker 线程上把它钉进 子 agent 的 ToolContext(`:subagent/observer`),子 agent 里那把 `delegate-tool` 在 handler 期取用(工具声明里显式给的 `:observer` 优先)。于是孙子 lane 开在 这条 lane 底下,`parentSubagentRunId` 有值。 **没有走 `:subagent-fn` 的签名变更**:那条路走不通——`subagent-fn` 在 lane 还不 存在时就被调了(handler → subagent-fn → spec → spawn → observer-of → lane)。 ToolContext 这条路顺序才对:lane 先造,agent 后建。
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |