@namzu/sdk 51.1.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 +100 -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/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/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/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/errors.d.ts +19 -0
- package/dist/types/provider/errors.d.ts.map +1 -1
- package/dist/types/provider/errors.js +24 -0
- package/dist/types/provider/errors.js.map +1 -1
- package/dist/types/session/events.d.ts +10 -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/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/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/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/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/errors.ts +33 -0
- package/src/types/session/events.ts +10 -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
|
@@ -20,13 +20,24 @@ import { generateToolCallId } from '../../utils/id.js';
|
|
|
20
20
|
import { compressShellOutput } from '../../utils/shell-compress.js';
|
|
21
21
|
import { parseStructuredResultJson } from '../../utils/structured-result-json.js';
|
|
22
22
|
import { bindOwner } from '../jobs/registry.js';
|
|
23
|
-
import { formatFailedToolOutput, isUnregistered, prepareDirectCall, runPreToolHook, unknownToolMessage, } from './executor/tool-call-admission.js';
|
|
23
|
+
import { formatFailedToolOutput, hookNote, isUnregistered, prepareDirectCall, runPreToolHook, unknownToolMessage, } from './executor/tool-call-admission.js';
|
|
24
24
|
import { describeVisibleFileEvidence } from './file-evidence-context.js';
|
|
25
25
|
import { seedObservationLedger } from './file-evidence-seed.js';
|
|
26
26
|
import { DEFAULT_TOOL_RESULT_GUARDRAILS } from './guardrail-presets.js';
|
|
27
|
+
import { declaredWriteEscalation, shellEscalations } from './path-escalation.js';
|
|
27
28
|
import { savedPresentation } from './saved-presentation.js';
|
|
28
29
|
import { ToolCallBudget, assertMaxToolCalls } from './tool-call-budget.js';
|
|
29
|
-
import { DEFAULT_MAX_TOOL_OUTPUT_CHARS, applyToolOutputBudget, describeDroppedContent, measureContentBytes, } from './tool-output-budget.js';
|
|
30
|
+
import { DEFAULT_MAX_TOOL_OUTPUT_CHARS, DEFAULT_MAX_TOOL_OUTPUT_CHARS_PER_MESSAGE, applyToolOutputBudget, describeDroppedContent, fitResultsToMessageBudget, measureContentBytes, } from './tool-output-budget.js';
|
|
31
|
+
/**
|
|
32
|
+
* A nested call cannot open a review from inside the tool that issued it, so
|
|
33
|
+
* a hook that asked for a person to approve it can only be answered with a
|
|
34
|
+
* refusal. Silence would run the call the hook wanted a person to see.
|
|
35
|
+
*/
|
|
36
|
+
function askedNestedMessage(toolName, outcome) {
|
|
37
|
+
if (outcome.kind !== 'continue' || outcome.permission?.decision !== 'ask')
|
|
38
|
+
return undefined;
|
|
39
|
+
return `Blocked: a hook asked that a person approve "${toolName}", and an approval cannot be requested from inside another tool. Call it directly.`;
|
|
40
|
+
}
|
|
30
41
|
function assertUniqueToolCallIds(toolCalls) {
|
|
31
42
|
const seen = new Set();
|
|
32
43
|
for (const [index, toolCall] of toolCalls.entries()) {
|
|
@@ -548,12 +559,67 @@ export class ToolExecutor {
|
|
|
548
559
|
tool.sandboxEscapeArgument !== undefined &&
|
|
549
560
|
input[tool.sandboxEscapeArgument] === true;
|
|
550
561
|
const unknownProgram = this.unknownProgramOf(tool, input, sandboxed);
|
|
551
|
-
|
|
562
|
+
const reaches = await this.pathEscalationsOf(tool, input, sandboxed);
|
|
563
|
+
if (reaches.outsidePaths.length > 0) {
|
|
564
|
+
outsidePaths = [...new Set([...(outsidePaths ?? []), ...reaches.outsidePaths])];
|
|
565
|
+
}
|
|
566
|
+
const protectedPaths = reaches.protectedPaths;
|
|
567
|
+
const removal = reaches.dangerousRemoval;
|
|
568
|
+
if (!outsidePaths &&
|
|
569
|
+
!sandboxEscape &&
|
|
570
|
+
unknownProgram === undefined &&
|
|
571
|
+
protectedPaths.length === 0 &&
|
|
572
|
+
removal === undefined) {
|
|
552
573
|
return undefined;
|
|
574
|
+
}
|
|
553
575
|
return {
|
|
554
576
|
...(outsidePaths ? { outsidePaths } : {}),
|
|
555
577
|
...(sandboxEscape ? { sandboxEscape: true } : {}),
|
|
556
578
|
...(unknownProgram !== undefined ? { unknownProgram } : {}),
|
|
579
|
+
...(protectedPaths.length > 0 ? { protectedPaths } : {}),
|
|
580
|
+
...(removal !== undefined ? { dangerousRemoval: removal } : {}),
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
/**
|
|
584
|
+
* What the call's own arguments write or remove that no mode may approve in
|
|
585
|
+
* advance, and, for a shell line, the paths outside the roots it names.
|
|
586
|
+
*
|
|
587
|
+
* The protected-path and removal floors hold whether or not the turn reviews
|
|
588
|
+
* outside paths and whether or not it is sandboxed: they are about what the
|
|
589
|
+
* write plants and what the removal destroys, not about where the turn is
|
|
590
|
+
* allowed to look. The outside-path half follows `outsideRootAccess`, as the
|
|
591
|
+
* file tools' own does.
|
|
592
|
+
*/
|
|
593
|
+
async pathEscalationsOf(tool, input, sandboxed) {
|
|
594
|
+
const roots = toolRoots(this.config);
|
|
595
|
+
const protectedPaths = [];
|
|
596
|
+
let outsidePaths = [];
|
|
597
|
+
let removal;
|
|
598
|
+
if (tool.pathArgument !== undefined && tool.isReadOnly?.(input) !== true) {
|
|
599
|
+
const value = input[tool.pathArgument];
|
|
600
|
+
if (typeof value === 'string') {
|
|
601
|
+
const hit = await declaredWriteEscalation(roots, value);
|
|
602
|
+
if (hit !== undefined)
|
|
603
|
+
protectedPaths.push(hit);
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
if (tool.commandArgument !== undefined) {
|
|
607
|
+
const line = input[tool.commandArgument];
|
|
608
|
+
if (typeof line === 'string') {
|
|
609
|
+
const dialect = tool.commandDialect?.({ sandboxed }) ?? 'sh';
|
|
610
|
+
const found = await shellEscalations(line, dialect, {
|
|
611
|
+
roots,
|
|
612
|
+
reviewOutside: this.config.outsideRootAccess === 'review' && !sandboxed,
|
|
613
|
+
});
|
|
614
|
+
protectedPaths.push(...found.protectedPaths);
|
|
615
|
+
outsidePaths = found.outsidePaths;
|
|
616
|
+
removal = found.dangerousRemoval;
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return {
|
|
620
|
+
outsidePaths,
|
|
621
|
+
protectedPaths: [...new Set(protectedPaths)],
|
|
622
|
+
...(removal !== undefined ? { dangerousRemoval: removal } : {}),
|
|
557
623
|
};
|
|
558
624
|
}
|
|
559
625
|
/**
|
|
@@ -602,11 +668,13 @@ export class ToolExecutor {
|
|
|
602
668
|
.filter((call) => call.kind !== 'synthetic')
|
|
603
669
|
.map((call) => {
|
|
604
670
|
const escalation = escalations.get(call.toolCall.id);
|
|
671
|
+
const hookPermission = call.hook?.permission;
|
|
605
672
|
return {
|
|
606
673
|
id: call.toolCall.id,
|
|
607
674
|
name: call.toolName,
|
|
608
675
|
input: call.input,
|
|
609
676
|
...(escalation ? { escalation } : {}),
|
|
677
|
+
...(hookPermission ? { hookPermission } : {}),
|
|
610
678
|
};
|
|
611
679
|
});
|
|
612
680
|
const batch = Object.freeze({
|
|
@@ -832,6 +900,7 @@ export class ToolExecutor {
|
|
|
832
900
|
isError: true,
|
|
833
901
|
});
|
|
834
902
|
}
|
|
903
|
+
this.fitBatchToMessageBudget(results);
|
|
835
904
|
// isError and rich content were computed and then discarded here: the
|
|
836
905
|
// tuple narrowed to {toolCallId, output} BEFORE the message was built,
|
|
837
906
|
// so the failure signal and any image block were structurally lost at
|
|
@@ -839,6 +908,46 @@ export class ToolExecutor {
|
|
|
839
908
|
const messages = results.map((r) => createToolMessage(r.content ?? r.output, r.toolCallId, r.isError, r.revealedTools));
|
|
840
909
|
return { messages, results, observations };
|
|
841
910
|
}
|
|
911
|
+
/**
|
|
912
|
+
* Hold the batch's combined result text under the per-message cap.
|
|
913
|
+
*
|
|
914
|
+
* Runs once, on the settled batch and before the results become history
|
|
915
|
+
* messages, so what it writes is what every later request replays.
|
|
916
|
+
*/
|
|
917
|
+
fitBatchToMessageBudget(results) {
|
|
918
|
+
const maxChars = this.config.maxToolOutputCharsPerMessage ?? DEFAULT_MAX_TOOL_OUTPUT_CHARS_PER_MESSAGE;
|
|
919
|
+
const replacements = fitResultsToMessageBudget(results.map((r) => ({
|
|
920
|
+
toolCallId: r.toolCallId,
|
|
921
|
+
toolName: r.toolName,
|
|
922
|
+
output: r.output,
|
|
923
|
+
// A result carrying rich content or a structured-output copy is
|
|
924
|
+
// not text the model reads alone, and a self-limiting tool has
|
|
925
|
+
// already decided its own size.
|
|
926
|
+
replaceable: r.content === undefined &&
|
|
927
|
+
r.structuredResultJson === undefined &&
|
|
928
|
+
this.config.tools.get(r.toolName)?.selfLimitingOutput !== true,
|
|
929
|
+
})), {
|
|
930
|
+
maxChars,
|
|
931
|
+
spillDir: this.outputDirectory(),
|
|
932
|
+
onError: (message) => this.log.warn('Failed to retain a tool output replaced for the message budget', {
|
|
933
|
+
[NAMZU.TURN_ID]: this.config.turnId,
|
|
934
|
+
'exception.message': message,
|
|
935
|
+
}),
|
|
936
|
+
});
|
|
937
|
+
if (replacements.size === 0)
|
|
938
|
+
return;
|
|
939
|
+
for (const [i, r] of results.entries()) {
|
|
940
|
+
const replacement = replacements.get(r.toolCallId);
|
|
941
|
+
if (replacement === undefined)
|
|
942
|
+
continue;
|
|
943
|
+
results[i] = { ...r, output: replacement.output };
|
|
944
|
+
}
|
|
945
|
+
this.log.warn("Tool results exceeded the message's combined budget", {
|
|
946
|
+
[NAMZU.TURN_ID]: this.config.turnId,
|
|
947
|
+
'namzu.runtime.replaced_count': replacements.size,
|
|
948
|
+
'namzu.runtime.message_budget_chars': maxChars,
|
|
949
|
+
});
|
|
950
|
+
}
|
|
842
951
|
/**
|
|
843
952
|
* Run a tool on behalf of another tool, and put it on the record.
|
|
844
953
|
*
|
|
@@ -1236,7 +1345,9 @@ export class ToolExecutor {
|
|
|
1236
1345
|
let input;
|
|
1237
1346
|
let prepared;
|
|
1238
1347
|
let inputFailure;
|
|
1348
|
+
let preparedHookContext;
|
|
1239
1349
|
if (preparedCall?.kind === 'ready' || preparedCall?.kind === 'legacy') {
|
|
1350
|
+
preparedHookContext = preparedCall.hook?.context;
|
|
1240
1351
|
input = preparedCall.input;
|
|
1241
1352
|
prepared = preparedCall.kind === 'ready' ? preparedCall.prepared : undefined;
|
|
1242
1353
|
if (preparedCall.kind === 'legacy')
|
|
@@ -1262,6 +1373,7 @@ export class ToolExecutor {
|
|
|
1262
1373
|
return this.recordSyntheticPreparation(admitted);
|
|
1263
1374
|
toolName = admitted.toolName;
|
|
1264
1375
|
input = admitted.input;
|
|
1376
|
+
preparedHookContext = admitted.hook?.context;
|
|
1265
1377
|
prepared = admitted.kind === 'ready' ? admitted.prepared : undefined;
|
|
1266
1378
|
if (admitted.kind === 'legacy')
|
|
1267
1379
|
inputFailure = admitted.inputFailure;
|
|
@@ -1460,7 +1572,10 @@ export class ToolExecutor {
|
|
|
1460
1572
|
];
|
|
1461
1573
|
}
|
|
1462
1574
|
}
|
|
1463
|
-
|
|
1575
|
+
// A tool that bounds its own output is exempt from the DEFAULT per-result
|
|
1576
|
+
// cap only; a host that set the cap explicitly still gets it.
|
|
1577
|
+
const maxToolOutputChars = this.config.maxToolOutputChars ??
|
|
1578
|
+
(executedDefinition?.selfLimitingOutput === true ? 0 : DEFAULT_MAX_TOOL_OUTPUT_CHARS);
|
|
1464
1579
|
const sourceOutput = output;
|
|
1465
1580
|
// This owner-bound channel follows the selected receipt after both result
|
|
1466
1581
|
// screening and post-tool replacement. ToolResult.data and raw input can
|
|
@@ -1511,12 +1626,25 @@ export class ToolExecutor {
|
|
|
1511
1626
|
});
|
|
1512
1627
|
}
|
|
1513
1628
|
output = budgeted.output;
|
|
1514
|
-
|
|
1629
|
+
let modelContent = selectedContent === undefined
|
|
1515
1630
|
? undefined
|
|
1516
1631
|
: this.budgetContent(selectedContent, toolName, toolCall.id, {
|
|
1517
1632
|
sourceOutput,
|
|
1518
1633
|
budgeted,
|
|
1519
1634
|
});
|
|
1635
|
+
// What hooks said about this call rides with its result, in the model's
|
|
1636
|
+
// receipt and the host's alike, framed as a hook's words. Added after
|
|
1637
|
+
// the output budget so a bounded result is never trimmed to make room
|
|
1638
|
+
// for it; the note has its own bound (`hookNote`).
|
|
1639
|
+
const hookTexts = [preparedHookContext, post.context].filter((text) => text !== undefined && text.length > 0);
|
|
1640
|
+
if (hookTexts.length > 0) {
|
|
1641
|
+
const note = hookNote(hookTexts);
|
|
1642
|
+
output = `${output}\n\n${note}`;
|
|
1643
|
+
if (typeof modelContent === 'string')
|
|
1644
|
+
modelContent = `${modelContent}\n\n${note}`;
|
|
1645
|
+
else if (modelContent)
|
|
1646
|
+
modelContent = [...modelContent, { type: 'text', text: note }];
|
|
1647
|
+
}
|
|
1520
1648
|
// A failed call, or an override that says the call failed. A `replace`
|
|
1521
1649
|
// says the opposite, and reading it as a failure is what made redaction
|
|
1522
1650
|
// unusable: the model was told a successful call had gone wrong, and
|
|
@@ -1820,8 +1948,21 @@ export class ToolExecutor {
|
|
|
1820
1948
|
emitEvent: this.emitEvent,
|
|
1821
1949
|
log: this.log,
|
|
1822
1950
|
allowedTools: this.effectiveAllowedTools(),
|
|
1951
|
+
requestHalt: (reason) => this.requestHalt(reason),
|
|
1823
1952
|
};
|
|
1824
1953
|
}
|
|
1954
|
+
/** Why a hook asked for the turn to stop, until the iteration loop reads it. */
|
|
1955
|
+
haltReason;
|
|
1956
|
+
/** The first request wins: a later hook does not rewrite why the turn stopped. */
|
|
1957
|
+
requestHalt(reason) {
|
|
1958
|
+
this.haltReason ??= reason;
|
|
1959
|
+
}
|
|
1960
|
+
/** Read and clear a hook's request to stop the turn. */
|
|
1961
|
+
takeHalt() {
|
|
1962
|
+
const reason = this.haltReason;
|
|
1963
|
+
this.haltReason = undefined;
|
|
1964
|
+
return reason;
|
|
1965
|
+
}
|
|
1825
1966
|
async prepareNestedCall(toolName, input, signal) {
|
|
1826
1967
|
signal.throwIfAborted();
|
|
1827
1968
|
const prepare = this.config.tools.prepareExecutionAsync ?? this.config.tools.prepareExecution;
|
|
@@ -1845,6 +1986,14 @@ export class ToolExecutor {
|
|
|
1845
1986
|
...(preOutcome.kind === 'skip' ? { skipped: true } : {}),
|
|
1846
1987
|
};
|
|
1847
1988
|
}
|
|
1989
|
+
const nestedAsk = askedNestedMessage(toolName, preOutcome);
|
|
1990
|
+
if (nestedAsk)
|
|
1991
|
+
return {
|
|
1992
|
+
kind: 'synthetic',
|
|
1993
|
+
input: preOutcome.input,
|
|
1994
|
+
message: nestedAsk,
|
|
1995
|
+
isError: true,
|
|
1996
|
+
};
|
|
1848
1997
|
return { kind: 'legacy', input: preOutcome.input };
|
|
1849
1998
|
}
|
|
1850
1999
|
let preparation;
|
|
@@ -1885,6 +2034,15 @@ export class ToolExecutor {
|
|
|
1885
2034
|
...(preOutcome.kind === 'skip' ? { skipped: true } : {}),
|
|
1886
2035
|
};
|
|
1887
2036
|
}
|
|
2037
|
+
const nestedAsk = askedNestedMessage(toolName, preOutcome);
|
|
2038
|
+
if (nestedAsk) {
|
|
2039
|
+
return {
|
|
2040
|
+
kind: 'synthetic',
|
|
2041
|
+
input: preOutcome.input,
|
|
2042
|
+
message: nestedAsk,
|
|
2043
|
+
isError: true,
|
|
2044
|
+
};
|
|
2045
|
+
}
|
|
1888
2046
|
if (!preOutcome.modified) {
|
|
1889
2047
|
return {
|
|
1890
2048
|
kind: 'ready',
|
|
@@ -1937,6 +2095,7 @@ export class ToolExecutor {
|
|
|
1937
2095
|
/**
|
|
1938
2096
|
* @returns `override` — text replacing the tool's output, or `null`.
|
|
1939
2097
|
* `retry` — the hook asked for the tool to run again.
|
|
2098
|
+
* `context` — what the hooks want the model to read beside the result.
|
|
1940
2099
|
*/
|
|
1941
2100
|
async runPostToolHook(toolName, input, toolResult) {
|
|
1942
2101
|
if (!this.config.pluginManager)
|
|
@@ -1951,6 +2110,22 @@ export class ToolExecutor {
|
|
|
1951
2110
|
toolResult,
|
|
1952
2111
|
signal: this.config.abortSignal,
|
|
1953
2112
|
}, this.emitEvent);
|
|
2113
|
+
// A failed call is announced a second time, by name, so a hook that
|
|
2114
|
+
// only cares about failures need not read every result. After
|
|
2115
|
+
// `post_tool_use`, so the existing hooks see exactly what they saw.
|
|
2116
|
+
if (!toolResult.success) {
|
|
2117
|
+
results = [
|
|
2118
|
+
...results,
|
|
2119
|
+
...(await this.config.pluginManager.executeHooks('post_tool_use_failure', {
|
|
2120
|
+
sessionId: this.config.sessionId,
|
|
2121
|
+
turnId: this.config.turnId,
|
|
2122
|
+
toolName,
|
|
2123
|
+
toolInput: input,
|
|
2124
|
+
toolResult,
|
|
2125
|
+
signal: this.config.abortSignal,
|
|
2126
|
+
}, this.emitEvent)),
|
|
2127
|
+
];
|
|
2128
|
+
}
|
|
1954
2129
|
}
|
|
1955
2130
|
catch (error) {
|
|
1956
2131
|
if (!this.config.abortSignal.aborted)
|
|
@@ -1969,9 +2144,14 @@ export class ToolExecutor {
|
|
|
1969
2144
|
}
|
|
1970
2145
|
let override = null;
|
|
1971
2146
|
let retry = false;
|
|
2147
|
+
const contexts = [];
|
|
1972
2148
|
for (const result of results) {
|
|
1973
2149
|
switch (result.action) {
|
|
1974
2150
|
case 'continue':
|
|
2151
|
+
if (result.context)
|
|
2152
|
+
contexts.push(result.context);
|
|
2153
|
+
if (result.halt)
|
|
2154
|
+
this.requestHalt(result.halt.reason);
|
|
1975
2155
|
continue;
|
|
1976
2156
|
case 'error':
|
|
1977
2157
|
override = { output: `Error: ${result.message}`, isError: true };
|
|
@@ -2005,7 +2185,11 @@ export class ToolExecutor {
|
|
|
2005
2185
|
}
|
|
2006
2186
|
}
|
|
2007
2187
|
}
|
|
2008
|
-
return {
|
|
2188
|
+
return {
|
|
2189
|
+
override,
|
|
2190
|
+
retry,
|
|
2191
|
+
...(contexts.length > 0 ? { context: contexts.join('\n') } : {}),
|
|
2192
|
+
};
|
|
2009
2193
|
}
|
|
2010
2194
|
/**
|
|
2011
2195
|
* Answer a tool call that policy or a human refused, without executing
|