@namzu/sdk 51.0.0 → 52.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +110 -0
- package/dist/agents/QueryAgent.d.ts.map +1 -1
- package/dist/agents/QueryAgent.js +2 -0
- package/dist/agents/QueryAgent.js.map +1 -1
- package/dist/agents/SupervisorAgent.d.ts +1 -1
- package/dist/agents/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/SupervisorAgent.js.map +1 -1
- package/dist/agents/examples/SupervisorAgent.d.ts +42 -0
- package/dist/agents/examples/SupervisorAgent.d.ts.map +1 -1
- package/dist/agents/examples/SupervisorAgent.js +80 -4
- package/dist/agents/examples/SupervisorAgent.js.map +1 -1
- package/dist/agents/index.d.ts +1 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js.map +1 -1
- package/dist/authorization/protected-paths.d.ts +36 -0
- package/dist/authorization/protected-paths.d.ts.map +1 -0
- package/dist/authorization/protected-paths.js +107 -0
- package/dist/authorization/protected-paths.js.map +1 -0
- package/dist/authorization/readonly-commands.d.ts +39 -0
- package/dist/authorization/readonly-commands.d.ts.map +1 -0
- package/dist/authorization/readonly-commands.js +797 -0
- package/dist/authorization/readonly-commands.js.map +1 -0
- package/dist/authorization/readonly-flags.d.ts +19 -0
- package/dist/authorization/readonly-flags.d.ts.map +1 -0
- package/dist/authorization/readonly-flags.js +178 -0
- package/dist/authorization/readonly-flags.js.map +1 -0
- package/dist/authorization/removal.d.ts +52 -0
- package/dist/authorization/removal.d.ts.map +1 -0
- package/dist/authorization/removal.js +283 -0
- package/dist/authorization/removal.js.map +1 -0
- package/dist/authorization/shell-paths.d.ts +66 -0
- package/dist/authorization/shell-paths.d.ts.map +1 -0
- package/dist/authorization/shell-paths.js +697 -0
- package/dist/authorization/shell-paths.js.map +1 -0
- package/dist/bridge/acp/update.d.ts.map +1 -1
- package/dist/bridge/acp/update.js +1 -0
- package/dist/bridge/acp/update.js.map +1 -1
- package/dist/bridge/sse/mapper.d.ts.map +1 -1
- package/dist/bridge/sse/mapper.js +1 -0
- package/dist/bridge/sse/mapper.js.map +1 -1
- package/dist/compaction/context-window.d.ts +24 -0
- package/dist/compaction/context-window.d.ts.map +1 -1
- package/dist/compaction/context-window.js +34 -0
- package/dist/compaction/context-window.js.map +1 -1
- package/dist/compaction/manual.d.ts.map +1 -1
- package/dist/compaction/manual.js +10 -2
- package/dist/compaction/manual.js.map +1 -1
- package/dist/compaction/plan.d.ts +4 -0
- package/dist/compaction/plan.d.ts.map +1 -1
- package/dist/compaction/plan.js +6 -2
- package/dist/compaction/plan.js.map +1 -1
- package/dist/compaction/verifier.d.ts +11 -1
- package/dist/compaction/verifier.d.ts.map +1 -1
- package/dist/compaction/verifier.js +19 -7
- package/dist/compaction/verifier.js.map +1 -1
- package/dist/config/runtime.d.ts +55 -7
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/runtime.js +23 -2
- package/dist/config/runtime.js.map +1 -1
- package/dist/connector/web/guarded-fetch.d.ts.map +1 -1
- package/dist/connector/web/guarded-fetch.js +24 -0
- package/dist/connector/web/guarded-fetch.js.map +1 -1
- package/dist/connector/web/index.d.ts +1 -1
- package/dist/connector/web/index.d.ts.map +1 -1
- package/dist/connector/web/page.d.ts +59 -0
- package/dist/connector/web/page.d.ts.map +1 -0
- package/dist/connector/web/page.js +112 -0
- package/dist/connector/web/page.js.map +1 -0
- package/dist/connector/web/types.d.ts +47 -0
- package/dist/connector/web/types.d.ts.map +1 -1
- package/dist/connector/web/types.js.map +1 -1
- package/dist/constants/continuation.d.ts +8 -0
- package/dist/constants/continuation.d.ts.map +1 -1
- package/dist/constants/continuation.js +8 -0
- package/dist/constants/continuation.js.map +1 -1
- package/dist/constants/plugin/index.d.ts +1 -1
- package/dist/constants/plugin/index.d.ts.map +1 -1
- package/dist/constants/plugin/index.js +1 -1
- package/dist/constants/plugin/index.js.map +1 -1
- package/dist/manager/agent/lifecycle.d.ts +7 -0
- package/dist/manager/agent/lifecycle.d.ts.map +1 -1
- package/dist/manager/agent/lifecycle.js +11 -2
- package/dist/manager/agent/lifecycle.js.map +1 -1
- package/dist/manager/session/turn-recorder.d.ts.map +1 -1
- package/dist/manager/session/turn-recorder.js +4 -2
- package/dist/manager/session/turn-recorder.js.map +1 -1
- package/dist/plugin/index.d.ts +1 -1
- package/dist/plugin/index.d.ts.map +1 -1
- package/dist/plugin/index.js +1 -1
- package/dist/plugin/index.js.map +1 -1
- package/dist/plugin/lifecycle.d.ts +6 -0
- package/dist/plugin/lifecycle.d.ts.map +1 -1
- package/dist/plugin/lifecycle.js +98 -114
- package/dist/plugin/lifecycle.js.map +1 -1
- package/dist/plugin/shell-hook.d.ts +90 -22
- package/dist/plugin/shell-hook.d.ts.map +1 -1
- package/dist/plugin/shell-hook.js +434 -41
- package/dist/plugin/shell-hook.js.map +1 -1
- package/dist/provider/errors.d.ts +10 -0
- package/dist/provider/errors.d.ts.map +1 -1
- package/dist/provider/errors.js +16 -0
- package/dist/provider/errors.js.map +1 -1
- package/dist/provider/retry.d.ts +27 -0
- package/dist/provider/retry.d.ts.map +1 -1
- package/dist/provider/retry.js +19 -3
- package/dist/provider/retry.js.map +1 -1
- package/dist/public-runtime.d.ts +4 -1
- package/dist/public-runtime.d.ts.map +1 -1
- package/dist/public-runtime.js +4 -1
- package/dist/public-runtime.js.map +1 -1
- package/dist/public-types.d.ts +2 -2
- package/dist/public-types.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.d.ts +21 -0
- package/dist/runtime/jobs/registry.d.ts.map +1 -1
- package/dist/runtime/jobs/registry.js +15 -2
- package/dist/runtime/jobs/registry.js.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.d.ts +10 -0
- package/dist/runtime/query/executor/tool-call-admission.d.ts.map +1 -1
- package/dist/runtime/query/executor/tool-call-admission.js +74 -13
- package/dist/runtime/query/executor/tool-call-admission.js.map +1 -1
- package/dist/runtime/query/executor.d.ts +41 -2
- package/dist/runtime/query/executor.d.ts.map +1 -1
- package/dist/runtime/query/executor.js +190 -6
- package/dist/runtime/query/executor.js.map +1 -1
- package/dist/runtime/query/finalize-turn.d.ts +6 -0
- package/dist/runtime/query/finalize-turn.d.ts.map +1 -1
- package/dist/runtime/query/finalize-turn.js +1 -1
- package/dist/runtime/query/finalize-turn.js.map +1 -1
- package/dist/runtime/query/index.d.ts +29 -0
- package/dist/runtime/query/index.d.ts.map +1 -1
- package/dist/runtime/query/index.js +15 -3
- package/dist/runtime/query/index.js.map +1 -1
- package/dist/runtime/query/iteration/index.d.ts +31 -0
- package/dist/runtime/query/iteration/index.d.ts.map +1 -1
- package/dist/runtime/query/iteration/index.js +216 -7
- package/dist/runtime/query/iteration/index.js.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts +58 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.d.ts.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js +91 -0
- package/dist/runtime/query/iteration/phases/compaction-breaker.js.map +1 -0
- package/dist/runtime/query/iteration/phases/compaction.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/compaction.js +89 -7
- package/dist/runtime/query/iteration/phases/compaction.js.map +1 -1
- package/dist/runtime/query/iteration/phases/context.d.ts +10 -0
- package/dist/runtime/query/iteration/phases/context.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/context.js.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.d.ts.map +1 -1
- package/dist/runtime/query/iteration/phases/tool-review.js +165 -2
- package/dist/runtime/query/iteration/phases/tool-review.js.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.d.ts.map +1 -1
- package/dist/runtime/query/iteration/stream-turn.js +24 -1
- package/dist/runtime/query/iteration/stream-turn.js.map +1 -1
- package/dist/runtime/query/path-escalation.d.ts +36 -0
- package/dist/runtime/query/path-escalation.d.ts.map +1 -0
- package/dist/runtime/query/path-escalation.js +184 -0
- package/dist/runtime/query/path-escalation.js.map +1 -0
- package/dist/runtime/query/plugin-hooks.d.ts.map +1 -1
- package/dist/runtime/query/plugin-hooks.js +8 -0
- package/dist/runtime/query/plugin-hooks.js.map +1 -1
- package/dist/runtime/query/reminders.d.ts +35 -0
- package/dist/runtime/query/reminders.d.ts.map +1 -0
- package/dist/runtime/query/reminders.js +7 -0
- package/dist/runtime/query/reminders.js.map +1 -0
- package/dist/runtime/query/resume-pending.d.ts.map +1 -1
- package/dist/runtime/query/resume-pending.js +26 -0
- package/dist/runtime/query/resume-pending.js.map +1 -1
- package/dist/runtime/query/review-policy.d.ts +26 -0
- package/dist/runtime/query/review-policy.d.ts.map +1 -1
- package/dist/runtime/query/review-policy.js +79 -5
- package/dist/runtime/query/review-policy.js.map +1 -1
- package/dist/runtime/query/tool-output-budget.d.ts +46 -0
- package/dist/runtime/query/tool-output-budget.d.ts.map +1 -1
- package/dist/runtime/query/tool-output-budget.js +85 -1
- package/dist/runtime/query/tool-output-budget.js.map +1 -1
- package/dist/runtime/query/tooling.d.ts +1 -0
- package/dist/runtime/query/tooling.d.ts.map +1 -1
- package/dist/runtime/query/tooling.js +5 -0
- package/dist/runtime/query/tooling.js.map +1 -1
- package/dist/session/paths.d.ts +5 -1
- package/dist/session/paths.d.ts.map +1 -1
- package/dist/session/paths.js +8 -0
- package/dist/session/paths.js.map +1 -1
- package/dist/store/memory/disk.d.ts.map +1 -1
- package/dist/store/memory/disk.js +2 -2
- package/dist/store/memory/disk.js.map +1 -1
- package/dist/store/memory/markdown.d.ts.map +1 -1
- package/dist/store/memory/markdown.js +2 -2
- package/dist/store/memory/markdown.js.map +1 -1
- package/dist/store/memory/naming.d.ts +9 -0
- package/dist/store/memory/naming.d.ts.map +1 -1
- package/dist/store/memory/naming.js +12 -0
- package/dist/store/memory/naming.js.map +1 -1
- package/dist/tools/builtins/bash.d.ts +30 -1
- package/dist/tools/builtins/bash.d.ts.map +1 -1
- package/dist/tools/builtins/bash.js +170 -26
- package/dist/tools/builtins/bash.js.map +1 -1
- package/dist/tools/builtins/content-fingerprint.d.ts +2 -0
- package/dist/tools/builtins/content-fingerprint.d.ts.map +1 -1
- package/dist/tools/builtins/content-fingerprint.js +4 -0
- package/dist/tools/builtins/content-fingerprint.js.map +1 -1
- package/dist/tools/builtins/edit.d.ts.map +1 -1
- package/dist/tools/builtins/edit.js +60 -18
- package/dist/tools/builtins/edit.js.map +1 -1
- package/dist/tools/builtins/grep.d.ts +8 -1
- package/dist/tools/builtins/grep.d.ts.map +1 -1
- package/dist/tools/builtins/grep.js +152 -33
- package/dist/tools/builtins/grep.js.map +1 -1
- package/dist/tools/builtins/read-file.d.ts +1 -0
- package/dist/tools/builtins/read-file.d.ts.map +1 -1
- package/dist/tools/builtins/read-file.js +44 -5
- package/dist/tools/builtins/read-file.js.map +1 -1
- package/dist/tools/builtins/read-render.d.ts +52 -0
- package/dist/tools/builtins/read-render.d.ts.map +1 -1
- package/dist/tools/builtins/read-render.js +143 -0
- package/dist/tools/builtins/read-render.js.map +1 -1
- package/dist/tools/builtins/web.d.ts +13 -2
- package/dist/tools/builtins/web.d.ts.map +1 -1
- package/dist/tools/builtins/web.js +225 -32
- package/dist/tools/builtins/web.js.map +1 -1
- package/dist/tools/coordinator/ask-user-question.d.ts +2 -0
- package/dist/tools/coordinator/ask-user-question.d.ts.map +1 -1
- package/dist/tools/coordinator/ask-user-question.js +256 -92
- package/dist/tools/coordinator/ask-user-question.js.map +1 -1
- package/dist/tools/coordinator/question-options.d.ts +1 -0
- package/dist/tools/coordinator/question-options.d.ts.map +1 -1
- package/dist/tools/coordinator/question-options.js +6 -1
- package/dist/tools/coordinator/question-options.js.map +1 -1
- package/dist/tools/defineTool.d.ts +4 -1
- package/dist/tools/defineTool.d.ts.map +1 -1
- package/dist/tools/defineTool.js +6 -1
- package/dist/tools/defineTool.js.map +1 -1
- package/dist/tools/paths.d.ts +6 -0
- package/dist/tools/paths.d.ts.map +1 -1
- package/dist/tools/paths.js +1 -1
- package/dist/tools/paths.js.map +1 -1
- package/dist/types/agent/query.d.ts +3 -0
- package/dist/types/agent/query.d.ts.map +1 -1
- package/dist/types/errors/catalog.js +1 -1
- package/dist/types/errors/catalog.js.map +1 -1
- package/dist/types/hitl/index.d.ts +104 -0
- package/dist/types/hitl/index.d.ts.map +1 -1
- package/dist/types/hitl/index.js.map +1 -1
- package/dist/types/message/index.d.ts +1 -1
- package/dist/types/message/index.d.ts.map +1 -1
- package/dist/types/message/index.js +2 -0
- package/dist/types/message/index.js.map +1 -1
- package/dist/types/plugin/index.d.ts +93 -19
- package/dist/types/plugin/index.d.ts.map +1 -1
- package/dist/types/plugin/index.js +3 -0
- package/dist/types/plugin/index.js.map +1 -1
- package/dist/types/provider/error.d.ts +6 -0
- package/dist/types/provider/error.d.ts.map +1 -1
- package/dist/types/provider/errors.d.ts +19 -0
- package/dist/types/provider/errors.d.ts.map +1 -1
- package/dist/types/provider/errors.js +39 -1
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/provider/stream.d.ts +6 -0
- package/dist/types/provider/stream.d.ts.map +1 -1
- package/dist/types/session/events.d.ts +15 -2
- package/dist/types/session/events.d.ts.map +1 -1
- package/dist/types/session/events.js.map +1 -1
- package/dist/types/session/records.d.ts +9 -9
- package/dist/types/session/records.d.ts.map +1 -1
- package/dist/types/session/records.js +1 -0
- package/dist/types/session/records.js.map +1 -1
- package/dist/types/session/stop-reason.d.ts +5 -0
- package/dist/types/session/stop-reason.d.ts.map +1 -1
- package/dist/types/tool/index.d.ts +52 -0
- package/dist/types/tool/index.d.ts.map +1 -1
- package/dist/types/tool/index.js.map +1 -1
- package/dist/utils/backoff.d.ts +12 -0
- package/dist/utils/backoff.d.ts.map +1 -1
- package/dist/utils/backoff.js +15 -0
- package/dist/utils/backoff.js.map +1 -1
- package/package.json +4 -2
- package/src/agents/QueryAgent.ts +5 -1
- package/src/agents/SupervisorAgent.ts +1 -1
- package/src/agents/examples/SupervisorAgent.ts +217 -106
- package/src/agents/index.ts +1 -1
- package/src/authorization/protected-paths.ts +110 -0
- package/src/authorization/readonly-commands.ts +771 -0
- package/src/authorization/readonly-flags.ts +196 -0
- package/src/authorization/removal.ts +326 -0
- package/src/authorization/shell-paths.ts +927 -0
- package/src/bridge/acp/update.ts +1 -0
- package/src/bridge/sse/mapper.ts +1 -0
- package/src/compaction/context-window.ts +41 -0
- package/src/compaction/manual.ts +10 -2
- package/src/compaction/plan.ts +11 -2
- package/src/compaction/verifier.ts +28 -3
- package/src/config/runtime.ts +23 -2
- package/src/connector/web/guarded-fetch.ts +26 -0
- package/src/connector/web/index.ts +3 -0
- package/src/connector/web/page.ts +130 -0
- package/src/connector/web/types.ts +47 -0
- package/src/constants/continuation.ts +10 -0
- package/src/constants/plugin/index.ts +1 -1
- package/src/manager/agent/lifecycle.ts +12 -4
- package/src/manager/session/turn-recorder.ts +10 -2
- package/src/plugin/index.ts +1 -0
- package/src/plugin/lifecycle.ts +107 -119
- package/src/plugin/shell-hook.ts +477 -43
- package/src/provider/errors.ts +18 -0
- package/src/provider/retry.ts +53 -3
- package/src/public-runtime.ts +8 -0
- package/src/public-types.ts +4 -0
- package/src/runtime/jobs/registry.ts +39 -2
- package/src/runtime/query/executor/tool-call-admission.ts +79 -13
- package/src/runtime/query/executor.ts +242 -8
- package/src/runtime/query/finalize-turn.ts +7 -1
- package/src/runtime/query/index.ts +45 -3
- package/src/runtime/query/iteration/index.ts +251 -12
- package/src/runtime/query/iteration/phases/compaction-breaker.ts +106 -0
- package/src/runtime/query/iteration/phases/compaction.ts +99 -12
- package/src/runtime/query/iteration/phases/context.ts +11 -0
- package/src/runtime/query/iteration/phases/tool-review.ts +177 -2
- package/src/runtime/query/iteration/stream-turn.ts +24 -1
- package/src/runtime/query/path-escalation.ts +204 -0
- package/src/runtime/query/plugin-hooks.ts +8 -0
- package/src/runtime/query/reminders.ts +45 -0
- package/src/runtime/query/resume-pending.ts +27 -0
- package/src/runtime/query/review-policy.ts +106 -5
- package/src/runtime/query/tool-output-budget.ts +115 -1
- package/src/runtime/query/tooling.ts +6 -0
- package/src/session/paths.ts +11 -1
- package/src/store/memory/disk.ts +2 -1
- package/src/store/memory/markdown.ts +2 -1
- package/src/store/memory/naming.ts +13 -0
- package/src/tools/builtins/bash.ts +203 -34
- package/src/tools/builtins/content-fingerprint.ts +5 -0
- package/src/tools/builtins/edit.ts +69 -19
- package/src/tools/builtins/grep.ts +159 -38
- package/src/tools/builtins/read-file.ts +48 -5
- package/src/tools/builtins/read-render.ts +193 -0
- package/src/tools/builtins/web.ts +258 -33
- package/src/tools/coordinator/ask-user-question.ts +309 -103
- package/src/tools/coordinator/question-options.ts +8 -1
- package/src/tools/defineTool.ts +11 -2
- package/src/tools/paths.ts +1 -1
- package/src/types/agent/query.ts +3 -0
- package/src/types/errors/catalog.ts +1 -1
- package/src/types/hitl/index.ts +104 -0
- package/src/types/message/index.ts +2 -0
- package/src/types/plugin/index.ts +101 -18
- package/src/types/provider/error.ts +6 -0
- package/src/types/provider/errors.ts +49 -1
- package/src/types/provider/stream.ts +6 -0
- package/src/types/session/events.ts +15 -2
- package/src/types/session/records.ts +1 -0
- package/src/types/session/stop-reason.ts +5 -0
- package/src/types/tool/index.ts +53 -2
- package/src/utils/backoff.ts +21 -0
package/src/types/hitl/index.ts
CHANGED
|
@@ -55,6 +55,14 @@ export type HITLResumeDecision =
|
|
|
55
55
|
* listed here for an unmarked call is ignored rather than trusted.
|
|
56
56
|
*/
|
|
57
57
|
skillGranted?: readonly string[]
|
|
58
|
+
/**
|
|
59
|
+
* Ids of calls approved on the strength of a `pre_tool_use` hook's
|
|
60
|
+
* `allow` ({@link ToolCallSummary.hookGrant}), with nobody asked.
|
|
61
|
+
*
|
|
62
|
+
* Audited like `skillGranted`, and ignored for any id whose call did
|
|
63
|
+
* not carry the mark.
|
|
64
|
+
*/
|
|
65
|
+
hookGranted?: readonly string[]
|
|
58
66
|
}
|
|
59
67
|
| {
|
|
60
68
|
action: 'modify_tools'
|
|
@@ -77,6 +85,15 @@ export type HITLResumeDecision =
|
|
|
77
85
|
action: 'answer_question'
|
|
78
86
|
selectedOptionIds: string[]
|
|
79
87
|
freeText?: string
|
|
88
|
+
/**
|
|
89
|
+
* One answer per question of a batch (`UserQuestionData.questions`).
|
|
90
|
+
* When present it is the answer; `selectedOptionIds`/`freeText`
|
|
91
|
+
* then carry nothing the tool reads (send `[]`). Absent on a
|
|
92
|
+
* single-question park, and on a batch from a host that only
|
|
93
|
+
* knows one question — then `selectedOptionIds`/`freeText`
|
|
94
|
+
* answer the first question and the rest are unanswered.
|
|
95
|
+
*/
|
|
96
|
+
answers?: readonly UserQuestionAnswer[]
|
|
80
97
|
/**
|
|
81
98
|
* Echo of `UserQuestionData.questionId` — the misdirection
|
|
82
99
|
* guard. The park/resolve registry on hosts is typically
|
|
@@ -176,6 +193,28 @@ export interface ToolCallSummary {
|
|
|
176
193
|
* and `strict`. A host's own handler may ignore it.
|
|
177
194
|
*/
|
|
178
195
|
skillGrant?: { readonly skill: string }
|
|
196
|
+
/**
|
|
197
|
+
* What a `pre_tool_use` hook answered about approving this call, as the
|
|
198
|
+
* hooks reported it. `ask` is acted on by the kernel (it makes the call an
|
|
199
|
+
* explicit review); `allow` is acted on only through {@link hookGrant}.
|
|
200
|
+
*/
|
|
201
|
+
hookPermission?: {
|
|
202
|
+
readonly decision: 'allow' | 'ask'
|
|
203
|
+
readonly reason?: string
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Present when a `pre_tool_use` hook said `allow` and nothing stronger
|
|
207
|
+
* stands in the way.
|
|
208
|
+
*
|
|
209
|
+
* Marked on the same terms as {@link skillGrant}: only a call the
|
|
210
|
+
* operator's policy left to review (no `deny`, no explicit `ask` rule, no
|
|
211
|
+
* hook `ask`), that is not destructive, carries no {@link escalation} and
|
|
212
|
+
* is not one the tool always asks about. A sandbox escape, a path outside
|
|
213
|
+
* the roots, a tool's own `requiresApproval`, a rule's review and the
|
|
214
|
+
* dangerous-pattern floor therefore all still reach a person, or refuse.
|
|
215
|
+
* `plan` and `strict` refuse a marked call exactly as they refuse any other.
|
|
216
|
+
*/
|
|
217
|
+
hookGrant?: { readonly reason?: string }
|
|
179
218
|
}
|
|
180
219
|
|
|
181
220
|
/** See {@link ToolCallSummary.escalation}. */
|
|
@@ -218,6 +257,27 @@ export interface ToolCallEscalation {
|
|
|
218
257
|
* where a program name is actually decided.
|
|
219
258
|
*/
|
|
220
259
|
unknownProgram?: string
|
|
260
|
+
/**
|
|
261
|
+
* Absolute paths this call writes that are protected in every mode: git
|
|
262
|
+
* hooks and config, shell rc files, editor and tool configuration, the
|
|
263
|
+
* project's own `.namzu` directory (see `authorization/protected-paths.ts`
|
|
264
|
+
* for the list). A write there plants something that runs later, outside
|
|
265
|
+
* the turn, so it is asked about every time and refused when nobody can be
|
|
266
|
+
* asked; no rule, mode or remembered approval covers it. Set for the file
|
|
267
|
+
* tools' declared path and for the visible write targets of a shell line:
|
|
268
|
+
* output redirections, and the operands of `cp`, `mv`, `tee`, `touch`,
|
|
269
|
+
* `mkdir`, `rm`, `rmdir` and `sed -i`.
|
|
270
|
+
*/
|
|
271
|
+
protectedPaths?: readonly string[]
|
|
272
|
+
/**
|
|
273
|
+
* Why a shell line removes something it must not: the file system root, a
|
|
274
|
+
* top-level directory, the home directory, the working directory or one of
|
|
275
|
+
* its parents, a glob that crosses directories, or a target a variable or
|
|
276
|
+
* substitution may empty. The flags do not matter, only the targets. Asked
|
|
277
|
+
* about every time and refused when nobody can be asked. Present only for a
|
|
278
|
+
* tool that declares `commandArgument`.
|
|
279
|
+
*/
|
|
280
|
+
dangerousRemoval?: string
|
|
221
281
|
}
|
|
222
282
|
|
|
223
283
|
export interface ToolModification {
|
|
@@ -250,6 +310,12 @@ export interface UserQuestionOption {
|
|
|
250
310
|
* Absent, not `false`, on every other option.
|
|
251
311
|
*/
|
|
252
312
|
recommended?: boolean
|
|
313
|
+
/**
|
|
314
|
+
* Plain text or markdown a host may show beside the option list while this
|
|
315
|
+
* option is focused (a snippet, a mock-up, a side-by-side). Optional and
|
|
316
|
+
* never required to answer; a host that has nowhere to show it ignores it.
|
|
317
|
+
*/
|
|
318
|
+
preview?: string
|
|
253
319
|
}
|
|
254
320
|
|
|
255
321
|
/**
|
|
@@ -267,6 +333,44 @@ export interface UserQuestionData {
|
|
|
267
333
|
options: UserQuestionOption[]
|
|
268
334
|
multiSelect: boolean
|
|
269
335
|
allowFreeText: boolean
|
|
336
|
+
/**
|
|
337
|
+
* Present when one `ask_user_question` call carries several related
|
|
338
|
+
* questions (two to four; a single question leaves this out). The
|
|
339
|
+
* top-level `question`, `header`, `options`, `multiSelect` and
|
|
340
|
+
* `allowFreeText` then mirror the FIRST entry, so a host that does not
|
|
341
|
+
* know this field still shows a coherent question and answers it; the
|
|
342
|
+
* rest read as unanswered.
|
|
343
|
+
*
|
|
344
|
+
* A host shows all of them together, collects every answer, and returns
|
|
345
|
+
* one {@link UserQuestionAnswer} per question it has an answer for through
|
|
346
|
+
* `answer_question.answers`.
|
|
347
|
+
*/
|
|
348
|
+
questions?: readonly UserQuestionItem[]
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* One question of a batch. `id` is stable: the asking `tool_use_id`, `#`, and
|
|
353
|
+
* the question's zero-based position, so an answer names the question it
|
|
354
|
+
* belongs to even when a host shows them in another order.
|
|
355
|
+
*/
|
|
356
|
+
export interface UserQuestionItem {
|
|
357
|
+
id: string
|
|
358
|
+
question: string
|
|
359
|
+
header?: string
|
|
360
|
+
options: UserQuestionOption[]
|
|
361
|
+
multiSelect: boolean
|
|
362
|
+
allowFreeText: boolean
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* The answer to one question of a batch. A question with no entry was not
|
|
367
|
+
* answered; an entry with no selection and no text counts the same.
|
|
368
|
+
*/
|
|
369
|
+
export interface UserQuestionAnswer {
|
|
370
|
+
/** {@link UserQuestionItem.id}. */
|
|
371
|
+
questionId: string
|
|
372
|
+
selectedOptionIds: string[]
|
|
373
|
+
freeText?: string
|
|
270
374
|
}
|
|
271
375
|
|
|
272
376
|
export interface PlanApprovalData {
|
|
@@ -352,11 +352,13 @@ export const RUNTIME_CONTEXT_MESSAGE_KINDS = [
|
|
|
352
352
|
'answer-review',
|
|
353
353
|
'auto-continuation',
|
|
354
354
|
'channel-message',
|
|
355
|
+
'hook-feedback',
|
|
355
356
|
'host-observation',
|
|
356
357
|
'job-exit',
|
|
357
358
|
'limit-finalization',
|
|
358
359
|
'peer-message',
|
|
359
360
|
'peer-notice',
|
|
361
|
+
'reminder',
|
|
360
362
|
'repeat-call',
|
|
361
363
|
'steering',
|
|
362
364
|
'step-context',
|
|
@@ -107,6 +107,24 @@ export type PluginHookEvent =
|
|
|
107
107
|
| 'turn_interrupt'
|
|
108
108
|
| 'pre_tool_use'
|
|
109
109
|
| 'post_tool_use'
|
|
110
|
+
/**
|
|
111
|
+
* A tool call ended in failure. Fired after `post_tool_use` for the same
|
|
112
|
+
* call, only when the result is a failure. Carries `toolName`, `toolInput`
|
|
113
|
+
* and `toolResult`.
|
|
114
|
+
*/
|
|
115
|
+
| 'post_tool_use_failure'
|
|
116
|
+
/**
|
|
117
|
+
* A person is about to be asked whether a tool call may run. Carries
|
|
118
|
+
* `toolName` and `toolInput`. A hook may answer before the question is
|
|
119
|
+
* shown: `continue` with `permission: { decision: 'allow' }` approves the
|
|
120
|
+
* call (never one that is always asked about), `skip` refuses it.
|
|
121
|
+
*/
|
|
122
|
+
| 'permission_request'
|
|
123
|
+
/**
|
|
124
|
+
* The host wants the operator's attention: a review is waiting, or a turn
|
|
125
|
+
* settled. Carries `notification` (`type` and `message`). Observational.
|
|
126
|
+
*/
|
|
127
|
+
| 'notification'
|
|
110
128
|
| 'pre_llm_call'
|
|
111
129
|
| 'post_llm_call'
|
|
112
130
|
| 'iteration_start'
|
|
@@ -139,6 +157,9 @@ export function assertPluginHookEvent(event: PluginHookEvent): void {
|
|
|
139
157
|
case 'turn_interrupt':
|
|
140
158
|
case 'pre_tool_use':
|
|
141
159
|
case 'post_tool_use':
|
|
160
|
+
case 'post_tool_use_failure':
|
|
161
|
+
case 'permission_request':
|
|
162
|
+
case 'notification':
|
|
142
163
|
case 'pre_llm_call':
|
|
143
164
|
case 'post_llm_call':
|
|
144
165
|
case 'iteration_start':
|
|
@@ -196,6 +217,16 @@ export interface PluginCompactionInfo {
|
|
|
196
217
|
readonly contextWindowTokens: number
|
|
197
218
|
}
|
|
198
219
|
|
|
220
|
+
/** What a `notification` hook is shown. */
|
|
221
|
+
export interface PluginNotificationInfo {
|
|
222
|
+
/**
|
|
223
|
+
* `approval_required` (a review is waiting), `turn_settled` (a turn ended) or
|
|
224
|
+
* `idle_prompt` (the host has waited for the operator for a while).
|
|
225
|
+
*/
|
|
226
|
+
readonly type: 'approval_required' | 'turn_settled' | 'idle_prompt'
|
|
227
|
+
readonly message: string
|
|
228
|
+
}
|
|
229
|
+
|
|
199
230
|
export interface PluginHookContext {
|
|
200
231
|
/** The turn the hook fired in. Absent on `session_start` and `session_end`. */
|
|
201
232
|
readonly turnId?: TurnId
|
|
@@ -214,6 +245,15 @@ export interface PluginHookContext {
|
|
|
214
245
|
readonly toolName?: string
|
|
215
246
|
readonly toolInput?: unknown
|
|
216
247
|
readonly toolResult?: ToolResult
|
|
248
|
+
/** What the host is telling the operator, on `notification`. */
|
|
249
|
+
readonly notification?: PluginNotificationInfo
|
|
250
|
+
/**
|
|
251
|
+
* On `turn_end` and `subagent_stop` when an earlier answer to the same
|
|
252
|
+
* event kept the turn going: the hook is being asked again about a turn it
|
|
253
|
+
* already refused to let end. A hook that always refuses would otherwise
|
|
254
|
+
* keep the model working until the turn's own limits stop it.
|
|
255
|
+
*/
|
|
256
|
+
readonly stopHookActive?: boolean
|
|
217
257
|
readonly iteration?: number
|
|
218
258
|
/**
|
|
219
259
|
* Why the turn was stopped, on `turn_interrupt`.
|
|
@@ -267,8 +307,41 @@ export interface PluginHookContext {
|
|
|
267
307
|
readonly signal?: AbortSignal
|
|
268
308
|
}
|
|
269
309
|
|
|
310
|
+
/**
|
|
311
|
+
* What a hook may say about a tool call beyond letting it run or not. Only
|
|
312
|
+
* `allow` and `ask` exist here: a refusal is `skip`, which always wins.
|
|
313
|
+
*
|
|
314
|
+
* `allow` stands in for the person's yes ONLY on a call that would have been
|
|
315
|
+
* asked about for no reason beyond "it changes something". It never covers a
|
|
316
|
+
* sandbox escape, a path outside the roots, a call the tool declares it always
|
|
317
|
+
* needs approval for, a call a rule sent to review explicitly, or one the tool
|
|
318
|
+
* declares destructive; and it never reopens what a rule denied.
|
|
319
|
+
* `ask` makes the call go to a person even where a rule or the tool's own
|
|
320
|
+
* read-only declaration would have let it through.
|
|
321
|
+
*/
|
|
322
|
+
export interface PluginHookPermission {
|
|
323
|
+
readonly decision: 'allow' | 'ask'
|
|
324
|
+
readonly reason?: string
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** Extra facts a hook may attach to the verdicts that let the work go on. */
|
|
328
|
+
export interface PluginHookNotes {
|
|
329
|
+
/**
|
|
330
|
+
* Text for the model. On a tool event it is appended to what the model
|
|
331
|
+
* reads of that call; on `user_prompt_submit` it joins the turn's context.
|
|
332
|
+
*/
|
|
333
|
+
readonly context?: string
|
|
334
|
+
/** Stop the turn once the current step is done. `reason` is shown to the operator. */
|
|
335
|
+
readonly halt?: { readonly reason: string }
|
|
336
|
+
/** A warning for the operator, reported through the logger. */
|
|
337
|
+
readonly notice?: string
|
|
338
|
+
}
|
|
339
|
+
|
|
270
340
|
export type PluginHookResult =
|
|
271
|
-
| {
|
|
341
|
+
| ({
|
|
342
|
+
action: 'continue'
|
|
343
|
+
permission?: PluginHookPermission
|
|
344
|
+
} & PluginHookNotes)
|
|
272
345
|
/**
|
|
273
346
|
* Add to what the model is told, without changing anything else.
|
|
274
347
|
*
|
|
@@ -278,8 +351,12 @@ export type PluginHookResult =
|
|
|
278
351
|
* it is rejected, because a tool result is not a place for context.
|
|
279
352
|
*/
|
|
280
353
|
| { action: 'annotate'; text: string }
|
|
281
|
-
| { action: 'skip'; reason: string }
|
|
282
|
-
| {
|
|
354
|
+
| ({ action: 'skip'; reason: string } & PluginHookNotes)
|
|
355
|
+
| ({
|
|
356
|
+
action: 'modify'
|
|
357
|
+
input: unknown
|
|
358
|
+
permission?: PluginHookPermission
|
|
359
|
+
} & PluginHookNotes)
|
|
283
360
|
| { action: 'error'; message: string }
|
|
284
361
|
| { action: 'retry' }
|
|
285
362
|
/**
|
|
@@ -333,9 +410,15 @@ export type PluginHookResultFor<E extends PluginHookEvent> = E extends 'user_pro
|
|
|
333
410
|
? Extract<PluginHookResult, { action: 'continue' | 'skip' | 'modify' | 'error' }>
|
|
334
411
|
: E extends 'post_tool_use'
|
|
335
412
|
? Extract<PluginHookResult, { action: 'continue' | 'replace' | 'retry' | 'error' }>
|
|
336
|
-
: E extends '
|
|
337
|
-
? Extract<PluginHookResult, { action: 'continue' }>
|
|
338
|
-
:
|
|
413
|
+
: E extends 'post_tool_use_failure'
|
|
414
|
+
? Extract<PluginHookResult, { action: 'continue' | 'error' }>
|
|
415
|
+
: E extends 'permission_request'
|
|
416
|
+
? Extract<PluginHookResult, { action: 'continue' | 'skip' }>
|
|
417
|
+
: E extends 'turn_end' | 'subagent_stop' | 'pre_compact'
|
|
418
|
+
? Extract<PluginHookResult, { action: 'continue' | 'skip' | 'error' }>
|
|
419
|
+
: E extends 'turn_interrupt' | 'session_start' | 'session_end' | 'notification'
|
|
420
|
+
? Extract<PluginHookResult, { action: 'continue' }>
|
|
421
|
+
: Extract<PluginHookResult, { action: 'continue' | 'error' }>
|
|
339
422
|
|
|
340
423
|
/** The event and its handler verdict stay correlated, including in hook arrays. */
|
|
341
424
|
export type PluginHookDefinition<E extends PluginHookEvent = PluginHookEvent> =
|
|
@@ -344,21 +427,21 @@ export type PluginHookDefinition<E extends PluginHookEvent = PluginHookEvent> =
|
|
|
344
427
|
readonly event: E
|
|
345
428
|
readonly handler: (context: PluginHookContext) => Promise<PluginHookResultFor<E>>
|
|
346
429
|
/**
|
|
347
|
-
* Lower
|
|
430
|
+
* Lower comes first in the answers. Default 100.
|
|
348
431
|
*
|
|
349
|
-
*
|
|
350
|
-
*
|
|
351
|
-
*
|
|
352
|
-
*
|
|
353
|
-
*
|
|
354
|
-
* whatever else stops the chain. A guard that fires depending on
|
|
355
|
-
* installation history is not a guard.
|
|
356
|
-
*
|
|
357
|
-
* Ties keep registration order, so plugins that never set a priority
|
|
358
|
-
* behave exactly as before. Convention: guards below 100, observers
|
|
359
|
-
* above.
|
|
432
|
+
* The hooks of one event start together and none waits for another, so
|
|
433
|
+
* priority no longer says who runs first; it says whose answer is read
|
|
434
|
+
* first. The first refusal in that order is the one the model is told,
|
|
435
|
+
* and of several rewrites the last in that order wins. Ties keep
|
|
436
|
+
* registration order. Convention: guards below 100, observers above.
|
|
360
437
|
*/
|
|
361
438
|
readonly priority?: number
|
|
439
|
+
/**
|
|
440
|
+
* Text for the operator's status line while this hook runs. Carried on
|
|
441
|
+
* the `plugin_hook_executing` event; a host that draws no status line
|
|
442
|
+
* ignores it.
|
|
443
|
+
*/
|
|
444
|
+
readonly statusMessage?: string
|
|
362
445
|
}
|
|
363
446
|
: never
|
|
364
447
|
|
|
@@ -45,4 +45,10 @@ export interface ProviderRequestErrorInit extends ProviderErrorInfo {
|
|
|
45
45
|
* still welcome; what is not welcome is a raw body passed straight in.
|
|
46
46
|
*/
|
|
47
47
|
readonly detail?: string
|
|
48
|
+
/**
|
|
49
|
+
* The provider's own `x-should-retry` verdict, when it sent one. Only `false`
|
|
50
|
+
* is acted on: a provider that says the same request must not be sent again
|
|
51
|
+
* is believed over the status code, so the retry loop leaves it alone.
|
|
52
|
+
*/
|
|
53
|
+
readonly shouldRetry?: boolean
|
|
48
54
|
}
|
|
@@ -54,6 +54,16 @@ export interface ProviderErrorInit {
|
|
|
54
54
|
readonly cause?: unknown
|
|
55
55
|
}
|
|
56
56
|
|
|
57
|
+
function shouldRetryHeader(link: Record<string, unknown>): false | undefined {
|
|
58
|
+
const headers = link.headers
|
|
59
|
+
if (!headers || typeof headers !== 'object') return undefined
|
|
60
|
+
const raw =
|
|
61
|
+
typeof (headers as Headers).get === 'function'
|
|
62
|
+
? (headers as Headers).get('x-should-retry')
|
|
63
|
+
: (headers as Record<string, unknown>)['x-should-retry']
|
|
64
|
+
return typeof raw === 'string' && raw.trim().toLowerCase() === 'false' ? false : undefined
|
|
65
|
+
}
|
|
66
|
+
|
|
57
67
|
/**
|
|
58
68
|
* A `retryable` flag declared anywhere on the cause chain.
|
|
59
69
|
*
|
|
@@ -72,6 +82,9 @@ export function declaredRetryable(err: unknown): boolean | undefined {
|
|
|
72
82
|
for (const link of causeChain(err)) {
|
|
73
83
|
const declared = link.retryable
|
|
74
84
|
if (typeof declared === 'boolean') return declared
|
|
85
|
+
// A raw vendor error that still carries its response headers: the
|
|
86
|
+
// provider's own `x-should-retry: false` is a first-hand "do not resend".
|
|
87
|
+
if (shouldRetryHeader(link) === false) return false
|
|
75
88
|
}
|
|
76
89
|
return undefined
|
|
77
90
|
}
|
|
@@ -224,6 +237,39 @@ function chainMessages(err: unknown): string[] {
|
|
|
224
237
|
return out
|
|
225
238
|
}
|
|
226
239
|
|
|
240
|
+
/**
|
|
241
|
+
* What a provider said when prompt plus requested output together passed the
|
|
242
|
+
* window: the prompt size, the output cap that was asked for, and the window.
|
|
243
|
+
*/
|
|
244
|
+
export interface OutputOverflowFigures {
|
|
245
|
+
readonly inputTokens: number
|
|
246
|
+
readonly maxTokens: number
|
|
247
|
+
readonly contextLimit: number
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Read the "input length and `max_tokens` exceed context limit: A + B > C"
|
|
252
|
+
* wording from a failure, anywhere on its cause chain.
|
|
253
|
+
*
|
|
254
|
+
* Different from a prompt that is too long on its own: here the prompt fits
|
|
255
|
+
* and only the requested output does not, so the remedy is a smaller
|
|
256
|
+
* `max_tokens`, not a smaller history. `undefined` means the failure does not
|
|
257
|
+
* carry those figures.
|
|
258
|
+
*/
|
|
259
|
+
export function readOutputOverflow(err: unknown): OutputOverflowFigures | undefined {
|
|
260
|
+
const pattern = /input length and `?max_tokens`? exceed context limit: (\d+) \+ (\d+) > (\d+)/i
|
|
261
|
+
for (const message of chainMessages(err)) {
|
|
262
|
+
const match = pattern.exec(message)
|
|
263
|
+
if (!match) continue
|
|
264
|
+
const inputTokens = Number.parseInt(match[1] ?? '', 10)
|
|
265
|
+
const maxTokens = Number.parseInt(match[2] ?? '', 10)
|
|
266
|
+
const contextLimit = Number.parseInt(match[3] ?? '', 10)
|
|
267
|
+
if (![inputTokens, maxTokens, contextLimit].every(Number.isFinite)) continue
|
|
268
|
+
return { inputTokens, maxTokens, contextLimit }
|
|
269
|
+
}
|
|
270
|
+
return undefined
|
|
271
|
+
}
|
|
272
|
+
|
|
227
273
|
/** Node/undici transport failures that mean "never reached the model". */
|
|
228
274
|
const NETWORK_ERRNOS: ReadonlySet<string> = new Set([
|
|
229
275
|
'ECONNRESET',
|
|
@@ -395,6 +441,7 @@ function classifyFromProviderRequestError(
|
|
|
395
441
|
providerId?: unknown
|
|
396
442
|
status?: unknown
|
|
397
443
|
retryAfterMs?: unknown
|
|
444
|
+
shouldRetry?: unknown
|
|
398
445
|
}
|
|
399
446
|
if (typeof candidate.kind !== 'string') return undefined
|
|
400
447
|
const mapped = KIND_TO_CODE[candidate.kind]
|
|
@@ -406,7 +453,8 @@ function classifyFromProviderRequestError(
|
|
|
406
453
|
return new ProviderError({
|
|
407
454
|
code: mapped.code,
|
|
408
455
|
message: err.message,
|
|
409
|
-
|
|
456
|
+
// The provider saying "do not resend" beats the kind's own verdict.
|
|
457
|
+
retryable: candidate.shouldRetry === false ? false : mapped.retryable,
|
|
410
458
|
cause: err,
|
|
411
459
|
...(typeof candidate.providerId === 'string'
|
|
412
460
|
? { providerId: candidate.providerId }
|
|
@@ -173,6 +173,12 @@ export interface ProviderRetryNotice {
|
|
|
173
173
|
readonly status?: number
|
|
174
174
|
/** The delay came from the server's own `Retry-After`, not backoff. */
|
|
175
175
|
readonly serverDirected: boolean
|
|
176
|
+
/**
|
|
177
|
+
* The failed attempt had already streamed text or reasoning, and the request
|
|
178
|
+
* is being sent again from the start. Whatever that attempt produced is void
|
|
179
|
+
* and the consumer must drop it before the next chunk.
|
|
180
|
+
*/
|
|
181
|
+
readonly restart?: boolean
|
|
176
182
|
}
|
|
177
183
|
|
|
178
184
|
/**
|
|
@@ -279,11 +279,17 @@ type CoreSessionEvent =
|
|
|
279
279
|
* `tool_result`, so it was refused wholesale rather than sent to
|
|
280
280
|
* a provider that rejects the pairing. A reducer bug, and one
|
|
281
281
|
* `findSafeTrimIndex` exists to prevent.
|
|
282
|
+
* - `breaker_open` — only with `compactionConfig.circuitBreaker`:
|
|
283
|
+
* three passes in a row failed, so automatic compaction is off for
|
|
284
|
+
* the rest of the turn. Sent once. `messages` is the live count.
|
|
285
|
+
* - `refilling` — only with `compactionConfig.circuitBreaker`: the
|
|
286
|
+
* context filled back up within three iterations of a compaction,
|
|
287
|
+
* three times in a row, and the turn is stopping. Sent once.
|
|
282
288
|
*/
|
|
283
|
-
cause: 'reducer_threw' | 'shed_nothing' | 'split_tool_pair'
|
|
289
|
+
cause: 'reducer_threw' | 'shed_nothing' | 'split_tool_pair' | 'breaker_open' | 'refilling'
|
|
284
290
|
/** Unchanged, and stated so a reader need not infer it. */
|
|
285
291
|
messages: number
|
|
286
|
-
/**
|
|
292
|
+
/** For `reducer_threw`, the reducer's message; for `breaker_open` and `refilling`, the one line to show. */
|
|
287
293
|
error?: string
|
|
288
294
|
}
|
|
289
295
|
| {
|
|
@@ -381,6 +387,11 @@ type CoreSessionEvent =
|
|
|
381
387
|
status?: number
|
|
382
388
|
/** The delay came from the server's own `Retry-After`. */
|
|
383
389
|
serverDirected: boolean
|
|
390
|
+
/**
|
|
391
|
+
* The failed attempt had already streamed text or reasoning and the
|
|
392
|
+
* request starts over: drop what this message showed so far.
|
|
393
|
+
*/
|
|
394
|
+
restart?: boolean
|
|
384
395
|
}
|
|
385
396
|
/**
|
|
386
397
|
* A member of the provider chain could not serve, and a later member has
|
|
@@ -987,6 +998,8 @@ type CoreSessionEvent =
|
|
|
987
998
|
turnId?: TurnId
|
|
988
999
|
pluginId: PluginId
|
|
989
1000
|
hookEvent: PluginHookEvent
|
|
1001
|
+
/** The hook's own text for a status line while it runs, when it declared one. */
|
|
1002
|
+
statusMessage?: string
|
|
990
1003
|
}
|
|
991
1004
|
| {
|
|
992
1005
|
type: 'plugin_hook_completed'
|
|
@@ -38,6 +38,11 @@ export type StopReason =
|
|
|
38
38
|
| 'step_refused'
|
|
39
39
|
/** The model never produced a valid structured output within its retries. */
|
|
40
40
|
| 'structured_output_failed'
|
|
41
|
+
/**
|
|
42
|
+
* The model's reply was cut off at its output limit more times in a row
|
|
43
|
+
* than `maxOutputContinuations` allows. Only with that option set.
|
|
44
|
+
*/
|
|
45
|
+
| 'output_limit'
|
|
41
46
|
/**
|
|
42
47
|
* A host reviewer kept rejecting the answer and the turn ran out of
|
|
43
48
|
* attempts.
|
package/src/types/tool/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChildProcess } from 'node:child_process'
|
|
1
2
|
import type { z } from 'zod'
|
|
2
3
|
import type { CodeNavigationProvider } from '../code-navigation/index.js'
|
|
3
4
|
// Type-only, and circular by design: a tool-result guardrail is described in
|
|
@@ -118,7 +119,24 @@ export interface BackgroundJobRegistryRef {
|
|
|
118
119
|
id: string
|
|
119
120
|
status: string
|
|
120
121
|
}
|
|
121
|
-
get(id: string): {
|
|
122
|
+
get(id: string): {
|
|
123
|
+
id: string
|
|
124
|
+
status: string
|
|
125
|
+
exitCode?: number
|
|
126
|
+
error?: string
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Take over a process the caller already started and is waiting on, so a
|
|
130
|
+
* foreground command that outran its timeout can keep running as a job
|
|
131
|
+
* instead of being killed. Optional: a host without it (or a sandboxed
|
|
132
|
+
* turn) keeps the kill. Throws when the owner is at its job cap.
|
|
133
|
+
*/
|
|
134
|
+
adopt?(params: {
|
|
135
|
+
command: string
|
|
136
|
+
child: ChildProcess
|
|
137
|
+
workingDirectory?: string
|
|
138
|
+
initialOutput?: readonly { readonly stream: 'stdout' | 'stderr'; readonly text: string }[]
|
|
139
|
+
}): { id: string; status: string }
|
|
122
140
|
/**
|
|
123
141
|
* Resolves once the process exists or failed to start (`error` says why).
|
|
124
142
|
* Optional: a host that cannot tell may omit it, and `bash` then replies
|
|
@@ -483,15 +501,39 @@ export interface ToolContext {
|
|
|
483
501
|
*/
|
|
484
502
|
web?: {
|
|
485
503
|
readonly fetch?: {
|
|
486
|
-
fetch(request: {
|
|
504
|
+
fetch(request: {
|
|
505
|
+
url: string
|
|
506
|
+
signal?: AbortSignal
|
|
507
|
+
/** `same-host` asks for a redirect to another site to be handed back, not followed. */
|
|
508
|
+
redirects?: 'follow' | 'same-host'
|
|
509
|
+
headers?: Readonly<Record<string, string>>
|
|
510
|
+
}): Promise<{
|
|
487
511
|
url: string
|
|
488
512
|
status: number
|
|
489
513
|
contentType?: string
|
|
490
514
|
body: string
|
|
491
515
|
truncated: boolean
|
|
492
516
|
redirects: readonly string[]
|
|
517
|
+
/** A redirect that was not followed; `body` is then empty. */
|
|
518
|
+
redirect?: { url: string; status: number }
|
|
493
519
|
}>
|
|
494
520
|
}
|
|
521
|
+
/**
|
|
522
|
+
* Answers a prompt from a page with a small model. Optional: without
|
|
523
|
+
* it `web_fetch` returns the page as markdown instead of an answer.
|
|
524
|
+
*/
|
|
525
|
+
readonly extract?: {
|
|
526
|
+
extract(request: {
|
|
527
|
+
url: string
|
|
528
|
+
prompt: string
|
|
529
|
+
content: string
|
|
530
|
+
instruction: string
|
|
531
|
+
body: string
|
|
532
|
+
signal?: AbortSignal
|
|
533
|
+
sessionId: string
|
|
534
|
+
turnId: string
|
|
535
|
+
}): Promise<string | undefined>
|
|
536
|
+
}
|
|
495
537
|
readonly search?: {
|
|
496
538
|
search(request: {
|
|
497
539
|
query: string
|
|
@@ -1103,6 +1145,15 @@ export interface ToolDefinition<TInput = unknown> extends ToolPresentation<TInpu
|
|
|
1103
1145
|
* their external effects have stopped, and does not imply success.
|
|
1104
1146
|
*/
|
|
1105
1147
|
executionBarrier?: boolean
|
|
1148
|
+
/**
|
|
1149
|
+
* The tool bounds its own output (a paged read, say), so the turn's default
|
|
1150
|
+
* per-result cap does not apply to it and its result is never replaced to
|
|
1151
|
+
* fit the per-message budget.
|
|
1152
|
+
*
|
|
1153
|
+
* Only the DEFAULT is lifted. A host that sets `maxToolOutputChars`
|
|
1154
|
+
* explicitly still bounds this tool's result by it.
|
|
1155
|
+
*/
|
|
1156
|
+
selfLimitingOutput?: boolean
|
|
1106
1157
|
}
|
|
1107
1158
|
|
|
1108
1159
|
/**
|
package/src/utils/backoff.ts
CHANGED
|
@@ -43,6 +43,27 @@ export function backoffWithJitter(
|
|
|
43
43
|
return Math.round(random() * exponential)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Exponential backoff that only ever adds jitter: the delay is the exponential
|
|
48
|
+
* step plus up to `ratio` of itself (a quarter by default), never less.
|
|
49
|
+
*
|
|
50
|
+
* Full jitter spreads a herd better but can answer a failure after a few
|
|
51
|
+
* milliseconds, which is a poor way to treat a server that just said it is
|
|
52
|
+
* struggling. This curve keeps the floor of every step, so a person watching a
|
|
53
|
+
* countdown sees a wait that grows the way the numbers on screen say it does.
|
|
54
|
+
*
|
|
55
|
+
* `attempt` is 0-based: attempt 0 draws from `[initialDelayMs, initialDelayMs * (1 + ratio)]`.
|
|
56
|
+
*/
|
|
57
|
+
export function backoffProportional(
|
|
58
|
+
attempt: number,
|
|
59
|
+
policy: BackoffPolicy,
|
|
60
|
+
random: () => number = Math.random,
|
|
61
|
+
ratio = 0.25,
|
|
62
|
+
): number {
|
|
63
|
+
const exponential = Math.min(policy.initialDelayMs * 2 ** attempt, policy.maxDelayMs)
|
|
64
|
+
return Math.round(exponential + random() * ratio * exponential)
|
|
65
|
+
}
|
|
66
|
+
|
|
46
67
|
/**
|
|
47
68
|
* Sleep, unless the signal says not to.
|
|
48
69
|
*
|