Liking cljdoc? Tell your friends :D

im.ttalk.agent.tool-registry

工具注册表:装配期把工具声明汇成一张表,运行期一次查表答完

从 chat-client 拆出来的一块。判据是「这些函数认识什么」——它们全部只认识 工具声明(:serial / :retry / :timeout / :return-direct / schema), 一个都不认识 ChatModel、filter 链或消息。chat-client 因此瘦回它的本分: record + 装配 + 三个 invoke 原语。

对照 beamai 的 beamai_tool / beamai_tool_index——同样是把工具那一摊从 ChatClient 里分出去;Spring AI 对应的是 ToolCallback 注册表那一层。

装配期做掉,运行期只查表:build-tool-meta 在 build-chat-client 时把 var 工具与内联工具两个来源汇成 {keyword -> ToolMeta};此前四个查询函数 各自写一遍 (if-let [v (get tool-vars k)] (读 var 元数据) (查 inline-meta)) ——同一段双分支手抄四遍,:timeout 就是在那种重复里漏掉 inline 分支、对内联 工具静默失效的。

本 ns 的查询函数吃 ChatClient(只读 :tool-meta / :tool-vars / :tool-manager 三个键,不 require chat-client,故无循环依赖)。

工具注册表:装配期把工具声明汇成一张表,运行期一次查表答完

从 `chat-client` 拆出来的一块。判据是「这些函数认识什么」——它们全部只认识
**工具声明**(`:serial` / `:retry` / `:timeout` / `:return-direct` / schema),
一个都不认识 ChatModel、filter 链或消息。`chat-client` 因此瘦回它的本分:
record + 装配 + 三个 invoke 原语。

对照 beamai 的 `beamai_tool` / `beamai_tool_index`——同样是把工具那一摊从
ChatClient 里分出去;Spring AI 对应的是 `ToolCallback` 注册表那一层。

**装配期做掉,运行期只查表**:`build-tool-meta` 在 `build-chat-client` 时把
var 工具与内联工具两个来源汇成 `{keyword -> ToolMeta}`;此前四个查询函数
各自写一遍 `(if-let [v (get tool-vars k)] (读 var 元数据) (查 inline-meta))`
——同一段双分支手抄四遍,`:timeout` 就是在那种重复里漏掉 inline 分支、对内联
工具静默失效的。

本 ns 的查询函数**吃 ChatClient**(只读 `:tool-meta` / `:tool-vars` /
`:tool-manager` 三个键,不 require chat-client,故无循环依赖)。
raw docstring

build-registryclj

(build-registry var-tools var-map inline-tools schemas)

把 var 工具与内联工具两个来源汇成一个 ToolRegistry。

校验先于建表:normalize-retry 会把非法声明 merge 成看似合法的策略, 先归一化就等于把错误藏起来。名字唯一又先于其余校验——重名时 var-map / inline-handler-map 已经被 into 把重复悄悄吃掉了,再校验别的就是在错误的 地基上校验。

参数:

  • var-tools: tool var 列表
  • var-map: {keyword -> var}(调用方已建好,避免重复计算)
  • inline-tools: 内联工具 map 列表(含 :handler)
  • schemas: 已编译的 tool schema 列表(var + 内联)

返回: ToolRegistry

把 var 工具与内联工具两个来源汇成一个 `ToolRegistry`。

**校验先于建表**:`normalize-retry` 会把非法声明 merge 成看似合法的策略,
先归一化就等于把错误藏起来。名字唯一又先于其余校验——重名时 var-map /
inline-handler-map 已经被 `into` 把重复悄悄吃掉了,再校验别的就是在错误的
地基上校验。

参数:
- var-tools:    tool var 列表
- var-map:      {keyword -> var}(调用方已建好,避免重复计算)
- inline-tools: 内联工具 map 列表(含 :handler)
- schemas:      已编译的 tool schema 列表(var + 内联)

返回: `ToolRegistry`
sourceraw docstring

effective-timeout*clj

(effective-timeout* chat-client tmeta)

effective-tool-timeout 的表体,吃已查好的 ToolMeta——让 invoke-tool 能复用它已经查到的那一份,不必为超时再查一次表。

`effective-tool-timeout` 的表体,吃已查好的 `ToolMeta`——让 `invoke-tool`
能复用它已经查到的那一份,不必为超时再查一次表。
sourceraw docstring

effective-tool-timeoutclj

(effective-tool-timeout chat-client fn-name)

该工具实际生效的超时(毫秒),nil = 不超时。

缺省不超时——框架不替调用方决定何时放弃。要限时须显式给出,两个来源:

工具声明 deftool {:timeout ms} > 引擎缺省 (...-tool-calling-manager {:timeout ms}) > 不超时

工具声明最优先——它最清楚自己要跑多久(长任务的逃生舱就是「声明一个大的」); 引擎缺省次之,让部署方能整体封顶而不必逐个改工具。

引擎缺省的读取优先走 *active-manager-timeout*(当前正在执行的 manager 的值,R4),回落到 chat-client 的 :tool-manager 字段(直调 invoke-tool 不经 manager 时)。

由 invoke-tool 的 terminal 消费并强制:开箱即生效,不需要挂任何 filter。 超时只包裹工具本体(terminal 内),不包裹 filter 链——审批等待不再吃掉超时 预算(R1)。

该工具**实际生效**的超时(毫秒),nil = 不超时。

**缺省不超时**——框架不替调用方决定何时放弃。要限时须显式给出,两个来源:

  工具声明 `deftool {:timeout ms}`  >  引擎缺省 `(...-tool-calling-manager
  {:timeout ms})`  >  **不超时**

工具声明最优先——它最清楚自己要跑多久(长任务的逃生舱就是「声明一个大的」);
引擎缺省次之,让部署方能整体封顶而不必逐个改工具。

引擎缺省的读取优先走 `*active-manager-timeout*`(**当前正在执行的** manager
的值,R4),回落到 chat-client 的 `:tool-manager` 字段(直调 invoke-tool 不经
manager 时)。

由 `invoke-tool` 的 terminal 消费并强制:**开箱即生效,不需要挂任何 filter**。
超时只包裹工具本体(terminal 内),不包裹 filter 链——审批等待不再吃掉超时
预算(R1)。
sourceraw docstring

find-functionclj

(find-function x fn-name)

查找 var 工具(内联工具无 var,返回 nil)

参数:

  • x: ChatClient 或 ToolRegistry
  • fn-name: 函数名(关键字或字符串)

返回: {:tool-var var} 或 nil

查找 var 工具(内联工具无 var,返回 nil)

参数:
- x:       ChatClient 或 ToolRegistry
- fn-name: 函数名(关键字或字符串)

返回:
{:tool-var var} 或 nil
sourceraw docstring

list-functionsclj

(list-functions x)

列出所有注册的 var 工具名(吃 ChatClient 或 ToolRegistry)

返回: 关键字列表

列出所有注册的 var 工具名(吃 ChatClient 或 ToolRegistry)

返回:
关键字列表
sourceraw docstring

registry-ofclj

(registry-of x)

取出工具注册表:ToolRegistry 原样返回,ChatClient 取其 :tool-registry。

查询函数一律经它,于是「传 ChatClient」与「传裸注册表」两种调用都成立—— 注册表是个独立的值,不是必须挂在客户端上才能用的一摊字段。

取出工具注册表:`ToolRegistry` 原样返回,ChatClient 取其 `:tool-registry`。

查询函数一律经它,于是「传 ChatClient」与「传裸注册表」两种调用都成立——
注册表是个独立的值,不是必须挂在客户端上才能用的一摊字段。
sourceraw docstring

retry-policyclj

(retry-policy chat-client fn-name)

工具的 :retry 声明(归一化已在装配期做掉)。仅 :transient 类错误按此策略 重试;声明即承诺幂等(重试会重跑整条 tool filter 链)。

返回: nil(未声明,不重试)| {:max-retries n :initial-delay-ms ms}

工具的 :retry 声明(归一化已在装配期做掉)。仅 :transient 类错误按此策略
重试;声明即承诺幂等(重试会重跑整条 tool filter 链)。

返回: nil(未声明,不重试)| {:max-retries n :initial-delay-ms ms}
sourceraw docstring

return-direct-tool?clj

(return-direct-tool? chat-client fn-name)

工具是否声明 :return-direct(结果即最终答案,不再回灌 LLM)。

对标 Spring AI ToolCallingAdvisor 的 return direct。

工具是否声明 :return-direct(结果即最终答案,不再回灌 LLM)。

对标 Spring AI ToolCallingAdvisor 的 return direct。
sourceraw docstring

serial-tool?clj

(serial-tool? chat-client fn-name)

工具是否声明 :serial(副作用工具;批内并行时整批退化为按序执行)。

工具是否声明 :serial(副作用工具;批内并行时整批退化为按序执行)。
sourceraw docstring

tool-keyclj

(tool-key fn-name)

函数名(关键字或字符串)→ 表的键。

函数名(关键字或字符串)→ 表的键。
sourceraw docstring

tool-metaclj

(tool-meta x fn-name)

工具的装配期预计算声明(ToolMeta record),未注册则 nil。

下面四个查询都是它的一层薄封装——var 与内联工具在装配期就汇成了一张表, 运行期没有分支可走岔。

工具的装配期预计算声明(`ToolMeta` record),未注册则 nil。

下面四个查询都是它的一层薄封装——**var 与内联工具在装配期就汇成了一张表**,
运行期没有分支可走岔。
sourceraw docstring

tool-schemasclj

(tool-schemas x)

发给 LLM 的 tool schema 列表(var 工具与内联工具同列)。

(:tools chat-client) 的替代——四个工具字段收进 :tool-registry 之后, ChatClient 上不再有 :tools。

发给 LLM 的 tool schema 列表(var 工具与内联工具同列)。

**`(:tools chat-client)` 的替代**——四个工具字段收进 `:tool-registry` 之后,
ChatClient 上不再有 `:tools`。
sourceraw docstring

tool-timeoutclj

(tool-timeout chat-client fn-name)

工具自己声明的 :timeout(毫秒)。

只答「这个工具声明了什么」,不含引擎缺省——那一层见 effective-tool-timeout。

返回: nil(未声明)| 正整数毫秒

工具**自己声明**的 `:timeout`(毫秒)。

只答「这个工具声明了什么」,不含引擎缺省——那一层见 `effective-tool-timeout`。

返回: nil(未声明)| 正整数毫秒
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close