Liking cljdoc? Tell your friends :D

im.ttalk.agent.approval

声明式审批策略、会话审批缓存、审批者链、拒绝熔断(designs/runtime-borrow.md §5 §6; 借 Keelson Tools/ApprovalPolicy.cs RulePolicy.cs ApprovalCache.cs ToolHintPolicy.cs 与 Advisors/ChainApprover.cs DenialBreaker.cs Approvers.cs,它们又借 Codex execpolicy / guardian)。

全是纯函数与数据,产出现有挂点能直接吃的东西:

出口给谁场景
gatereact :tool-gate / simple-agent :approvalHITL:要问就暂停等人
approval-filterchat-client :filters(:tool 链)同步审批(CLI / 审批服务 / 模型审阅者)
->approve-fn旧的 flt/approval-filter兼容

决策:{:decision :allow|:prompt|:forbid :reason 字符串? :allow-session? bool}, 多条取最严(forbid > prompt > allow)。

策略:(fn [req] -> 决策),req = {:name :args :sensitive? :inline? :hints :tool-call}。

审批者:(fn [req] -> {:approved? bool :reason? :remember? :timed-out?} | nil), nil = 不表态(交给链上的下一位)。:remember :session = 「本会话都批准」。

声明式审批策略、会话审批缓存、审批者链、拒绝熔断(designs/runtime-borrow.md §5 §6;
借 Keelson `Tools/ApprovalPolicy.cs` `RulePolicy.cs` `ApprovalCache.cs` `ToolHintPolicy.cs`
与 `Advisors/ChainApprover.cs` `DenialBreaker.cs` `Approvers.cs`,它们又借 Codex execpolicy /
guardian)。

全是**纯函数与数据**,产出现有挂点能直接吃的东西:

| 出口 | 给谁 | 场景 |
|---|---|---|
| `gate`            | react `:tool-gate` / simple-agent `:approval` | HITL:要问就**暂停**等人 |
| `approval-filter` | chat-client `:filters`(`:tool` 链)          | 同步审批(CLI / 审批服务 / 模型审阅者) |
| `->approve-fn`    | 旧的 `flt/approval-filter`                    | 兼容 |

**决策**:`{:decision :allow|:prompt|:forbid :reason 字符串? :allow-session? bool}`,
多条取最严(forbid > prompt > allow)。

**策略**:`(fn [req] -> 决策)`,req = `{:name :args :sensitive? :inline? :hints :tool-call}`。

**审批者**:`(fn [req] -> {:approved? bool :reason? :remember? :timed-out?} | nil)`,
nil = 不表态(交给链上的下一位)。`:remember :session` = 「本会话都批准」。
raw docstring

->approve-fnclj

(->approve-fn {:keys [approver]})

适配旧的 flt/approval-filter(它只对 :sensitive 工具问 (approve-fn name args) -> bool)。

适配旧的 `flt/approval-filter`(它只对 :sensitive 工具问 `(approve-fn name args) -> bool`)。
sourceraw docstring

allowclj

直接执行。

直接执行。
sourceraw docstring

approval-filterclj

(approval-filter {:keys [policy approver cache breaker hints-fn]
                  :or {policy sensitive-policy}})

同步审批 :tool filter(CLI / 审批服务 / 模型审阅者)。

opts:

  • :policy 策略(缺省 sensitive-policy)
  • :approver 审批者(chain-approver / timeout-approver / 模型审阅者…); prompt 时没有审批者 → 一律拒(敏感操作不静默放行)
  • :cache session-cache;审批者回 :remember :session 时记账,同键不再问
  • :breaker 熔断参数 map(如 {:max-consecutive 3});给了就开。按会话计数、 每个 turn 清零;跳闸 → 写 :loop/stop 停回合
  • :hints-fn (fn [工具名] -> hints):filter 里拿不到注册表,内联工具的注解靠它给

审批者收到的 req 多带 :reason(策略理由):context :call-id。

同步审批 `:tool` filter(CLI / 审批服务 / 模型审阅者)。

opts:
- :policy    策略(缺省 sensitive-policy)
- :approver  审批者(`chain-approver` / `timeout-approver` / 模型审阅者…);
             prompt 时没有审批者 → 一律拒(敏感操作不静默放行)
- :cache     `session-cache`;审批者回 `:remember :session` 时记账,同键不再问
- :breaker   熔断参数 map(如 {:max-consecutive 3});给了就开。按会话计数、
             每个 turn 清零;跳闸 → 写 `:loop/stop` 停回合
- :hints-fn  (fn [工具名] -> hints):filter 里拿不到注册表,内联工具的注解靠它给

审批者收到的 req 多带 `:reason`(策略理由)`:context` `:call-id`。
sourceraw docstring

approval-keyclj

(approval-key tool-name args)

审批键:工具名 + 规范化参数(键序不同、同值 → 同键)。

审批键:工具名 + 规范化参数(键序不同、同值 → 同键)。
sourceraw docstring

approved?clj

(approved? cache k)
source

breaker-recordclj

(breaker-record st denied?)

记一次决定 → [新状态 本次跳闸?]。拒:连拒 +1;批准:连拒清零。只跳一次。

记一次决定 → `[新状态 本次跳闸?]`。拒:连拒 +1;批准:连拒清零。只跳一次。
sourceraw docstring

breaker-stateclj

(breaker-state)
(breaker-state opts)

熔断初始状态。opts: :max-consecutive 3、:max-recent 10、:window 50(同 Codex guardian)。

熔断初始状态。opts: :max-consecutive 3、:max-recent 10、:window 50(同 Codex guardian)。
sourceraw docstring

breaker-stop-noteclj

source

chain-approverclj

(chain-approver & approvers)

同 chain-reviewer,但到底无人表态 → 拒(无人表态 ≠ 默许)。

同 `chain-reviewer`,但到底无人表态 → **拒**(无人表态 ≠ 默许)。
sourceraw docstring

chain-reviewerclj

(chain-reviewer & approvers)

审批链(可嵌套):按序问,第一个非 nil 的说了算;某环抛 → 拒(带异常信息,不再往下问); 到底都不表态 → nil。

审批链(可嵌套):按序问,第一个非 nil 的说了算;某环抛 → 拒(带异常信息,不再往下问);
到底都不表态 → nil。
sourceraw docstring

denial-breakerclj

(denial-breaker)
(denial-breaker opts)

熔断器(atom 包装):(record! b denied?) → 本次跳闸返回 true。

熔断器(atom 包装):`(record! b denied?)` → 本次跳闸返回 true。
sourceraw docstring

forbidclj

(forbid)
(forbid reason)

不执行也不问,回拒绝(带理由)给模型。

不执行也不问,回拒绝(带理由)给模型。
sourceraw docstring

gateclj

(gate chat-client {:keys [policy cache] :or {policy sensitive-policy}})

策略 → react 的 :tool-gate:

  • allow → :proceed
  • forbid → {:reject 理由}(不问,模型直接拿到原因)
  • prompt → 会话缓存命中 :proceed,否则 {:pause {:reason :allow-session? :key}} (react 暂停;:key 供 resume 时「本会话都批准」记账)

opts: :policy(缺省 sensitive-policy)、:cache(session-cache,可选)

策略 → react 的 `:tool-gate`:
- allow  → `:proceed`
- forbid → `{:reject 理由}`(不问,模型直接拿到原因)
- prompt → 会话缓存命中 `:proceed`,否则 `{:pause {:reason :allow-session? :key}}`
          (react 暂停;`:key` 供 resume 时「本会话都批准」记账)

opts: :policy(缺省 sensitive-policy)、:cache(`session-cache`,可选)
sourceraw docstring

glob-match?clj

(glob-match? pattern s)

工具名 glob:* 任意串、? 一个字符。

工具名 glob:`*` 任意串、`?` 一个字符。
sourceraw docstring

hint-policyclj

(hint-policy & {:keys [mode modes] :or {mode :auto}})

按工具注解判的策略:只管内联工具(MCP 等外来工具,:inline? true);var 工具 仍按 :sensitive?。模式::auto(注解:destructive⇒问、read-only⇒免、缺省⇒问)、 :prompt(都问)、:writes(只读免问)、:approve(都不问)。:prompt/:writes 问的时候不许「本会话都批准」(同 Codex)。

opts: :mode 缺省模式(:auto);:modes [[工具名glob 模式] …] 先到先得。

按工具注解判的策略:只管**内联工具**(MCP 等外来工具,`:inline? true`);var 工具
仍按 `:sensitive?`。模式:`:auto`(注解:destructive⇒问、read-only⇒免、缺省⇒问)、
`:prompt`(都问)、`:writes`(只读免问)、`:approve`(都不问)。`:prompt`/`:writes`
问的时候不许「本会话都批准」(同 Codex)。

opts: :mode 缺省模式(:auto);:modes [[工具名glob 模式] …] 先到先得。
sourceraw docstring

hints-ofclj

(hints-of tool-map)

从内联工具 map 读注解::annotations {:readOnlyHint ..}(MCP 形状,键 keyword/字符串皆可)、 顶层 :read-only-hint 等,或 MCP 接入时放在元数据里的原始工具定义。

从内联工具 map 读注解:`:annotations {:readOnlyHint ..}`(MCP 形状,键 keyword/字符串皆可)、
顶层 `:read-only-hint` 等,或 MCP 接入时放在元数据里的原始工具定义。
sourceraw docstring

parse-pathclj

(parse-path path)

$ $.a.b a.b $.argv[0] $['k.x'] a.0 → 段向量(字符串或整数下标)。非法抛。

`$` `$.a.b` `a.b` `$.argv[0]` `$['k.x']` `a.0` → 段向量(字符串或整数下标)。非法抛。
sourceraw docstring

promptclj

(prompt)
(prompt reason)

要问。

要问。
sourceraw docstring

record!clj

(record! b denied?)
source

remember!clj

(remember! cache k)
source

requires-approval?clj

(requires-approval? {:keys [read-only? destructive? open-world?]} mode)

MCP 注解判据(Codex requires_mcp_tool_approval_for_mode)。hints 键: :read-only? :destructive? :open-world?(nil = 没给)。

MCP 注解判据(Codex `requires_mcp_tool_approval_for_mode`)。hints 键:
`:read-only?` `:destructive?` `:open-world?`(nil = 没给)。
sourceraw docstring

restore!clj

(restore! cache ks)

把快照并回缓存。

把快照并回缓存。
sourceraw docstring

rule-policyclj

(rule-policy rules & {:keys [fallback] :or {fallback sensitive-policy}})

数据驱动的审批策略:规则按工具名 glob + 参数谓词命中,多条命中取最严; 一条都没命中 → :fallback(缺省 sensitive-policy)。规则在构造时校验与自检, 不合格抛 ex-info。

规则: {:tool "shell*" :when [{:path "$.argv" :prefix ["git" ["status" "log"]]}] ; 恰好一个运算 :decision :allow ; 缺省 :allow :justification "只读 git 命令" :match [{:argv ["git" "status"]}] :not-match [{:argv ["git" "push"]}]}

谓词运算::equals(深相等):in(其一):regex(字符串,不锚定) :exists(true/false):prefix(数组前缀,某项写成向量 = 几种候选)。

数据驱动的审批策略:规则按工具名 glob + 参数谓词命中,**多条命中取最严**;
一条都没命中 → `:fallback`(缺省 `sensitive-policy`)。规则在构造时校验与自检,
不合格抛 ex-info。

规则:
{:tool "shell*"
 :when [{:path "$.argv" :prefix ["git" ["status" "log"]]}]   ; 恰好一个运算
 :decision :allow                                                  ; 缺省 :allow
 :justification "只读 git 命令"
 :match [{:argv ["git" "status"]}] :not-match [{:argv ["git" "push"]}]}

谓词运算:`:equals`(深相等)`:in`(其一)`:regex`(字符串,不锚定)
`:exists`(true/false)`:prefix`(数组前缀,某项写成向量 = 几种候选)。
sourceraw docstring

sensitive-policyclj

(sensitive-policy req)

缺省策略(今天的行为)::sensitive? → prompt,否则 allow。

缺省策略(今天的行为):`:sensitive?` → prompt,否则 allow。
sourceraw docstring

session-cacheclj

(session-cache)
(session-cache initial)

会话审批缓存(「本会话都批准」过的键)。线程安全。

会话审批缓存(「本会话都批准」过的键)。线程安全。
sourceraw docstring

snapshotclj

(snapshot cache)

缓存快照(排序后的键向量,可 EDN 往返;随暂停快照保存)。

缓存快照(排序后的键向量,可 EDN 往返;随暂停快照保存)。
sourceraw docstring

strictestclj

(strictest decisions)

取最严(同级取先给的);空 → allow。

取最严(同级取先给的);空 → allow。
sourceraw docstring

strictest-policyclj

(strictest-policy & policies)

几条策略一起判,取最严。

几条策略一起判,取最严。
sourceraw docstring

timeout-approverclj

(timeout-approver approver timeout-ms)

给审批者套时限:超时是结果({:approved? false :timed-out? true}),不是异常。 在虚拟线程上跑,到点 interrupt(同工具超时的语义:放弃等待)。

给审批者套时限:超时是**结果**(`{:approved? false :timed-out? true}`),不是异常。
在虚拟线程上跑,到点 interrupt(同工具超时的语义:放弃等待)。
sourceraw docstring

tool-requestclj

(tool-request chat-client tc)

react 的 tool-call → 策略输入。

react 的 tool-call → 策略输入。
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