@librechat/agents 3.6.9 → 3.6.11
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 +99 -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 +32 -21
- 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 +16 -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/stream.cjs +1 -0
- package/dist/cjs/stream.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 +79 -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 +39 -21
- 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 +73 -13
- package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
- package/dist/cjs/tools/ptcTimeout.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 +99 -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 +34 -23
- 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/stream.mjs +1 -0
- package/dist/esm/stream.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 +73 -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 +39 -21
- 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 +72 -15
- package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
- package/dist/esm/tools/ptcTimeout.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 +19 -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 +25 -0
- package/dist/types/tools/ProgrammaticCallerPolicy.d.ts +20 -0
- package/dist/types/tools/ToolNode.d.ts +12 -7
- package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +10 -0
- package/dist/types/tools/ptcTimeout.d.ts +8 -0
- package/dist/types/types/graph.d.ts +3 -1
- package/dist/types/types/tools.d.ts +30 -2
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +253 -69
- package/src/agents/projection.ts +9 -1
- package/src/graphs/Graph.ts +62 -26
- 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/stream.ts +6 -0
- package/src/tools/BashProgrammaticToolCalling.ts +46 -12
- package/src/tools/CallerCapabilities.ts +146 -0
- package/src/tools/ProgrammaticCallerPolicy.ts +97 -0
- package/src/tools/ProgrammaticToolCalling.ts +41 -7
- package/src/tools/ToolNode.ts +111 -50
- package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +24 -26
- package/src/tools/local/LocalProgrammaticToolCalling.ts +28 -23
- package/src/tools/local/resolveLocalExecutionTools.ts +209 -16
- package/src/tools/ptcTimeout.ts +6 -0
- package/src/types/graph.ts +3 -0
- package/src/types/tools.ts +32 -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
|
|
package/src/stream.ts
CHANGED
|
@@ -820,6 +820,12 @@ function startEagerToolExecutions(args: {
|
|
|
820
820
|
toolCalls: entries.map((entry) => entry.request),
|
|
821
821
|
userId: graph.config?.configurable?.user_id as string | undefined,
|
|
822
822
|
agentId: agentContext?.agentId,
|
|
823
|
+
callerCapabilityProjection:
|
|
824
|
+
(
|
|
825
|
+
agentContext as
|
|
826
|
+
| Partial<Pick<AgentContext, 'getCallerCapabilityProjectionSnapshot'>>
|
|
827
|
+
| undefined
|
|
828
|
+
)?.getCallerCapabilityProjectionSnapshot?.(),
|
|
823
829
|
configurable: graph.config?.configurable as
|
|
824
830
|
| Record<string, unknown>
|
|
825
831
|
| undefined,
|
|
@@ -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,146 @@
|
|
|
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
|
+
/**
|
|
18
|
+
* Combines event schemas with runtime capability metadata. Matching runtime
|
|
19
|
+
* entries override caller/defer policy without replacing the event schema;
|
|
20
|
+
* runtime-only definitions are appended intact.
|
|
21
|
+
*/
|
|
22
|
+
export function mergeCallerCapabilityDefinitions(
|
|
23
|
+
toolDefs: Iterable<t.LCTool> | null | undefined,
|
|
24
|
+
overrides: Iterable<t.LCTool> | null | undefined
|
|
25
|
+
): t.LCTool[] {
|
|
26
|
+
const runtimeDefinitions = Array.from(overrides ?? []);
|
|
27
|
+
const merged = new Map(
|
|
28
|
+
applyCallerCapabilityDefinitionOverrides(
|
|
29
|
+
toolDefs ?? [],
|
|
30
|
+
runtimeDefinitions
|
|
31
|
+
).map((toolDef) => [toolDef.name, toolDef])
|
|
32
|
+
);
|
|
33
|
+
for (const override of runtimeDefinitions) {
|
|
34
|
+
if (!merged.has(override.name)) {
|
|
35
|
+
merged.set(override.name, override);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return Array.from(merged.values());
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Applies runtime caller metadata to schema-only event definitions without
|
|
43
|
+
* adding registry-only tools or replacing their model-facing schemas.
|
|
44
|
+
*/
|
|
45
|
+
export function applyCallerCapabilityDefinitionOverrides(
|
|
46
|
+
toolDefs: Iterable<t.LCTool>,
|
|
47
|
+
overrides: Iterable<t.LCTool> | null | undefined
|
|
48
|
+
): t.LCTool[] {
|
|
49
|
+
const overridesByName = new Map<string, t.LCTool>();
|
|
50
|
+
for (const override of overrides ?? []) {
|
|
51
|
+
overridesByName.set(override.name, override);
|
|
52
|
+
}
|
|
53
|
+
return Array.from(toolDefs, (toolDef) => {
|
|
54
|
+
const override = overridesByName.get(toolDef.name);
|
|
55
|
+
if (override == null) {
|
|
56
|
+
return toolDef;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
...toolDef,
|
|
60
|
+
allowed_callers: override.allowed_callers,
|
|
61
|
+
defer_loading: override.defer_loading,
|
|
62
|
+
};
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/** Converts the live projection into the versioned event transport shape. */
|
|
67
|
+
export function createCallerCapabilityProjectionSnapshot(
|
|
68
|
+
projection: CallerCapabilityProjection
|
|
69
|
+
): t.CallerCapabilityProjectionSnapshot {
|
|
70
|
+
return {
|
|
71
|
+
version: 1,
|
|
72
|
+
directToolNames: projection.directTools.map((toolDef) => toolDef.name),
|
|
73
|
+
codeExecutionToolNames: projection.codeExecutionTools.map(
|
|
74
|
+
(toolDef) => toolDef.name
|
|
75
|
+
),
|
|
76
|
+
directOnlyToolNames: projection.directOnlyTools.map(
|
|
77
|
+
(toolDef) => toolDef.name
|
|
78
|
+
),
|
|
79
|
+
codeExecutionOnlyToolNames: projection.codeExecutionOnlyTools.map(
|
|
80
|
+
(toolDef) => toolDef.name
|
|
81
|
+
),
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function getAllowedCallers(
|
|
86
|
+
toolDef: t.LCTool
|
|
87
|
+
): readonly t.AllowedCaller[] {
|
|
88
|
+
return toolDef.allowed_callers ?? ['direct'];
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function allowsToolCaller(
|
|
92
|
+
toolDef: t.LCTool,
|
|
93
|
+
caller: t.AllowedCaller
|
|
94
|
+
): boolean {
|
|
95
|
+
return getAllowedCallers(toolDef).includes(caller);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
export function isProgrammaticControlTool(name: string): boolean {
|
|
99
|
+
return PROGRAMMATIC_CONTROL_TOOL_NAMES.has(name);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export function isToolDefinitionActive(
|
|
103
|
+
toolDef: t.LCTool,
|
|
104
|
+
discoveredToolNames: ReadonlySet<string>
|
|
105
|
+
): boolean {
|
|
106
|
+
return (
|
|
107
|
+
toolDef.defer_loading !== true || discoveredToolNames.has(toolDef.name)
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export function resolveCallerCapabilityProjection(
|
|
112
|
+
toolDefs: Iterable<t.LCTool>,
|
|
113
|
+
isActive: (toolDef: t.LCTool) => boolean = () => true
|
|
114
|
+
): CallerCapabilityProjection {
|
|
115
|
+
const directTools: t.LCTool[] = [];
|
|
116
|
+
const codeExecutionTools: t.LCTool[] = [];
|
|
117
|
+
const directOnlyTools: t.LCTool[] = [];
|
|
118
|
+
const codeExecutionOnlyTools: t.LCTool[] = [];
|
|
119
|
+
|
|
120
|
+
for (const toolDef of toolDefs) {
|
|
121
|
+
if (!isActive(toolDef)) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
const allowsDirect = allowsToolCaller(toolDef, 'direct');
|
|
125
|
+
const allowsCodeExecution = allowsToolCaller(toolDef, 'code_execution');
|
|
126
|
+
if (allowsDirect) {
|
|
127
|
+
directTools.push(toolDef);
|
|
128
|
+
}
|
|
129
|
+
if (allowsCodeExecution) {
|
|
130
|
+
codeExecutionTools.push(toolDef);
|
|
131
|
+
}
|
|
132
|
+
if (allowsDirect && !allowsCodeExecution) {
|
|
133
|
+
directOnlyTools.push(toolDef);
|
|
134
|
+
}
|
|
135
|
+
if (allowsCodeExecution && !allowsDirect) {
|
|
136
|
+
codeExecutionOnlyTools.push(toolDef);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return {
|
|
141
|
+
directTools,
|
|
142
|
+
codeExecutionTools,
|
|
143
|
+
directOnlyTools,
|
|
144
|
+
codeExecutionOnlyTools,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
@@ -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(
|