agentfootprint 9.20.0 → 9.22.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/AGENTS.md +1 -1
- package/CLAUDE.md +1 -1
- package/README.md +1 -0
- package/ai-instructions/claude-code/SKILL.md +1 -1
- package/dist/artifacts/capability.js +131 -0
- package/dist/artifacts/capability.js.map +1 -0
- package/dist/artifacts/fileArtifacts.js +230 -0
- package/dist/artifacts/fileArtifacts.js.map +1 -0
- package/dist/artifacts/inMemoryArtifacts.js +165 -0
- package/dist/artifacts/inMemoryArtifacts.js.map +1 -0
- package/dist/artifacts/index.js +47 -0
- package/dist/artifacts/index.js.map +1 -0
- package/dist/artifacts/minting.js +79 -0
- package/dist/artifacts/minting.js.map +1 -0
- package/dist/artifacts/naming.js +64 -0
- package/dist/artifacts/naming.js.map +1 -0
- package/dist/artifacts/payload.js +113 -0
- package/dist/artifacts/payload.js.map +1 -0
- package/dist/artifacts/placement.js +86 -0
- package/dist/artifacts/placement.js.map +1 -0
- package/dist/artifacts/present.js +98 -0
- package/dist/artifacts/present.js.map +1 -0
- package/dist/artifacts/retention.js +121 -0
- package/dist/artifacts/retention.js.map +1 -0
- package/dist/artifacts/sqliteArtifacts.js +338 -0
- package/dist/artifacts/sqliteArtifacts.js.map +1 -0
- package/dist/artifacts/types.js +96 -0
- package/dist/artifacts/types.js.map +1 -0
- package/dist/artifacts/wants.js +240 -0
- package/dist/artifacts/wants.js.map +1 -0
- package/dist/core/Agent.js +73 -2
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/agent/buildToolRegistry.js +30 -1
- package/dist/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/core/agent/presentTool.js +59 -0
- package/dist/core/agent/presentTool.js.map +1 -0
- package/dist/core/agent/stages/toolCalls.js +347 -8
- package/dist/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/core/codeRunnerTool.js +89 -3
- package/dist/core/codeRunnerTool.js.map +1 -1
- package/dist/core/tools.js +7 -0
- package/dist/core/tools.js.map +1 -1
- package/dist/esm/adapters/types.d.ts +17 -1
- package/dist/esm/artifacts/capability.d.ts +93 -0
- package/dist/esm/artifacts/capability.js +126 -0
- package/dist/esm/artifacts/capability.js.map +1 -0
- package/dist/esm/artifacts/fileArtifacts.d.ts +58 -0
- package/dist/esm/artifacts/fileArtifacts.js +225 -0
- package/dist/esm/artifacts/fileArtifacts.js.map +1 -0
- package/dist/esm/artifacts/inMemoryArtifacts.d.ts +54 -0
- package/dist/esm/artifacts/inMemoryArtifacts.js +161 -0
- package/dist/esm/artifacts/inMemoryArtifacts.js.map +1 -0
- package/dist/esm/artifacts/index.d.ts +21 -0
- package/dist/esm/artifacts/index.js +21 -0
- package/dist/esm/artifacts/index.js.map +1 -0
- package/dist/esm/artifacts/minting.d.ts +29 -0
- package/dist/esm/artifacts/minting.js +75 -0
- package/dist/esm/artifacts/minting.js.map +1 -0
- package/dist/esm/artifacts/naming.d.ts +36 -0
- package/dist/esm/artifacts/naming.js +59 -0
- package/dist/esm/artifacts/naming.js.map +1 -0
- package/dist/esm/artifacts/payload.d.ts +43 -0
- package/dist/esm/artifacts/payload.js +105 -0
- package/dist/esm/artifacts/payload.js.map +1 -0
- package/dist/esm/artifacts/placement.d.ts +74 -0
- package/dist/esm/artifacts/placement.js +79 -0
- package/dist/esm/artifacts/placement.js.map +1 -0
- package/dist/esm/artifacts/present.d.ts +77 -0
- package/dist/esm/artifacts/present.js +94 -0
- package/dist/esm/artifacts/present.js.map +1 -0
- package/dist/esm/artifacts/retention.d.ts +72 -0
- package/dist/esm/artifacts/retention.js +115 -0
- package/dist/esm/artifacts/retention.js.map +1 -0
- package/dist/esm/artifacts/sqliteArtifacts.d.ts +90 -0
- package/dist/esm/artifacts/sqliteArtifacts.js +333 -0
- package/dist/esm/artifacts/sqliteArtifacts.js.map +1 -0
- package/dist/esm/artifacts/types.d.ts +220 -0
- package/dist/esm/artifacts/types.js +90 -0
- package/dist/esm/artifacts/types.js.map +1 -0
- package/dist/esm/artifacts/wants.d.ts +104 -0
- package/dist/esm/artifacts/wants.js +234 -0
- package/dist/esm/artifacts/wants.js.map +1 -0
- package/dist/esm/core/Agent.d.ts +8 -2
- package/dist/esm/core/Agent.js +73 -2
- package/dist/esm/core/Agent.js.map +1 -1
- package/dist/esm/core/agent/buildToolRegistry.d.ts +11 -1
- package/dist/esm/core/agent/buildToolRegistry.js +30 -1
- package/dist/esm/core/agent/buildToolRegistry.js.map +1 -1
- package/dist/esm/core/agent/presentTool.d.ts +22 -0
- package/dist/esm/core/agent/presentTool.js +55 -0
- package/dist/esm/core/agent/presentTool.js.map +1 -0
- package/dist/esm/core/agent/stages/toolCalls.d.ts +22 -0
- package/dist/esm/core/agent/stages/toolCalls.js +347 -8
- package/dist/esm/core/agent/stages/toolCalls.js.map +1 -1
- package/dist/esm/core/agent/types.d.ts +46 -0
- package/dist/esm/core/codeRunnerTool.js +89 -3
- package/dist/esm/core/codeRunnerTool.js.map +1 -1
- package/dist/esm/core/tools.d.ts +49 -0
- package/dist/esm/core/tools.js +7 -0
- package/dist/esm/core/tools.js.map +1 -1
- package/dist/esm/events/dispatcher.d.ts +1 -1
- package/dist/esm/events/dispatcher.js.map +1 -1
- package/dist/esm/events/payloads.d.ts +83 -0
- package/dist/esm/events/registry.d.ts +13 -1
- package/dist/esm/events/registry.js +12 -0
- package/dist/esm/events/registry.js.map +1 -1
- package/dist/esm/index.d.ts +3 -1
- package/dist/esm/index.js +17 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/mcp/mcpServe.js +16 -0
- package/dist/esm/lib/mcp/mcpServe.js.map +1 -1
- package/dist/esm/lib/trace-toolpack/traceToolpack.js +4 -0
- package/dist/esm/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/esm/recorders/core/ArtifactsRecorder.d.ts +22 -0
- package/dist/esm/recorders/core/ArtifactsRecorder.js +27 -0
- package/dist/esm/recorders/core/ArtifactsRecorder.js.map +1 -0
- package/dist/events/dispatcher.js.map +1 -1
- package/dist/events/registry.js +12 -0
- package/dist/events/registry.js.map +1 -1
- package/dist/index.js +43 -8
- package/dist/index.js.map +1 -1
- package/dist/lib/mcp/mcpServe.js +16 -0
- package/dist/lib/mcp/mcpServe.js.map +1 -1
- package/dist/lib/trace-toolpack/traceToolpack.js +4 -0
- package/dist/lib/trace-toolpack/traceToolpack.js.map +1 -1
- package/dist/recorders/core/ArtifactsRecorder.js +31 -0
- package/dist/recorders/core/ArtifactsRecorder.js.map +1 -0
- package/dist/types/adapters/types.d.ts +17 -1
- package/dist/types/adapters/types.d.ts.map +1 -1
- package/dist/types/artifacts/capability.d.ts +94 -0
- package/dist/types/artifacts/capability.d.ts.map +1 -0
- package/dist/types/artifacts/fileArtifacts.d.ts +59 -0
- package/dist/types/artifacts/fileArtifacts.d.ts.map +1 -0
- package/dist/types/artifacts/inMemoryArtifacts.d.ts +55 -0
- package/dist/types/artifacts/inMemoryArtifacts.d.ts.map +1 -0
- package/dist/types/artifacts/index.d.ts +22 -0
- package/dist/types/artifacts/index.d.ts.map +1 -0
- package/dist/types/artifacts/minting.d.ts +30 -0
- package/dist/types/artifacts/minting.d.ts.map +1 -0
- package/dist/types/artifacts/naming.d.ts +37 -0
- package/dist/types/artifacts/naming.d.ts.map +1 -0
- package/dist/types/artifacts/payload.d.ts +44 -0
- package/dist/types/artifacts/payload.d.ts.map +1 -0
- package/dist/types/artifacts/placement.d.ts +75 -0
- package/dist/types/artifacts/placement.d.ts.map +1 -0
- package/dist/types/artifacts/present.d.ts +78 -0
- package/dist/types/artifacts/present.d.ts.map +1 -0
- package/dist/types/artifacts/retention.d.ts +73 -0
- package/dist/types/artifacts/retention.d.ts.map +1 -0
- package/dist/types/artifacts/sqliteArtifacts.d.ts +91 -0
- package/dist/types/artifacts/sqliteArtifacts.d.ts.map +1 -0
- package/dist/types/artifacts/types.d.ts +221 -0
- package/dist/types/artifacts/types.d.ts.map +1 -0
- package/dist/types/artifacts/wants.d.ts +105 -0
- package/dist/types/artifacts/wants.d.ts.map +1 -0
- package/dist/types/core/Agent.d.ts +8 -2
- package/dist/types/core/Agent.d.ts.map +1 -1
- package/dist/types/core/agent/buildToolRegistry.d.ts +11 -1
- package/dist/types/core/agent/buildToolRegistry.d.ts.map +1 -1
- package/dist/types/core/agent/presentTool.d.ts +23 -0
- package/dist/types/core/agent/presentTool.d.ts.map +1 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts +22 -0
- package/dist/types/core/agent/stages/toolCalls.d.ts.map +1 -1
- package/dist/types/core/agent/types.d.ts +46 -0
- package/dist/types/core/agent/types.d.ts.map +1 -1
- package/dist/types/core/codeRunnerTool.d.ts.map +1 -1
- package/dist/types/core/tools.d.ts +49 -0
- package/dist/types/core/tools.d.ts.map +1 -1
- package/dist/types/events/dispatcher.d.ts +1 -1
- package/dist/types/events/dispatcher.d.ts.map +1 -1
- package/dist/types/events/payloads.d.ts +83 -0
- package/dist/types/events/payloads.d.ts.map +1 -1
- package/dist/types/events/registry.d.ts +13 -1
- package/dist/types/events/registry.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/mcp/mcpServe.d.ts.map +1 -1
- package/dist/types/lib/trace-toolpack/traceToolpack.d.ts.map +1 -1
- package/dist/types/recorders/core/ArtifactsRecorder.d.ts +23 -0
- package/dist/types/recorders/core/ArtifactsRecorder.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -41,13 +41,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
41
41
|
exports.buildToolRegistry = void 0;
|
|
42
42
|
const skillTools_js_1 = require("../../lib/injection-engine/skillTools.js");
|
|
43
43
|
const skillSteps_js_1 = require("../../lib/injection-engine/skillSteps.js");
|
|
44
|
+
const present_js_1 = require("../../artifacts/present.js");
|
|
45
|
+
const presentTool_js_1 = require("./presentTool.js");
|
|
44
46
|
const tools_js_1 = require("../tools.js");
|
|
45
47
|
/**
|
|
46
48
|
* Compose the augmented tool registry from the static `.tool()`
|
|
47
49
|
* registry + the agent's injections (skills only). Throws on tool-
|
|
48
50
|
* name collisions across sources.
|
|
49
51
|
*/
|
|
50
|
-
function buildToolRegistry(registry, injections) {
|
|
52
|
+
function buildToolRegistry(registry, injections, options = {}) {
|
|
51
53
|
const skills = injections.filter((i) => i.flavor === 'skill');
|
|
52
54
|
// Collect skill tools, deduping by name when the SAME Tool reference
|
|
53
55
|
// is shared across skills. Different Tool implementations under the
|
|
@@ -91,9 +93,36 @@ function buildToolRegistry(registry, injections) {
|
|
|
91
93
|
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
92
94
|
[{ name: 'read_skill', tool: (0, skillTools_js_1.buildReadSkillTool)(skills) }]
|
|
93
95
|
: [];
|
|
96
|
+
// ── `present` — the hand-to-the-screen tool (9.22.0) ────────────────
|
|
97
|
+
// Auto-attached as a FULL citizen (schema offered + dispatchable) ONLY
|
|
98
|
+
// when a store is attached — the read_skill seam. The name is reserved
|
|
99
|
+
// the moment the store is: a consumer tool already holding 'present'
|
|
100
|
+
// would silently win the dispatch map and the model's presentations
|
|
101
|
+
// would run somebody else's function — accepted-and-silently-wrong, so
|
|
102
|
+
// it is refused by name (the skip_step law). Without a store, nothing
|
|
103
|
+
// here runs and a consumer's own 'present' is nobody's business.
|
|
104
|
+
const presentEntries = [];
|
|
105
|
+
if (options.hasArtifactStore === true) {
|
|
106
|
+
const holders = [
|
|
107
|
+
...registry.map((e) => e.name),
|
|
108
|
+
...skillToolEntries.map((e) => e.name),
|
|
109
|
+
...sharedSkillTools.keys(),
|
|
110
|
+
];
|
|
111
|
+
if (holders.includes(present_js_1.PRESENT_TOOL_NAME)) {
|
|
112
|
+
throw new Error(`Agent: tool name '${present_js_1.PRESENT_TOOL_NAME}' is reserved when an artifact store is ` +
|
|
113
|
+
`attached — the framework auto-attaches the hand-to-the-screen tool under that ` +
|
|
114
|
+
`name, and a same-named tool would silently take over the model's presentations. ` +
|
|
115
|
+
`Rename your tool, or drop the \`artifacts\` store.`);
|
|
116
|
+
}
|
|
117
|
+
presentEntries.push({
|
|
118
|
+
name: present_js_1.PRESENT_TOOL_NAME,
|
|
119
|
+
tool: (0, presentTool_js_1.buildPresentTool)(),
|
|
120
|
+
});
|
|
121
|
+
}
|
|
94
122
|
const augmentedRegistry = [
|
|
95
123
|
...registry,
|
|
96
124
|
...readSkillEntries,
|
|
125
|
+
...presentEntries,
|
|
97
126
|
...skillToolEntries,
|
|
98
127
|
];
|
|
99
128
|
// Final cross-source name-uniqueness check: static .tool() vs
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buildToolRegistry.js","sourceRoot":"","sources":["../../../src/core/agent/buildToolRegistry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;;;AAEH,4EAA8E;AAC9E,4EAIkD;AAGlD,0CAAuF;
|
|
1
|
+
{"version":3,"file":"buildToolRegistry.js","sourceRoot":"","sources":["../../../src/core/agent/buildToolRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* presentTool — the SHELL of the auto-attached `present` tool (9.22.0).
|
|
4
|
+
*
|
|
5
|
+
* Pattern: the `skip_step` placeholder, exactly. The tool here carries the
|
|
6
|
+
* schema the model reads; the AUTHORITATIVE work — `head` the ref under the
|
|
7
|
+
* run's scope, compose the description-snapshot result, emit
|
|
8
|
+
* `agentfootprint.artifacts.presented` — lives in the tool-calls stage
|
|
9
|
+
* (`applyPresent` in `stages/toolCalls.ts`), which OVERWRITES this
|
|
10
|
+
* placeholder's result. Bookkeeping lives where the batch order lives: the
|
|
11
|
+
* stage owns the scope, the store, and the typed emit channel; a tool's
|
|
12
|
+
* execute owns none of them.
|
|
13
|
+
*
|
|
14
|
+
* Attached by `buildToolRegistry` ONLY when a store is attached (the
|
|
15
|
+
* `read_skill` seam): a storeless agent never sees the tool, never reserves
|
|
16
|
+
* the name, and is byte-identical.
|
|
17
|
+
*
|
|
18
|
+
* The pure half — `PRESENT_TOOL_NAME`, `presentArtifact`, the snapshot
|
|
19
|
+
* shapes — lives in `src/artifacts/present.ts`, which cannot import core.
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.buildPresentTool = void 0;
|
|
23
|
+
const present_js_1 = require("../../artifacts/present.js");
|
|
24
|
+
const tools_js_1 = require("../tools.js");
|
|
25
|
+
/** Build the placeholder `present` tool. See the module header. */
|
|
26
|
+
function buildPresentTool() {
|
|
27
|
+
return (0, tools_js_1.defineTool)({
|
|
28
|
+
name: present_js_1.PRESENT_TOOL_NAME,
|
|
29
|
+
description: 'Hand a stored artifact to the screen instead of writing its contents out. Pass the ' +
|
|
30
|
+
"art_… ref and say how to render it (as: 'bar-chart', 'table', 'image', …); the " +
|
|
31
|
+
'screen redeems the ref itself. Use this to finish an answer whose substance is data ' +
|
|
32
|
+
'you stored — never retype what the store already holds.',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
ref: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'The art_… ref of the stored artifact to present.',
|
|
39
|
+
},
|
|
40
|
+
as: {
|
|
41
|
+
type: 'string',
|
|
42
|
+
description: "Consumer vocabulary for how the screen should render it: 'bar-chart', 'table', " +
|
|
43
|
+
"'image', 'markdown', … Say what it is; the screen picks the renderer.",
|
|
44
|
+
},
|
|
45
|
+
label: {
|
|
46
|
+
type: 'string',
|
|
47
|
+
description: "Optional human title for this presentation (e.g. 'Q3 sales by region').",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ['ref', 'as'],
|
|
51
|
+
additionalProperties: false,
|
|
52
|
+
},
|
|
53
|
+
execute: () => 'present noted. (Raw placeholder — the agent loop replaces this result with the ' +
|
|
54
|
+
'description snapshot; reading it verbatim means the runner that dispatched present ' +
|
|
55
|
+
'has no artifact store behind it.)',
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
exports.buildPresentTool = buildPresentTool;
|
|
59
|
+
//# sourceMappingURL=presentTool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presentTool.js","sourceRoot":"","sources":["../../../src/core/agent/presentTool.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;;;AAEH,2DAA+D;AAC/D,0CAAoD;AAEpD,mEAAmE;AACnE,SAAgB,gBAAgB;IAC9B,OAAO,IAAA,qBAAU,EAAsD;QACrE,IAAI,EAAE,8BAAiB;QACvB,WAAW,EACT,qFAAqF;YACrF,iFAAiF;YACjF,sFAAsF;YACtF,yDAAyD;QAC3D,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,GAAG,EAAE;oBACH,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,kDAAkD;iBAChE;gBACD,EAAE,EAAE;oBACF,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,iFAAiF;wBACjF,uEAAuE;iBAC1E;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,yEAAyE;iBACvF;aACF;YACD,QAAQ,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC;YACvB,oBAAoB,EAAE,KAAK;SAC5B;QACD,OAAO,EAAE,GAAG,EAAE,CACZ,iFAAiF;YACjF,qFAAqF;YACrF,mCAAmC;KACtC,CAAoB,CAAC;AACxB,CAAC;AAlCD,4CAkCC"}
|
|
@@ -52,6 +52,10 @@ const extractSequence_js_1 = require("../../../security/extractSequence.js");
|
|
|
52
52
|
const skillTarget_js_1 = require("../../../security/skillTarget.js");
|
|
53
53
|
const routingPolicy_js_1 = require("../../../lib/injection-engine/routingPolicy.js");
|
|
54
54
|
const types_js_2 = require("../../../identity/types.js");
|
|
55
|
+
const capability_js_1 = require("../../../artifacts/capability.js");
|
|
56
|
+
const wants_js_1 = require("../../../artifacts/wants.js");
|
|
57
|
+
const present_js_1 = require("../../../artifacts/present.js");
|
|
58
|
+
const placement_js_1 = require("../../../artifacts/placement.js");
|
|
55
59
|
const consent_js_1 = require("../../../identity/consent.js");
|
|
56
60
|
const pause_js_1 = require("../../pause.js");
|
|
57
61
|
const checkin_js_1 = require("../../checkin.js");
|
|
@@ -640,6 +644,248 @@ function buildToolCallsHandler(deps) {
|
|
|
640
644
|
},
|
|
641
645
|
};
|
|
642
646
|
};
|
|
647
|
+
/**
|
|
648
|
+
* `ctx.artifacts` + `ctx.hasArtifacts` for one dispatch — the claim-check
|
|
649
|
+
* capability, shaped exactly like `ctx.credentials` (9.21.0).
|
|
650
|
+
*
|
|
651
|
+
* The SCOPE is `scope.runIdentity` — the tuple the seed stage committed and
|
|
652
|
+
* memory already scopes on (an anonymous run isolates to its own runId, a
|
|
653
|
+
* session-bound run to its sessionId, an identity-carrying run to the
|
|
654
|
+
* caller's tenant/principal). Composed HERE, where the tool cannot reach:
|
|
655
|
+
* the capability closes over it, so a ref alone opens nothing and a tool
|
|
656
|
+
* can never widen the scope it resolves under. Detached to a plain object
|
|
657
|
+
* so the store never holds a live scope proxy.
|
|
658
|
+
*
|
|
659
|
+
* Every fact the capability reports rides the ordinary emit channel via
|
|
660
|
+
* `typedEmit`, mid-stage, carrying the real runtimeStageId — collected
|
|
661
|
+
* during traversal, exactly like `credential.failed`. Payload bytes never
|
|
662
|
+
* enter an event; the facts are meta only.
|
|
663
|
+
*
|
|
664
|
+
* With NO store attached the capability is the fail-closed teacher and no
|
|
665
|
+
* runIdentity read happens — a storeless agent's trace stays byte-identical.
|
|
666
|
+
*/
|
|
667
|
+
const toolArtifacts = (scope, toolName, toolCallId) => {
|
|
668
|
+
const onEvent = (fact) => {
|
|
669
|
+
switch (fact.type) {
|
|
670
|
+
case 'minted': {
|
|
671
|
+
const meta = fact.meta;
|
|
672
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.minted', {
|
|
673
|
+
ref: meta.ref,
|
|
674
|
+
kind: meta.kind,
|
|
675
|
+
mediaType: meta.mediaType,
|
|
676
|
+
bytes: meta.bytes,
|
|
677
|
+
...(meta.label !== undefined && { label: meta.label }),
|
|
678
|
+
...(meta.digest !== undefined && { digest: meta.digest }),
|
|
679
|
+
...(meta.expiresAt !== undefined && { expiresAt: meta.expiresAt }),
|
|
680
|
+
...(meta.origin !== undefined && { origin: meta.origin }),
|
|
681
|
+
...(meta.parentRefs !== undefined && { parentRefs: meta.parentRefs }),
|
|
682
|
+
tool: toolName,
|
|
683
|
+
});
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
case 'resolved':
|
|
687
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.resolved', {
|
|
688
|
+
ref: fact.ref,
|
|
689
|
+
via: fact.via,
|
|
690
|
+
kind: fact.kind,
|
|
691
|
+
bytes: fact.bytes,
|
|
692
|
+
tool: toolName,
|
|
693
|
+
});
|
|
694
|
+
return;
|
|
695
|
+
case 'expired':
|
|
696
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.expired', {
|
|
697
|
+
ref: fact.swept.ref,
|
|
698
|
+
reason: fact.swept.reason,
|
|
699
|
+
kind: fact.swept.kind,
|
|
700
|
+
bytes: fact.swept.bytes,
|
|
701
|
+
tool: toolName,
|
|
702
|
+
});
|
|
703
|
+
return;
|
|
704
|
+
case 'refused':
|
|
705
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.refused', {
|
|
706
|
+
op: fact.op,
|
|
707
|
+
reason: fact.reason,
|
|
708
|
+
...(fact.ref !== undefined && { ref: fact.ref }),
|
|
709
|
+
...(fact.detail !== undefined && { detail: fact.detail }),
|
|
710
|
+
tool: toolName,
|
|
711
|
+
});
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
const store = deps.artifactStore;
|
|
716
|
+
if (store === undefined) {
|
|
717
|
+
return { artifacts: (0, capability_js_1.unconfiguredArtifacts)(onEvent), hasArtifacts: false };
|
|
718
|
+
}
|
|
719
|
+
const facts = deps.currentRun?.();
|
|
720
|
+
const artifacts = (0, capability_js_1.bindArtifacts)(store, runScopeOf(scope), {
|
|
721
|
+
origin: { ...(facts?.runId !== undefined && { runId: facts.runId }), toolCallId },
|
|
722
|
+
onEvent,
|
|
723
|
+
});
|
|
724
|
+
return { artifacts, hasArtifacts: true };
|
|
725
|
+
};
|
|
726
|
+
/**
|
|
727
|
+
* The run's artifact scope — `scope.runIdentity`, detached to a plain
|
|
728
|
+
* object so no store or resolver ever holds a live scope proxy. ONE
|
|
729
|
+
* composition shared by the capability binding, `wants` resolution,
|
|
730
|
+
* `present`, and placement: four doors, one isolation rule, no drift.
|
|
731
|
+
*/
|
|
732
|
+
const runScopeOf = (scope) => {
|
|
733
|
+
const identity = scope.runIdentity;
|
|
734
|
+
return {
|
|
735
|
+
conversationId: identity.conversationId,
|
|
736
|
+
...(identity.tenant !== undefined && { tenant: identity.tenant }),
|
|
737
|
+
...(identity.principal !== undefined && { principal: identity.principal }),
|
|
738
|
+
};
|
|
739
|
+
};
|
|
740
|
+
// ── Ref ARGUMENTS at dispatch (9.22.0, Leg 1) — ONE resolver, every door ──
|
|
741
|
+
// The batch loop and `resolveCredentialAndExecute` (the resume paths) both
|
|
742
|
+
// dispatch tools; each calls this BEFORE credential resolution — never
|
|
743
|
+
// acquire credentials for a call that won't run — so a declared ref is
|
|
744
|
+
// judged identically whichever door the call came through. Success rides
|
|
745
|
+
// the existing `artifacts.resolved` (one event per resolved argument);
|
|
746
|
+
// refusals ride `artifacts.refused` with `op: 'dispatch'`, and the tool is
|
|
747
|
+
// NOT executed — the model reads the teaching refusal instead.
|
|
748
|
+
const resolveWantsAtDispatch = async (scope, toolName, wants, args) => {
|
|
749
|
+
const store = deps.artifactStore;
|
|
750
|
+
if (store === undefined) {
|
|
751
|
+
// Statically registered tools are refused at BUILD; this serves the
|
|
752
|
+
// doors that only meet the tool at dispatch (provider-served tools).
|
|
753
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.refused', {
|
|
754
|
+
op: 'dispatch',
|
|
755
|
+
reason: 'no-store',
|
|
756
|
+
detail: `tool '${toolName}' declares wants but no artifact store is attached`,
|
|
757
|
+
tool: toolName,
|
|
758
|
+
});
|
|
759
|
+
return { ok: false, refusal: (0, wants_js_1.wantsNeedsStoreRefusal)(toolName, wants) };
|
|
760
|
+
}
|
|
761
|
+
const verdict = await (0, wants_js_1.resolveToolWants)(store, runScopeOf(scope), toolName, wants, args);
|
|
762
|
+
if (!verdict.ok) {
|
|
763
|
+
for (const refusal of verdict.refusals) {
|
|
764
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.refused', {
|
|
765
|
+
op: 'dispatch',
|
|
766
|
+
reason: refusal.reason,
|
|
767
|
+
...(refusal.ref !== undefined && { ref: refusal.ref }),
|
|
768
|
+
detail: refusal.detail,
|
|
769
|
+
tool: toolName,
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
return { ok: false, refusal: verdict.refusal };
|
|
773
|
+
}
|
|
774
|
+
for (const { meta } of verdict.resolved) {
|
|
775
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.resolved', {
|
|
776
|
+
ref: meta.ref,
|
|
777
|
+
via: 'get',
|
|
778
|
+
kind: meta.kind,
|
|
779
|
+
bytes: meta.bytes,
|
|
780
|
+
tool: toolName,
|
|
781
|
+
});
|
|
782
|
+
}
|
|
783
|
+
return {
|
|
784
|
+
ok: true,
|
|
785
|
+
args: verdict.args,
|
|
786
|
+
// Absent when nothing resolved (no declared arg was passed): absent
|
|
787
|
+
// and empty are different facts, and `ctx.wanted` keeps them apart.
|
|
788
|
+
...(verdict.resolved.length > 0 && { wanted: verdict.wanted }),
|
|
789
|
+
};
|
|
790
|
+
};
|
|
791
|
+
// ── The `present` tool's authoritative result (9.22.0, Leg 2) ──────────
|
|
792
|
+
// The skip_step pattern: the auto-attached placeholder ran; the stage —
|
|
793
|
+
// which owns the scope, the store and the emit channel — OVERWRITES its
|
|
794
|
+
// result with the description snapshot (or the teaching refusal), so
|
|
795
|
+
// governance rules and the caps compose over what the model will read.
|
|
796
|
+
const applyPresent = async (scope, call) => {
|
|
797
|
+
const store = deps.artifactStore;
|
|
798
|
+
if (store === undefined) {
|
|
799
|
+
// Unreachable through the Agent (the tool is only attached beside a
|
|
800
|
+
// store) — kept for the same reason the placeholder text exists.
|
|
801
|
+
return {
|
|
802
|
+
ok: false,
|
|
803
|
+
text: 'present has no artifact store behind it here; nothing was presented.',
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
const outcome = await (0, present_js_1.presentArtifact)(store, runScopeOf(scope), call.args);
|
|
807
|
+
if (!outcome.ok) {
|
|
808
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.refused', {
|
|
809
|
+
op: 'dispatch',
|
|
810
|
+
reason: outcome.missedRef !== undefined ? 'missing-or-expired' : 'invalid-input',
|
|
811
|
+
...(outcome.missedRef !== undefined && { ref: outcome.missedRef }),
|
|
812
|
+
detail: outcome.refusal,
|
|
813
|
+
tool: present_js_1.PRESENT_TOOL_NAME,
|
|
814
|
+
});
|
|
815
|
+
return { ok: false, text: outcome.refusal };
|
|
816
|
+
}
|
|
817
|
+
const { ref, as, snapshot } = outcome.result;
|
|
818
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.resolved', {
|
|
819
|
+
ref,
|
|
820
|
+
via: 'head',
|
|
821
|
+
kind: snapshot.kind,
|
|
822
|
+
bytes: snapshot.bytes,
|
|
823
|
+
tool: present_js_1.PRESENT_TOOL_NAME,
|
|
824
|
+
});
|
|
825
|
+
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.artifacts.presented', {
|
|
826
|
+
ref,
|
|
827
|
+
as,
|
|
828
|
+
snapshot: { ...snapshot },
|
|
829
|
+
toolCallId: call.toolCallId,
|
|
830
|
+
iteration: call.iteration,
|
|
831
|
+
});
|
|
832
|
+
// The snapshot lives INSIDE the tool result — the one thing provider
|
|
833
|
+
// history keeps typed and durable — so a reloaded conversation can
|
|
834
|
+
// re-draw the pane, or state honestly why it can't.
|
|
835
|
+
return { ok: true, text: (0, validators_js_1.safeStringify)(outcome.result) };
|
|
836
|
+
};
|
|
837
|
+
// ── The placement threshold (9.22.0, Leg 3) — ONE judge, every door ────
|
|
838
|
+
// Called beside every `capResults` site, on the FINALIZED values (after
|
|
839
|
+
// the tool's own resultCeiling, after the after-tool chain) and before the
|
|
840
|
+
// truncation net — the stated precedence: author's refusal first, then the
|
|
841
|
+
// operator's ref-ing, then the last-resort net (which then measures the
|
|
842
|
+
// ticket). A placed result is a TICKET, not a refusal: the caller's
|
|
843
|
+
// effects/step bookkeeping proceeds exactly as if the payload had landed.
|
|
844
|
+
const placeResults = async (scope, call, values, eligible) => {
|
|
845
|
+
const placement = deps.placement;
|
|
846
|
+
if (placement === undefined || deps.artifactStore === undefined || !eligible)
|
|
847
|
+
return values;
|
|
848
|
+
const text = typeof values.modelResult === 'string'
|
|
849
|
+
? values.modelResult
|
|
850
|
+
: (0, validators_js_1.safeStringify)(values.modelResult);
|
|
851
|
+
if (text.length <= placement.maxInlineChars)
|
|
852
|
+
return values;
|
|
853
|
+
const bound = toolArtifacts(scope, call.toolName, call.toolCallId);
|
|
854
|
+
let meta;
|
|
855
|
+
try {
|
|
856
|
+
// The payload stored is the EXACT text the model would have read —
|
|
857
|
+
// byte-faithful, so a consumer redeems precisely what was displaced.
|
|
858
|
+
// `mediaType` states what that text is: a JSON serialization when the
|
|
859
|
+
// tool returned a value, plain text when it returned a string.
|
|
860
|
+
meta = await bound.artifacts.put({
|
|
861
|
+
kind: (0, placement_js_1.placedResultKind)(call.toolName),
|
|
862
|
+
mediaType: typeof values.modelResult === 'string' ? 'text/plain' : 'application/json',
|
|
863
|
+
data: text,
|
|
864
|
+
label: `${call.toolName} result`,
|
|
865
|
+
});
|
|
866
|
+
}
|
|
867
|
+
catch (err) {
|
|
868
|
+
// The store could not take it (a payload over the whole scope budget,
|
|
869
|
+
// say). The refusal is already on the record via the capability sink;
|
|
870
|
+
// the honest fallback is today's path — the truncation net still
|
|
871
|
+
// measures what placement could not lift. Named in dev mode.
|
|
872
|
+
if ((0, footprintjs_1.isDevMode)()) {
|
|
873
|
+
// eslint-disable-next-line no-console
|
|
874
|
+
console.warn(`agentfootprint placement: tool '${call.toolName}' result (${text.length} chars) ` +
|
|
875
|
+
`exceeded the ${placement.maxInlineChars}-char threshold but could not be ` +
|
|
876
|
+
`stored: ${err instanceof Error ? err.message : String(err)}`);
|
|
877
|
+
}
|
|
878
|
+
return values;
|
|
879
|
+
}
|
|
880
|
+
const substitute = (0, placement_js_1.placedToolResult)(call.toolName, meta, text.length, placement.maxInlineChars);
|
|
881
|
+
return {
|
|
882
|
+
// One ticket when the two channels carry one value — the capResults
|
|
883
|
+
// law. A chain-transformed `result` keeps its own truth and meets the
|
|
884
|
+
// truncation net below, exactly as before.
|
|
885
|
+
result: values.result === values.modelResult ? substitute : values.result,
|
|
886
|
+
modelResult: substitute,
|
|
887
|
+
};
|
|
888
|
+
};
|
|
643
889
|
/**
|
|
644
890
|
* Fire the `'call'`-scoped cleanups this tool call registered.
|
|
645
891
|
*
|
|
@@ -746,6 +992,18 @@ function buildToolCallsHandler(deps) {
|
|
|
746
992
|
const resolveCredentialAndExecute = async (scope, tool, toolName, args, toolCallId, iteration, env) => {
|
|
747
993
|
if (!tool)
|
|
748
994
|
return { result: `Unknown tool: ${toolName}`, error: true };
|
|
995
|
+
// Declared artifact arguments (9.22.0) — the same resolution the batch
|
|
996
|
+
// loop applies, at this door: a resumed call's refs are judged exactly
|
|
997
|
+
// as an inline call's, BEFORE credentials, and a refusal means the tool
|
|
998
|
+
// does not run.
|
|
999
|
+
let wantedMeta;
|
|
1000
|
+
if (tool.wants !== undefined) {
|
|
1001
|
+
const resolution = await resolveWantsAtDispatch(scope, toolName, tool.wants, args);
|
|
1002
|
+
if (!resolution.ok)
|
|
1003
|
+
return { result: resolution.refusal, error: true };
|
|
1004
|
+
args = resolution.args;
|
|
1005
|
+
wantedMeta = resolution.wanted;
|
|
1006
|
+
}
|
|
749
1007
|
const runIdentity = scope.runIdentity;
|
|
750
1008
|
let resolvedCredential;
|
|
751
1009
|
const need = tool.needs;
|
|
@@ -817,6 +1075,8 @@ function buildToolCallsHandler(deps) {
|
|
|
817
1075
|
credentials: reportingCredentials(credentials, scope, toolName),
|
|
818
1076
|
hasCredentials,
|
|
819
1077
|
...(resolvedCredential && { credential: resolvedCredential }),
|
|
1078
|
+
...toolArtifacts(scope, toolName, toolCallId),
|
|
1079
|
+
...(wantedMeta !== undefined && { wanted: wantedMeta }),
|
|
820
1080
|
...sessionContext(scope, toolName, toolCallId),
|
|
821
1081
|
});
|
|
822
1082
|
await endCall(toolCallId);
|
|
@@ -1325,6 +1585,29 @@ function buildToolCallsHandler(deps) {
|
|
|
1325
1585
|
}
|
|
1326
1586
|
}
|
|
1327
1587
|
if (!denied && !argsRejected) {
|
|
1588
|
+
// ── Declared artifact arguments (9.22.0) ──────────────────────
|
|
1589
|
+
// The `needs` precedent applied to data: resolve the tool's
|
|
1590
|
+
// declared `wants` refs BEFORE credential resolution (never
|
|
1591
|
+
// acquire credentials for a call that won't run) and BEFORE
|
|
1592
|
+
// execute — a stale/unknown/wrong-kind ref never reaches the
|
|
1593
|
+
// tool; the model reads a teaching refusal listing the live refs
|
|
1594
|
+
// of the wanted kind. On success `callArgs` carries the RESOLVED
|
|
1595
|
+
// DATA and `ctx.wanted` the claim tickets. Tools without `wants`
|
|
1596
|
+
// take the exact path they always took.
|
|
1597
|
+
let wantedMeta;
|
|
1598
|
+
let wantsBlocked = false;
|
|
1599
|
+
if (tool?.wants !== undefined) {
|
|
1600
|
+
const resolution = await resolveWantsAtDispatch(scope, tc.name, tool.wants, callArgs);
|
|
1601
|
+
if (resolution.ok) {
|
|
1602
|
+
callArgs = resolution.args;
|
|
1603
|
+
wantedMeta = resolution.wanted;
|
|
1604
|
+
}
|
|
1605
|
+
else {
|
|
1606
|
+
wantsBlocked = true;
|
|
1607
|
+
error = true;
|
|
1608
|
+
result = resolution.refusal;
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1328
1611
|
// Declare-and-push: resolve the tool's declared credential BEFORE
|
|
1329
1612
|
// invoking, and inject it as ctx.credential. On consent-required or
|
|
1330
1613
|
// failure, surface the reason to the LLM (tool result) + emit; the
|
|
@@ -1332,7 +1615,7 @@ function buildToolCallsHandler(deps) {
|
|
|
1332
1615
|
// throws is surfaced, not retried).
|
|
1333
1616
|
let resolvedCredential;
|
|
1334
1617
|
let credentialBlocked = false;
|
|
1335
|
-
const need = tool?.needs;
|
|
1618
|
+
const need = wantsBlocked ? undefined : tool?.needs;
|
|
1336
1619
|
if (need) {
|
|
1337
1620
|
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.credential.requested', {
|
|
1338
1621
|
service: need.credential,
|
|
@@ -1427,7 +1710,7 @@ function buildToolCallsHandler(deps) {
|
|
|
1427
1710
|
result = `credential error for '${need.credential}': ${reason}`;
|
|
1428
1711
|
}
|
|
1429
1712
|
}
|
|
1430
|
-
if (!credentialBlocked) {
|
|
1713
|
+
if (!credentialBlocked && !wantsBlocked) {
|
|
1431
1714
|
try {
|
|
1432
1715
|
if (!tool)
|
|
1433
1716
|
throw new Error(`Unknown tool: ${tc.name}`);
|
|
@@ -1442,6 +1725,8 @@ function buildToolCallsHandler(deps) {
|
|
|
1442
1725
|
credentials: reportingCredentials(credentials, scope, tc.name),
|
|
1443
1726
|
hasCredentials,
|
|
1444
1727
|
...(resolvedCredential && { credential: resolvedCredential }),
|
|
1728
|
+
...toolArtifacts(scope, tc.name, tc.id),
|
|
1729
|
+
...(wantedMeta !== undefined && { wanted: wantedMeta }),
|
|
1445
1730
|
...sessionContext(scope, tc.name, tc.id),
|
|
1446
1731
|
});
|
|
1447
1732
|
// The typed effects channel (9.19.0): a recognized envelope is
|
|
@@ -1586,6 +1871,23 @@ function buildToolCallsHandler(deps) {
|
|
|
1586
1871
|
if (deps.stepPlanFor && tc.name === skillSteps_js_1.SKIP_STEP_TOOL_NAME && !error && !denied) {
|
|
1587
1872
|
result = applySkipStep(scope, { args: callArgs, toolCallId: tc.id, iteration });
|
|
1588
1873
|
}
|
|
1874
|
+
// ── present bookkeeping (9.22.0) ───────────────────────────────
|
|
1875
|
+
// Same mechanism as skip_step: the auto-attached placeholder ran;
|
|
1876
|
+
// the stage overwrites its result with the description snapshot (or
|
|
1877
|
+
// the teaching refusal) BEFORE the after-tool moment, so governance
|
|
1878
|
+
// and the caps compose over what the model will actually read. A
|
|
1879
|
+
// miss is an errored call: the model holds no presentation, and a
|
|
1880
|
+
// procedure step whose tool presented nothing must not advance.
|
|
1881
|
+
if (deps.artifactStore && tc.name === present_js_1.PRESENT_TOOL_NAME && executed && !error && !denied) {
|
|
1882
|
+
const presented = await applyPresent(scope, {
|
|
1883
|
+
args: callArgs,
|
|
1884
|
+
toolCallId: tc.id,
|
|
1885
|
+
iteration,
|
|
1886
|
+
});
|
|
1887
|
+
result = presented.text;
|
|
1888
|
+
if (!presented.ok)
|
|
1889
|
+
error = true;
|
|
1890
|
+
}
|
|
1589
1891
|
// ── The after-tool moment ────────────────────────────────────────
|
|
1590
1892
|
// Last thing before the result becomes history, and only for a call
|
|
1591
1893
|
// that ran. `modelResult` is what the model reads; `result` stays the
|
|
@@ -1604,10 +1906,19 @@ function buildToolCallsHandler(deps) {
|
|
|
1604
1906
|
...(env.signal && { signal: env.signal }),
|
|
1605
1907
|
})
|
|
1606
1908
|
: result;
|
|
1909
|
+
// Placement next (9.22.0) — the operator's ref-ing, judged on what
|
|
1910
|
+
// the chain let through (a rule that already summarized a huge
|
|
1911
|
+
// result is measured on what it produced, the same reasoning as the
|
|
1912
|
+
// cap). Over the threshold, the payload is checked into the store
|
|
1913
|
+
// and BOTH channels carry the ticket; the truncation net below then
|
|
1914
|
+
// measures the ticket. A refused/denied/errored call is never
|
|
1915
|
+
// placed: a refusal is already short, and 'tool-result/<name>' must
|
|
1916
|
+
// never claim an error is the tool's result.
|
|
1917
|
+
const placedValues = await placeResults(scope, { toolName: tc.name, toolCallId: tc.id, iteration }, { result, modelResult: rawModelResult }, executed && !error && !denied && !ceilingRefused);
|
|
1607
1918
|
// The ceiling, last — after the tool, after the chain. A rule that
|
|
1608
1919
|
// already summarized a huge result is measured on what it produced, so
|
|
1609
1920
|
// the cap composes with governance rather than pre-empting it.
|
|
1610
|
-
const capped = capResults(tc.name,
|
|
1921
|
+
const capped = capResults(tc.name, placedValues);
|
|
1611
1922
|
const modelResult = capped.modelResult;
|
|
1612
1923
|
const durationMs = Date.now() - startMs;
|
|
1613
1924
|
(0, typedEmit_js_1.typedEmit)(scope, 'agentfootprint.stream.tool_end', {
|
|
@@ -1929,6 +2240,22 @@ function buildToolCallsHandler(deps) {
|
|
|
1929
2240
|
if (deps.stepPlanFor && toolName === skillSteps_js_1.SKIP_STEP_TOOL_NAME && stepToolRan) {
|
|
1930
2241
|
result = applySkipStep(scope, { args: rest.args, toolCallId, iteration });
|
|
1931
2242
|
}
|
|
2243
|
+
// present behind a middleware ask, approved (9.22.0): same
|
|
2244
|
+
// overwrite the batch loop applies — the snapshot (or refusal)
|
|
2245
|
+
// replaces the placeholder before the chain's last word. A miss
|
|
2246
|
+
// is an errored call here too.
|
|
2247
|
+
if (deps.artifactStore && toolName === present_js_1.PRESENT_TOOL_NAME && stepToolRan) {
|
|
2248
|
+
const presented = await applyPresent(scope, {
|
|
2249
|
+
args: rest.args,
|
|
2250
|
+
toolCallId,
|
|
2251
|
+
iteration,
|
|
2252
|
+
});
|
|
2253
|
+
result = presented.text;
|
|
2254
|
+
if (!presented.ok) {
|
|
2255
|
+
error = true;
|
|
2256
|
+
stepToolRan = false;
|
|
2257
|
+
}
|
|
2258
|
+
}
|
|
1932
2259
|
// The tool ran on this side of the pause, so the chain gets its
|
|
1933
2260
|
// last word here too — a rule about results cannot be skipped by
|
|
1934
2261
|
// routing a call through a human.
|
|
@@ -1952,7 +2279,11 @@ function buildToolCallsHandler(deps) {
|
|
|
1952
2279
|
// else the two are the same value.
|
|
1953
2280
|
if (modelResult === undefined)
|
|
1954
2281
|
modelResult = result;
|
|
1955
|
-
|
|
2282
|
+
// Placement then the truncation net — the batch loop's precedence,
|
|
2283
|
+
// kept on this door (a resumed result is as placeable as an inline
|
|
2284
|
+
// one; `stepToolRan` is exactly "ran clean").
|
|
2285
|
+
const askPlaced = await placeResults(scope, { toolName, toolCallId, iteration }, { result, modelResult }, stepToolRan);
|
|
2286
|
+
const askCapped = capResults(toolName, askPlaced);
|
|
1956
2287
|
modelResult = askCapped.modelResult;
|
|
1957
2288
|
let askResultStr = typeof modelResult === 'string' ? modelResult : (0, validators_js_1.safeStringify)(modelResult);
|
|
1958
2289
|
// Step boundary (9.18.0) — a result finalized HERE is as final as one
|
|
@@ -2073,7 +2404,9 @@ function buildToolCallsHandler(deps) {
|
|
|
2073
2404
|
}
|
|
2074
2405
|
if (modelResult === undefined)
|
|
2075
2406
|
modelResult = result;
|
|
2076
|
-
|
|
2407
|
+
// Placement then the truncation net — the batch loop's precedence.
|
|
2408
|
+
const decisionPlaced = await placeResults(scope, { toolName, toolCallId, iteration }, { result, modelResult }, stepToolRan);
|
|
2409
|
+
const decisionCapped = capResults(toolName, decisionPlaced);
|
|
2077
2410
|
modelResult = decisionCapped.modelResult;
|
|
2078
2411
|
let decisionResultStr = typeof modelResult === 'string' ? modelResult : (0, validators_js_1.safeStringify)(modelResult);
|
|
2079
2412
|
// Step boundary (9.18.0) — an approved consequential step (a checkIn
|
|
@@ -2165,7 +2498,9 @@ function buildToolCallsHandler(deps) {
|
|
|
2165
2498
|
}
|
|
2166
2499
|
if (modelResult === undefined)
|
|
2167
2500
|
modelResult = result;
|
|
2168
|
-
|
|
2501
|
+
// Placement then the truncation net — the batch loop's precedence.
|
|
2502
|
+
const consentPlaced = await placeResults(scope, { toolName, toolCallId, iteration }, { result, modelResult }, dispatched.executed === true && error !== true && dispatched.ceilingRefused !== true);
|
|
2503
|
+
const consentCapped = capResults(toolName, consentPlaced);
|
|
2169
2504
|
modelResult = consentCapped.modelResult;
|
|
2170
2505
|
let consentResultStr = typeof modelResult === 'string' ? modelResult : (0, validators_js_1.safeStringify)(modelResult);
|
|
2171
2506
|
// Step boundary (9.18.0) — a step tool that waited on 3LO consent
|
|
@@ -2269,8 +2604,12 @@ function buildToolCallsHandler(deps) {
|
|
|
2269
2604
|
});
|
|
2270
2605
|
// A person's answer is measured too. The cap is about what one turn can
|
|
2271
2606
|
// afford to carry, and a pasted transcript costs a window exactly as much
|
|
2272
|
-
// as a tool's rows do
|
|
2273
|
-
|
|
2607
|
+
// as a tool's rows do — which is also why PLACEMENT judges it: the
|
|
2608
|
+
// handler's contract makes the answer the tool's result, so a pasted
|
|
2609
|
+
// 500KB transcript is checked in as `tool-result/<tool>` and the model
|
|
2610
|
+
// routes the ticket.
|
|
2611
|
+
const pausePlaced = await placeResults(scope, { toolName, toolCallId, iteration }, { result: input, modelResult: rawPauseResult }, true);
|
|
2612
|
+
const pauseCapped = capResults(toolName, pausePlaced);
|
|
2274
2613
|
const modelResult = pauseCapped.modelResult;
|
|
2275
2614
|
let resultStr = typeof modelResult === 'string' ? modelResult : (0, validators_js_1.safeStringify)(modelResult);
|
|
2276
2615
|
// Step boundary (9.18.0) — THE HITL step ("ask a human, then export"):
|