@librechat/agents 3.6.8 → 3.6.10
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/dist/cjs/agents/AgentContext.cjs +46 -39
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/agents/projection.cjs +2 -2
- package/dist/cjs/agents/projection.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +28 -18
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +87 -16
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +10 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +14 -0
- package/dist/cjs/messages/alternation.cjs +125 -20
- package/dist/cjs/messages/alternation.cjs.map +1 -1
- package/dist/cjs/messages/core.cjs +195 -18
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +488 -118
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/handoffCue.cjs +3 -2
- package/dist/cjs/messages/handoffCue.cjs.map +1 -1
- package/dist/cjs/messages/index.cjs +1 -0
- package/dist/cjs/messages/injected.cjs +5 -2
- package/dist/cjs/messages/injected.cjs.map +1 -1
- package/dist/cjs/messages/provenance.cjs +411 -0
- package/dist/cjs/messages/provenance.cjs.map +1 -0
- package/dist/cjs/messages/prune.cjs +18 -13
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/messages/toolResultTypes.cjs +663 -0
- package/dist/cjs/messages/toolResultTypes.cjs.map +1 -0
- package/dist/cjs/run.cjs +7 -4
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +21 -4
- package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/CallerCapabilities.cjs +48 -0
- package/dist/cjs/tools/CallerCapabilities.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs +34 -0
- package/dist/cjs/tools/ProgrammaticCallerPolicy.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +21 -4
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +25 -24
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +12 -4
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +13 -4
- package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +47 -11
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/ptcTimeout.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +19 -9
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +2 -1
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs +1 -1
- package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
- package/dist/cjs/utils/toolContent.cjs +2 -2
- package/dist/cjs/utils/toolContent.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +46 -39
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/agents/projection.mjs +2 -2
- package/dist/esm/agents/projection.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +30 -20
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +87 -16
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +10 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +4 -3
- package/dist/esm/messages/alternation.mjs +125 -20
- package/dist/esm/messages/alternation.mjs.map +1 -1
- package/dist/esm/messages/core.mjs +196 -19
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +488 -119
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/handoffCue.mjs +3 -2
- package/dist/esm/messages/handoffCue.mjs.map +1 -1
- package/dist/esm/messages/index.mjs +1 -0
- package/dist/esm/messages/injected.mjs +5 -2
- package/dist/esm/messages/injected.mjs.map +1 -1
- package/dist/esm/messages/provenance.mjs +401 -0
- package/dist/esm/messages/provenance.mjs.map +1 -0
- package/dist/esm/messages/prune.mjs +18 -13
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/messages/toolResultTypes.mjs +657 -0
- package/dist/esm/messages/toolResultTypes.mjs.map +1 -0
- package/dist/esm/run.mjs +7 -4
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs +21 -4
- package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/CallerCapabilities.mjs +45 -0
- package/dist/esm/tools/CallerCapabilities.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticCallerPolicy.mjs +32 -0
- package/dist/esm/tools/ProgrammaticCallerPolicy.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +21 -4
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +25 -24
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +14 -6
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +15 -6
- package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +47 -12
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/ptcTimeout.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +19 -9
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +2 -1
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs +1 -1
- package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
- package/dist/esm/utils/toolContent.mjs +2 -2
- package/dist/esm/utils/toolContent.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +8 -13
- package/dist/types/agents/projection.d.ts +3 -1
- package/dist/types/graphs/Graph.d.ts +1 -1
- package/dist/types/llm/openai/index.d.ts +20 -0
- package/dist/types/messages/format.d.ts +5 -0
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/messages/provenance.d.ts +85 -0
- package/dist/types/messages/toolResultTypes.d.ts +33 -0
- package/dist/types/tools/CallerCapabilities.d.ts +12 -0
- package/dist/types/tools/ProgrammaticCallerPolicy.d.ts +20 -0
- package/dist/types/tools/ToolNode.d.ts +4 -7
- package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +4 -0
- package/dist/types/tools/ptcTimeout.d.ts +8 -0
- package/dist/types/tools/search/types.d.ts +15 -0
- package/dist/types/types/graph.d.ts +3 -1
- package/dist/types/types/tools.d.ts +13 -2
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +109 -67
- package/src/agents/projection.ts +9 -1
- package/src/graphs/Graph.ts +56 -23
- package/src/graphs/MultiAgentGraph.ts +175 -33
- package/src/llm/openai/index.ts +43 -0
- package/src/messages/alternation.ts +217 -34
- package/src/messages/core.ts +358 -38
- package/src/messages/format.ts +958 -137
- package/src/messages/handoffCue.ts +7 -4
- package/src/messages/index.ts +1 -0
- package/src/messages/injected.ts +9 -6
- package/src/messages/provenance.ts +897 -0
- package/src/messages/prune.ts +28 -10
- package/src/messages/toolResultTypes.ts +1174 -0
- package/src/run.ts +9 -4
- package/src/tools/BashProgrammaticToolCalling.ts +46 -12
- package/src/tools/CallerCapabilities.ts +78 -0
- package/src/tools/ProgrammaticCallerPolicy.ts +97 -0
- package/src/tools/ProgrammaticToolCalling.ts +41 -7
- package/src/tools/ToolNode.ts +70 -52
- package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +24 -26
- package/src/tools/local/LocalProgrammaticToolCalling.ts +28 -23
- package/src/tools/local/resolveLocalExecutionTools.ts +132 -13
- package/src/tools/ptcTimeout.ts +6 -0
- package/src/tools/search/search.ts +25 -8
- package/src/tools/search/tool.ts +2 -0
- package/src/tools/search/types.ts +16 -0
- package/src/tools/subagent/SubagentExecutor.ts +8 -4
- package/src/types/graph.ts +3 -0
- package/src/types/tools.ts +14 -3
- package/src/utils/toolContent.ts +2 -2
package/src/run.ts
CHANGED
|
@@ -93,6 +93,7 @@ import {
|
|
|
93
93
|
import { applyGraphRuntimeConfig } from '@/graphs/applyGraphRuntimeConfig';
|
|
94
94
|
import { LANGFUSE_OPERATION_METADATA_KEY } from '@/langfuseOperation';
|
|
95
95
|
import { createTokenCounter, encodingForModel } from '@/utils/tokens';
|
|
96
|
+
import { stampSyntheticProviderMessage } from '@/messages/provenance';
|
|
96
97
|
import { initializeLangfuseTracing } from './instrumentation';
|
|
97
98
|
import { seedRunInitialSessions } from '@/utils/toolSessions';
|
|
98
99
|
import { getTraceIdSeed } from '@/langfuseRuntimeContext';
|
|
@@ -469,6 +470,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
469
470
|
subagentTasks: this.subagentTasks,
|
|
470
471
|
preemption: this.preemption,
|
|
471
472
|
streamLimits: this.streamLimits,
|
|
473
|
+
toolExecution: this.toolExecution,
|
|
472
474
|
},
|
|
473
475
|
});
|
|
474
476
|
/** Propagate compile options from graph config */
|
|
@@ -508,6 +510,7 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
508
510
|
subagentTasks: this.subagentTasks,
|
|
509
511
|
preemption: this.preemption,
|
|
510
512
|
streamLimits: this.streamLimits,
|
|
513
|
+
toolExecution: this.toolExecution,
|
|
511
514
|
},
|
|
512
515
|
});
|
|
513
516
|
|
|
@@ -699,10 +702,12 @@ export class Run<_T extends t.BaseGraphState> {
|
|
|
699
702
|
* it into the agent's `instructions` config instead.
|
|
700
703
|
*/
|
|
701
704
|
stateInputs.messages.push(
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
705
|
+
stampSyntheticProviderMessage(
|
|
706
|
+
new HumanMessage({
|
|
707
|
+
content: preStreamContexts.join('\n\n'),
|
|
708
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
709
|
+
})
|
|
710
|
+
)
|
|
706
711
|
);
|
|
707
712
|
}
|
|
708
713
|
|
|
@@ -13,16 +13,22 @@ import {
|
|
|
13
13
|
getCodeBaseURL,
|
|
14
14
|
selectRuntimeSessionHint,
|
|
15
15
|
} from './CodeExecutor';
|
|
16
|
-
import {
|
|
17
|
-
clampCodeApiRunTimeoutMs,
|
|
18
|
-
createCodeApiRunTimeoutSchema,
|
|
19
|
-
resolveCodeApiRunTimeoutMs,
|
|
20
|
-
} from './ptcTimeout';
|
|
21
16
|
import {
|
|
22
17
|
makeRequest,
|
|
23
18
|
executeTools,
|
|
24
19
|
formatCompletedResponse,
|
|
25
20
|
} from './ProgrammaticToolCalling';
|
|
21
|
+
import {
|
|
22
|
+
projectProgrammaticToolMap,
|
|
23
|
+
resolveProgrammaticToolDefinitions,
|
|
24
|
+
selectProgrammaticTools,
|
|
25
|
+
type ProgrammaticInvocationParams,
|
|
26
|
+
} from './ProgrammaticCallerPolicy';
|
|
27
|
+
import {
|
|
28
|
+
clampCodeApiRunTimeoutMs,
|
|
29
|
+
createCodeApiRunTimeoutSchema,
|
|
30
|
+
resolveCodeApiRunTimeoutMs,
|
|
31
|
+
} from './ptcTimeout';
|
|
26
32
|
import { INTENT_PROPERTY } from '@/tools/intentArg';
|
|
27
33
|
import { Constants } from '@/common';
|
|
28
34
|
|
|
@@ -108,6 +114,10 @@ ${EXAMPLES}
|
|
|
108
114
|
|
|
109
115
|
${CORE_RULES}`;
|
|
110
116
|
|
|
117
|
+
const TOOL_MANIFEST_DESCRIPTION =
|
|
118
|
+
'Exact registered tool names used by the code. Required when direct-only tools are configured; ' +
|
|
119
|
+
'validated before execution starts.';
|
|
120
|
+
|
|
111
121
|
// ============================================================================
|
|
112
122
|
// Schema
|
|
113
123
|
// ============================================================================
|
|
@@ -124,6 +134,12 @@ export function createBashProgrammaticToolCallingSchema(
|
|
|
124
134
|
minLength: 1,
|
|
125
135
|
description: CODE_PARAM_DESCRIPTION,
|
|
126
136
|
},
|
|
137
|
+
tool_manifest: {
|
|
138
|
+
type: 'array',
|
|
139
|
+
items: { type: 'string' },
|
|
140
|
+
uniqueItems: true,
|
|
141
|
+
description: TOOL_MANIFEST_DESCRIPTION,
|
|
142
|
+
},
|
|
127
143
|
timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),
|
|
128
144
|
},
|
|
129
145
|
required: ['code'],
|
|
@@ -302,7 +318,7 @@ export function createBashProgrammaticToolCallingTool(
|
|
|
302
318
|
|
|
303
319
|
return tool(
|
|
304
320
|
async (rawParams, config) => {
|
|
305
|
-
const params = rawParams as
|
|
321
|
+
const params = rawParams as ProgrammaticInvocationParams;
|
|
306
322
|
const { code } = params;
|
|
307
323
|
const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);
|
|
308
324
|
|
|
@@ -314,11 +330,26 @@ export function createBashProgrammaticToolCallingTool(
|
|
|
314
330
|
};
|
|
315
331
|
const {
|
|
316
332
|
toolMap,
|
|
317
|
-
|
|
333
|
+
disallowedToolDefs,
|
|
318
334
|
session_id,
|
|
319
335
|
_injected_files,
|
|
320
336
|
_runtime_session_hint,
|
|
321
337
|
} = toolCall;
|
|
338
|
+
const toolDefs = resolveProgrammaticToolDefinitions(
|
|
339
|
+
toolCall as typeof toolCall & { tools?: t.LCTool[] }
|
|
340
|
+
);
|
|
341
|
+
|
|
342
|
+
const programmaticToolName =
|
|
343
|
+
toolCall.programmaticToolName ??
|
|
344
|
+
(typeof toolCall.name === 'string' && toolCall.name !== ''
|
|
345
|
+
? toolCall.name
|
|
346
|
+
: Constants.BASH_PROGRAMMATIC_TOOL_CALLING);
|
|
347
|
+
const effectiveTools = selectProgrammaticTools({
|
|
348
|
+
requestedToolNames: params.tool_manifest,
|
|
349
|
+
allowedToolDefs: toolDefs,
|
|
350
|
+
disallowedToolDefs,
|
|
351
|
+
programmaticToolName,
|
|
352
|
+
});
|
|
322
353
|
|
|
323
354
|
if (toolMap == null || toolMap.size === 0) {
|
|
324
355
|
throw new Error(
|
|
@@ -334,20 +365,23 @@ export function createBashProgrammaticToolCallingTool(
|
|
|
334
365
|
);
|
|
335
366
|
}
|
|
336
367
|
|
|
368
|
+
const effectiveToolMap = projectProgrammaticToolMap(
|
|
369
|
+
toolMap,
|
|
370
|
+
effectiveTools
|
|
371
|
+
);
|
|
372
|
+
|
|
337
373
|
let roundTrip = 0;
|
|
338
374
|
|
|
339
375
|
try {
|
|
340
376
|
// ====================================================================
|
|
341
|
-
// Phase 1:
|
|
377
|
+
// Phase 1: Send the validated tool manifest with the initial request
|
|
342
378
|
// ====================================================================
|
|
343
379
|
|
|
344
|
-
const effectiveTools = filterBashToolsByUsage(toolDefs, code, debug);
|
|
345
|
-
|
|
346
380
|
if (debug) {
|
|
347
381
|
// eslint-disable-next-line no-console
|
|
348
382
|
console.log(
|
|
349
383
|
`[BashPTC Debug] Sending ${effectiveTools.length} tools to API ` +
|
|
350
|
-
`(
|
|
384
|
+
`(selected from ${toolDefs.length})`
|
|
351
385
|
);
|
|
352
386
|
}
|
|
353
387
|
|
|
@@ -422,7 +456,7 @@ export function createBashProgrammaticToolCallingTool(
|
|
|
422
456
|
const toolResults = normalizeBashToolResultsForReplay(
|
|
423
457
|
await executeTools(
|
|
424
458
|
response.tool_calls ?? [],
|
|
425
|
-
|
|
459
|
+
effectiveToolMap,
|
|
426
460
|
Constants.BASH_PROGRAMMATIC_TOOL_CALLING
|
|
427
461
|
)
|
|
428
462
|
);
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type * as t from '@/types';
|
|
2
|
+
import { Constants } from '@/common';
|
|
3
|
+
|
|
4
|
+
const PROGRAMMATIC_CONTROL_TOOL_NAMES = new Set<string>([
|
|
5
|
+
Constants.PROGRAMMATIC_TOOL_CALLING,
|
|
6
|
+
Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
|
|
7
|
+
Constants.TOOL_SEARCH,
|
|
8
|
+
]);
|
|
9
|
+
|
|
10
|
+
export type CallerCapabilityProjection = {
|
|
11
|
+
directTools: t.LCTool[];
|
|
12
|
+
codeExecutionTools: t.LCTool[];
|
|
13
|
+
directOnlyTools: t.LCTool[];
|
|
14
|
+
codeExecutionOnlyTools: t.LCTool[];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export function getAllowedCallers(
|
|
18
|
+
toolDef: t.LCTool
|
|
19
|
+
): readonly t.AllowedCaller[] {
|
|
20
|
+
return toolDef.allowed_callers ?? ['direct'];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function allowsToolCaller(
|
|
24
|
+
toolDef: t.LCTool,
|
|
25
|
+
caller: t.AllowedCaller
|
|
26
|
+
): boolean {
|
|
27
|
+
return getAllowedCallers(toolDef).includes(caller);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function isProgrammaticControlTool(name: string): boolean {
|
|
31
|
+
return PROGRAMMATIC_CONTROL_TOOL_NAMES.has(name);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function isToolDefinitionActive(
|
|
35
|
+
toolDef: t.LCTool,
|
|
36
|
+
discoveredToolNames: ReadonlySet<string>
|
|
37
|
+
): boolean {
|
|
38
|
+
return (
|
|
39
|
+
toolDef.defer_loading !== true || discoveredToolNames.has(toolDef.name)
|
|
40
|
+
);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function resolveCallerCapabilityProjection(
|
|
44
|
+
toolDefs: Iterable<t.LCTool>,
|
|
45
|
+
isActive: (toolDef: t.LCTool) => boolean = () => true
|
|
46
|
+
): CallerCapabilityProjection {
|
|
47
|
+
const directTools: t.LCTool[] = [];
|
|
48
|
+
const codeExecutionTools: t.LCTool[] = [];
|
|
49
|
+
const directOnlyTools: t.LCTool[] = [];
|
|
50
|
+
const codeExecutionOnlyTools: t.LCTool[] = [];
|
|
51
|
+
|
|
52
|
+
for (const toolDef of toolDefs) {
|
|
53
|
+
if (!isActive(toolDef)) {
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const allowsDirect = allowsToolCaller(toolDef, 'direct');
|
|
57
|
+
const allowsCodeExecution = allowsToolCaller(toolDef, 'code_execution');
|
|
58
|
+
if (allowsDirect) {
|
|
59
|
+
directTools.push(toolDef);
|
|
60
|
+
}
|
|
61
|
+
if (allowsCodeExecution) {
|
|
62
|
+
codeExecutionTools.push(toolDef);
|
|
63
|
+
}
|
|
64
|
+
if (allowsDirect && !allowsCodeExecution) {
|
|
65
|
+
directOnlyTools.push(toolDef);
|
|
66
|
+
}
|
|
67
|
+
if (allowsCodeExecution && !allowsDirect) {
|
|
68
|
+
codeExecutionOnlyTools.push(toolDef);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
directTools,
|
|
74
|
+
codeExecutionTools,
|
|
75
|
+
directOnlyTools,
|
|
76
|
+
codeExecutionOnlyTools,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type * as t from '@/types';
|
|
2
|
+
|
|
3
|
+
export type ProgrammaticInvocationParams = {
|
|
4
|
+
code: string;
|
|
5
|
+
tool_manifest?: string[];
|
|
6
|
+
timeout?: number;
|
|
7
|
+
lang?: string;
|
|
8
|
+
runtime?: string;
|
|
9
|
+
language?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export function resolveProgrammaticToolDefinitions(
|
|
13
|
+
context: Partial<t.ProgrammaticCache> & { tools?: t.LCTool[] }
|
|
14
|
+
): t.LCTool[] | undefined {
|
|
15
|
+
return context.toolDefs ?? context.tools;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function projectProgrammaticToolMap(
|
|
19
|
+
toolMap: t.ToolMap,
|
|
20
|
+
selectedToolDefs: readonly t.LCTool[]
|
|
21
|
+
): t.ToolMap {
|
|
22
|
+
const selectedNames = new Set(selectedToolDefs.map((toolDef) => toolDef.name));
|
|
23
|
+
return new Map(
|
|
24
|
+
[...toolMap].filter(([name]) => selectedNames.has(name))
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function assertDisallowedToolUsage(
|
|
29
|
+
disallowedNames: ReadonlySet<string>,
|
|
30
|
+
programmaticToolName: string
|
|
31
|
+
): void {
|
|
32
|
+
if (disallowedNames.size === 0) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const names = [...disallowedNames];
|
|
37
|
+
throw new Error(
|
|
38
|
+
`Tool${names.length === 1 ? '' : 's'} ${names
|
|
39
|
+
.map((name) => `"${name}"`)
|
|
40
|
+
.join(', ')} cannot be called from "${programmaticToolName}" because ` +
|
|
41
|
+
`the${names.length === 1 ? ' tool is' : 'se tools are'} not marked for code_execution. ` +
|
|
42
|
+
`Call ${names.length === 1 ? 'it' : 'them'} directly instead.`
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function selectProgrammaticTools(args: {
|
|
47
|
+
requestedToolNames?: string[];
|
|
48
|
+
allowedToolDefs?: t.LCTool[];
|
|
49
|
+
disallowedToolDefs?: t.LCTool[];
|
|
50
|
+
programmaticToolName: string;
|
|
51
|
+
}): t.LCTool[] {
|
|
52
|
+
const allowedToolDefs = args.allowedToolDefs ?? [];
|
|
53
|
+
const disallowedToolDefs = args.disallowedToolDefs ?? [];
|
|
54
|
+
const requestedToolNames = args.requestedToolNames;
|
|
55
|
+
|
|
56
|
+
if (requestedToolNames == null) {
|
|
57
|
+
if (disallowedToolDefs.length > 0) {
|
|
58
|
+
throw new Error(
|
|
59
|
+
`"${args.programmaticToolName}" requires a tool_manifest when direct-only tools are configured. ` +
|
|
60
|
+
'List every registered tool name used by the submitted code in the tool_manifest field.'
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
return allowedToolDefs;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const disallowedNames = new Set(
|
|
67
|
+
disallowedToolDefs.map((toolDef) => toolDef.name)
|
|
68
|
+
);
|
|
69
|
+
const requestedDisallowedNames = new Set(
|
|
70
|
+
requestedToolNames.filter((name) => disallowedNames.has(name))
|
|
71
|
+
);
|
|
72
|
+
assertDisallowedToolUsage(
|
|
73
|
+
requestedDisallowedNames,
|
|
74
|
+
args.programmaticToolName
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
const allowedByName = new Map(
|
|
78
|
+
allowedToolDefs.map((toolDef) => [toolDef.name, toolDef])
|
|
79
|
+
);
|
|
80
|
+
const unknownNames = new Set(
|
|
81
|
+
requestedToolNames.filter((name) => !allowedByName.has(name))
|
|
82
|
+
);
|
|
83
|
+
if (unknownNames.size > 0) {
|
|
84
|
+
throw new Error(
|
|
85
|
+
`Tool${unknownNames.size === 1 ? '' : 's'} ${[...unknownNames]
|
|
86
|
+
.map((name) => `"${name}"`)
|
|
87
|
+
.join(
|
|
88
|
+
', '
|
|
89
|
+
)} cannot be used by "${args.programmaticToolName}" because ` +
|
|
90
|
+
`${unknownNames.size === 1 ? 'it is' : 'they are'} not available for code_execution.`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
return [...new Set(requestedToolNames)].map(
|
|
95
|
+
(name) => allowedByName.get(name) as t.LCTool
|
|
96
|
+
);
|
|
97
|
+
}
|
|
@@ -26,6 +26,12 @@ import {
|
|
|
26
26
|
createCodeApiRunTimeoutSchema,
|
|
27
27
|
resolveCodeApiRunTimeoutMs,
|
|
28
28
|
} from './ptcTimeout';
|
|
29
|
+
import {
|
|
30
|
+
projectProgrammaticToolMap,
|
|
31
|
+
resolveProgrammaticToolDefinitions,
|
|
32
|
+
selectProgrammaticTools,
|
|
33
|
+
type ProgrammaticInvocationParams,
|
|
34
|
+
} from './ProgrammaticCallerPolicy';
|
|
29
35
|
import { resolveFetchProxyAgent } from '@/utils/proxy';
|
|
30
36
|
import { INTENT_PROPERTY } from '@/tools/intentArg';
|
|
31
37
|
import { Constants } from '@/common';
|
|
@@ -87,6 +93,10 @@ ${EXAMPLES}
|
|
|
87
93
|
|
|
88
94
|
${CORE_RULES}`;
|
|
89
95
|
|
|
96
|
+
const TOOL_MANIFEST_DESCRIPTION =
|
|
97
|
+
'Exact registered tool names used by the code. Required when direct-only tools are configured; ' +
|
|
98
|
+
'validated before execution starts.';
|
|
99
|
+
|
|
90
100
|
export function createProgrammaticToolCallingSchema(
|
|
91
101
|
maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS
|
|
92
102
|
): ProgrammaticToolCallingJsonSchema {
|
|
@@ -99,6 +109,12 @@ export function createProgrammaticToolCallingSchema(
|
|
|
99
109
|
minLength: 1,
|
|
100
110
|
description: CODE_PARAM_DESCRIPTION,
|
|
101
111
|
},
|
|
112
|
+
tool_manifest: {
|
|
113
|
+
type: 'array',
|
|
114
|
+
items: { type: 'string' },
|
|
115
|
+
uniqueItems: true,
|
|
116
|
+
description: TOOL_MANIFEST_DESCRIPTION,
|
|
117
|
+
},
|
|
102
118
|
timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),
|
|
103
119
|
},
|
|
104
120
|
required: ['code'],
|
|
@@ -893,7 +909,7 @@ export function createProgrammaticToolCallingTool(
|
|
|
893
909
|
|
|
894
910
|
return tool(
|
|
895
911
|
async (rawParams, config) => {
|
|
896
|
-
const params = rawParams as
|
|
912
|
+
const params = rawParams as ProgrammaticInvocationParams;
|
|
897
913
|
const { code } = params;
|
|
898
914
|
const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);
|
|
899
915
|
|
|
@@ -906,11 +922,26 @@ export function createProgrammaticToolCallingTool(
|
|
|
906
922
|
};
|
|
907
923
|
const {
|
|
908
924
|
toolMap,
|
|
909
|
-
|
|
925
|
+
disallowedToolDefs,
|
|
910
926
|
session_id,
|
|
911
927
|
_injected_files,
|
|
912
928
|
_runtime_session_hint,
|
|
913
929
|
} = toolCall;
|
|
930
|
+
const toolDefs = resolveProgrammaticToolDefinitions(
|
|
931
|
+
toolCall as typeof toolCall & { tools?: t.LCTool[] }
|
|
932
|
+
);
|
|
933
|
+
|
|
934
|
+
const programmaticToolName =
|
|
935
|
+
toolCall.programmaticToolName ??
|
|
936
|
+
(typeof toolCall.name === 'string' && toolCall.name !== ''
|
|
937
|
+
? toolCall.name
|
|
938
|
+
: Constants.PROGRAMMATIC_TOOL_CALLING);
|
|
939
|
+
const effectiveTools = selectProgrammaticTools({
|
|
940
|
+
requestedToolNames: params.tool_manifest,
|
|
941
|
+
allowedToolDefs: toolDefs,
|
|
942
|
+
disallowedToolDefs,
|
|
943
|
+
programmaticToolName,
|
|
944
|
+
});
|
|
914
945
|
|
|
915
946
|
if (toolMap == null || toolMap.size === 0) {
|
|
916
947
|
throw new Error(
|
|
@@ -926,20 +957,23 @@ export function createProgrammaticToolCallingTool(
|
|
|
926
957
|
);
|
|
927
958
|
}
|
|
928
959
|
|
|
960
|
+
const effectiveToolMap = projectProgrammaticToolMap(
|
|
961
|
+
toolMap,
|
|
962
|
+
effectiveTools
|
|
963
|
+
);
|
|
964
|
+
|
|
929
965
|
let roundTrip = 0;
|
|
930
966
|
|
|
931
967
|
try {
|
|
932
968
|
// ====================================================================
|
|
933
|
-
// Phase 1:
|
|
969
|
+
// Phase 1: Send the validated tool manifest with the initial request
|
|
934
970
|
// ====================================================================
|
|
935
971
|
|
|
936
|
-
const effectiveTools = filterToolsByUsage(toolDefs, code, debug);
|
|
937
|
-
|
|
938
972
|
if (debug) {
|
|
939
973
|
// eslint-disable-next-line no-console
|
|
940
974
|
console.log(
|
|
941
975
|
`[PTC Debug] Sending ${effectiveTools.length} tools to API ` +
|
|
942
|
-
`(
|
|
976
|
+
`(selected from ${toolDefs.length})`
|
|
943
977
|
);
|
|
944
978
|
}
|
|
945
979
|
|
|
@@ -1015,7 +1049,7 @@ export function createProgrammaticToolCallingTool(
|
|
|
1015
1049
|
|
|
1016
1050
|
const toolResults = await executeTools(
|
|
1017
1051
|
response.tool_calls ?? [],
|
|
1018
|
-
|
|
1052
|
+
effectiveToolMap
|
|
1019
1053
|
);
|
|
1020
1054
|
|
|
1021
1055
|
response = await makeRequest(
|
package/src/tools/ToolNode.ts
CHANGED
|
@@ -62,7 +62,6 @@ import {
|
|
|
62
62
|
SUBAGENT_PARENT_BATCH_CONFIG_KEY,
|
|
63
63
|
SUBAGENT_REPLAY_CONTROLLER,
|
|
64
64
|
} from '@/tools/subagent/SubagentReplay';
|
|
65
|
-
import { attachRunStepResumeState } from '@/tools/runStepResume';
|
|
66
65
|
import {
|
|
67
66
|
INTENT_ARG,
|
|
68
67
|
readOutcomeFields,
|
|
@@ -95,8 +94,14 @@ import {
|
|
|
95
94
|
resolveLocalToolRegistry,
|
|
96
95
|
resolveLocalExecutionTools,
|
|
97
96
|
} from '@/tools/local';
|
|
97
|
+
import {
|
|
98
|
+
isToolDefinitionActive,
|
|
99
|
+
isProgrammaticControlTool,
|
|
100
|
+
resolveCallerCapabilityProjection,
|
|
101
|
+
} from '@/tools/CallerCapabilities';
|
|
98
102
|
import { stripCodeSessionFileSummary } from '@/tools/CodeSessionFileSummary';
|
|
99
103
|
import { Constants, GraphEvents, CODE_EXECUTION_TOOLS } from '@/common';
|
|
104
|
+
import { attachRunStepResumeState } from '@/tools/runStepResume';
|
|
100
105
|
|
|
101
106
|
/** Host-facing batch requests must not carry the batch's breaker scope —
|
|
102
107
|
* hosts spread `configurable` into their own run configs. */
|
|
@@ -110,6 +115,7 @@ function stripRunBreakerScope(
|
|
|
110
115
|
return rest;
|
|
111
116
|
}
|
|
112
117
|
import { convertInjectedMessages } from '@/messages/injected';
|
|
118
|
+
import { stampSyntheticProviderMessage } from '@/messages/provenance';
|
|
113
119
|
import { safeDispatchCustomEvent } from '@/utils/events';
|
|
114
120
|
import { RunnableCallable, composeAbortSignals } from '@/utils';
|
|
115
121
|
import {
|
|
@@ -692,8 +698,8 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
692
698
|
>();
|
|
693
699
|
/** Tool registry for filtering (lazy computation of programmatic maps) */
|
|
694
700
|
private toolRegistry?: t.LCToolRegistry;
|
|
695
|
-
/**
|
|
696
|
-
private
|
|
701
|
+
/** Reads deferred-tool discovery state from the owning agent context. */
|
|
702
|
+
private getDiscoveredToolNames?: () => readonly string[];
|
|
697
703
|
/** Reference to Graph's sessions map for automatic session injection */
|
|
698
704
|
private sessions?: t.ToolSessionMap;
|
|
699
705
|
/** Partition within `sessions` owned by this agent's execution profile. */
|
|
@@ -797,6 +803,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
797
803
|
handleToolErrors,
|
|
798
804
|
loadRuntimeTools,
|
|
799
805
|
toolRegistry,
|
|
806
|
+
getDiscoveredToolNames,
|
|
800
807
|
sessions,
|
|
801
808
|
codeSessionKey,
|
|
802
809
|
eventDrivenMode,
|
|
@@ -872,6 +879,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
872
879
|
toolRegistry,
|
|
873
880
|
toolExecution,
|
|
874
881
|
});
|
|
882
|
+
this.getDiscoveredToolNames = getDiscoveredToolNames;
|
|
875
883
|
this.sessions = sessions;
|
|
876
884
|
this.codeSessionKey = codeSessionKey ?? Constants.EXECUTE_CODE;
|
|
877
885
|
this.eventDrivenMode = eventDrivenMode ?? false;
|
|
@@ -986,6 +994,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
986
994
|
const resolved = resolveLocalExecutionTools({
|
|
987
995
|
toolMap: this.toolMap,
|
|
988
996
|
toolExecution: this.toolExecution,
|
|
997
|
+
toolRegistry: this.toolRegistry,
|
|
989
998
|
fileCheckpointer: this.fileCheckpointer,
|
|
990
999
|
});
|
|
991
1000
|
|
|
@@ -1001,7 +1010,6 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1001
1010
|
...(this.directToolNames ?? new Set<string>()),
|
|
1002
1011
|
...resolved.directToolNames,
|
|
1003
1012
|
]);
|
|
1004
|
-
this.programmaticCache = undefined;
|
|
1005
1013
|
}
|
|
1006
1014
|
|
|
1007
1015
|
/**
|
|
@@ -1097,30 +1105,30 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1097
1105
|
this.settledInterruptingResults.clear();
|
|
1098
1106
|
}
|
|
1099
1107
|
|
|
1100
|
-
/**
|
|
1101
|
-
|
|
1102
|
-
* Single iteration builds both toolMap and toolDefs simultaneously.
|
|
1103
|
-
*/
|
|
1104
|
-
private getProgrammaticTools(): { toolMap: t.ToolMap; toolDefs: t.LCTool[] } {
|
|
1105
|
-
if (this.programmaticCache) return this.programmaticCache;
|
|
1106
|
-
|
|
1108
|
+
/** Returns active tools projected by their effective caller capabilities. */
|
|
1109
|
+
private getProgrammaticTools(): t.ProgrammaticCache {
|
|
1107
1110
|
const toolMap: t.ToolMap = new Map();
|
|
1108
|
-
const
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1111
|
+
const discoveredToolNames = new Set(
|
|
1112
|
+
this.getDiscoveredToolNames?.() ?? []
|
|
1113
|
+
);
|
|
1114
|
+
const capabilities = resolveCallerCapabilityProjection(
|
|
1115
|
+
this.toolRegistry?.values() ?? [],
|
|
1116
|
+
(toolDef) => isToolDefinitionActive(toolDef, discoveredToolNames)
|
|
1117
|
+
);
|
|
1118
|
+
for (const toolDef of capabilities.codeExecutionTools) {
|
|
1119
|
+
const tool = this.toolMap.get(toolDef.name);
|
|
1120
|
+
if (tool != null) {
|
|
1121
|
+
toolMap.set(toolDef.name, tool);
|
|
1119
1122
|
}
|
|
1120
1123
|
}
|
|
1121
1124
|
|
|
1122
|
-
|
|
1123
|
-
|
|
1125
|
+
return {
|
|
1126
|
+
toolMap,
|
|
1127
|
+
toolDefs: capabilities.codeExecutionTools,
|
|
1128
|
+
disallowedToolDefs: capabilities.directOnlyTools
|
|
1129
|
+
.filter((toolDef) => !isProgrammaticControlTool(toolDef.name))
|
|
1130
|
+
.map((toolDef) => ({ name: toolDef.name })),
|
|
1131
|
+
};
|
|
1124
1132
|
}
|
|
1125
1133
|
|
|
1126
1134
|
/**
|
|
@@ -1331,11 +1339,14 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
1331
1339
|
call.name === Constants.PROGRAMMATIC_TOOL_CALLING ||
|
|
1332
1340
|
call.name === Constants.BASH_PROGRAMMATIC_TOOL_CALLING
|
|
1333
1341
|
) {
|
|
1334
|
-
const { toolMap, toolDefs } =
|
|
1342
|
+
const { toolMap, toolDefs, disallowedToolDefs } =
|
|
1343
|
+
this.getProgrammaticTools();
|
|
1335
1344
|
invokeParams = {
|
|
1336
1345
|
...invokeParams,
|
|
1337
1346
|
toolMap,
|
|
1338
1347
|
toolDefs,
|
|
1348
|
+
disallowedToolDefs,
|
|
1349
|
+
programmaticToolName: call.name,
|
|
1339
1350
|
// Plumb the hook context into the programmatic-tool path so
|
|
1340
1351
|
// inner tool calls made via the in-process bridge can run
|
|
1341
1352
|
// through `PreToolUse` (deny / updatedInput) before reaching
|
|
@@ -3927,10 +3938,12 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
3927
3938
|
* a user message; `role` is metadata only.
|
|
3928
3939
|
*/
|
|
3929
3940
|
injected.push(
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3941
|
+
stampSyntheticProviderMessage(
|
|
3942
|
+
new HumanMessage({
|
|
3943
|
+
content: batchAdditionalContexts.join('\n\n'),
|
|
3944
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
3945
|
+
})
|
|
3946
|
+
)
|
|
3934
3947
|
);
|
|
3935
3948
|
}
|
|
3936
3949
|
|
|
@@ -4423,13 +4436,15 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
4423
4436
|
directAdditionalContexts.length > 0
|
|
4424
4437
|
? [
|
|
4425
4438
|
sendOutput,
|
|
4426
|
-
|
|
4427
|
-
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
|
|
4439
|
+
stampSyntheticProviderMessage(
|
|
4440
|
+
new HumanMessage({
|
|
4441
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
4442
|
+
// Match the event-driven path's marker so hosts /
|
|
4443
|
+
// model-side annotators treat this as system intent
|
|
4444
|
+
// rather than ordinary user text. Codex P2 [46].
|
|
4445
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
4446
|
+
})
|
|
4447
|
+
),
|
|
4433
4448
|
]
|
|
4434
4449
|
: [sendOutput];
|
|
4435
4450
|
await this.handleRunToolCompletions(
|
|
@@ -4477,7 +4492,6 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
4477
4492
|
this.toolMap =
|
|
4478
4493
|
toolMap ?? new Map(tools.map((tool) => [tool.name, tool]));
|
|
4479
4494
|
this.applyToolExecutionOverrides();
|
|
4480
|
-
this.programmaticCache = undefined; // Invalidate cache on toolMap change
|
|
4481
4495
|
}
|
|
4482
4496
|
|
|
4483
4497
|
const filteredCalls =
|
|
@@ -4721,14 +4735,16 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
4721
4735
|
const directInjected: BaseMessage[] =
|
|
4722
4736
|
directAdditionalContexts.length > 0
|
|
4723
4737
|
? [
|
|
4724
|
-
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4738
|
+
stampSyntheticProviderMessage(
|
|
4739
|
+
new HumanMessage({
|
|
4740
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
4741
|
+
// System-role metadata to match the event-driven
|
|
4742
|
+
// path so policy/recovery guidance is treated
|
|
4743
|
+
// consistently regardless of whether the tool ran
|
|
4744
|
+
// direct or dispatched. Codex P2 [46].
|
|
4745
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
4746
|
+
})
|
|
4747
|
+
),
|
|
4732
4748
|
]
|
|
4733
4749
|
: [];
|
|
4734
4750
|
outputs = [
|
|
@@ -4782,13 +4798,15 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
4782
4798
|
...promotedPrefix,
|
|
4783
4799
|
...toolOutputs,
|
|
4784
4800
|
...invalidCallResults,
|
|
4785
|
-
|
|
4786
|
-
|
|
4787
|
-
|
|
4788
|
-
|
|
4789
|
-
|
|
4790
|
-
|
|
4791
|
-
|
|
4801
|
+
stampSyntheticProviderMessage(
|
|
4802
|
+
new HumanMessage({
|
|
4803
|
+
content: directAdditionalContexts.join('\n\n'),
|
|
4804
|
+
// Same system-role marker the event-driven path
|
|
4805
|
+
// uses so direct vs dispatched is invisible to
|
|
4806
|
+
// downstream consumers. Codex P2 [46].
|
|
4807
|
+
additional_kwargs: { role: 'system', source: 'hook' },
|
|
4808
|
+
})
|
|
4809
|
+
),
|
|
4792
4810
|
]
|
|
4793
4811
|
: [...promotedPrefix, ...toolOutputs, ...invalidCallResults];
|
|
4794
4812
|
}
|