@librechat/agents 3.0.42 → 3.0.43
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 +134 -70
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/common/enum.cjs +1 -1
- package/dist/cjs/common/enum.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +7 -13
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/main.cjs +5 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/tools.cjs +85 -0
- package/dist/cjs/messages/tools.cjs.map +1 -0
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +55 -32
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +30 -13
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +134 -70
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/common/enum.mjs +1 -1
- package/dist/esm/common/enum.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +8 -14
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/main.mjs +2 -1
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/tools.mjs +82 -0
- package/dist/esm/messages/tools.mjs.map +1 -0
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +54 -33
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +30 -13
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +37 -17
- package/dist/types/common/enum.d.ts +1 -1
- package/dist/types/messages/index.d.ts +1 -0
- package/dist/types/messages/tools.d.ts +17 -0
- package/dist/types/tools/ProgrammaticToolCalling.d.ts +15 -23
- package/dist/types/tools/ToolNode.d.ts +9 -7
- package/dist/types/types/tools.d.ts +5 -5
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +157 -85
- package/src/agents/__tests__/AgentContext.test.ts +805 -0
- package/src/common/enum.ts +1 -1
- package/src/graphs/Graph.ts +9 -21
- package/src/messages/__tests__/tools.test.ts +473 -0
- package/src/messages/index.ts +1 -0
- package/src/messages/tools.ts +99 -0
- package/src/scripts/code_exec_ptc.ts +78 -21
- package/src/scripts/programmatic_exec.ts +3 -3
- package/src/scripts/programmatic_exec_agent.ts +4 -4
- package/src/tools/ProgrammaticToolCalling.ts +71 -39
- package/src/tools/ToolNode.ts +33 -14
- package/src/tools/__tests__/ProgrammaticToolCalling.integration.test.ts +9 -9
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +180 -5
- package/src/types/tools.ts +3 -5
|
@@ -3,40 +3,32 @@ import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
|
3
3
|
import type * as t from '@/types';
|
|
4
4
|
declare const ProgrammaticToolCallingSchema: z.ZodObject<{
|
|
5
5
|
code: z.ZodString;
|
|
6
|
-
tools: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
7
|
-
name: z.ZodString;
|
|
8
|
-
description: z.ZodOptional<z.ZodString>;
|
|
9
|
-
parameters: z.ZodAny;
|
|
10
|
-
}, "strip", z.ZodTypeAny, {
|
|
11
|
-
name: string;
|
|
12
|
-
description?: string | undefined;
|
|
13
|
-
parameters?: any;
|
|
14
|
-
}, {
|
|
15
|
-
name: string;
|
|
16
|
-
description?: string | undefined;
|
|
17
|
-
parameters?: any;
|
|
18
|
-
}>, "many">>;
|
|
19
6
|
session_id: z.ZodOptional<z.ZodString>;
|
|
20
7
|
timeout: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
|
|
21
8
|
}, "strip", z.ZodTypeAny, {
|
|
22
9
|
code: string;
|
|
23
10
|
timeout: number;
|
|
24
|
-
tools?: {
|
|
25
|
-
name: string;
|
|
26
|
-
description?: string | undefined;
|
|
27
|
-
parameters?: any;
|
|
28
|
-
}[] | undefined;
|
|
29
11
|
session_id?: string | undefined;
|
|
30
12
|
}, {
|
|
31
13
|
code: string;
|
|
32
|
-
tools?: {
|
|
33
|
-
name: string;
|
|
34
|
-
description?: string | undefined;
|
|
35
|
-
parameters?: any;
|
|
36
|
-
}[] | undefined;
|
|
37
14
|
timeout?: number | undefined;
|
|
38
15
|
session_id?: string | undefined;
|
|
39
16
|
}>;
|
|
17
|
+
/**
|
|
18
|
+
* Extracts tool names that are actually called in the Python code.
|
|
19
|
+
* Matches patterns like `await tool_name(`, `tool_name(`, and asyncio.gather calls.
|
|
20
|
+
* @param code - The Python code to analyze
|
|
21
|
+
* @param availableToolNames - Set of available tool names to match against
|
|
22
|
+
* @returns Set of tool names found in the code
|
|
23
|
+
*/
|
|
24
|
+
export declare function extractUsedToolNames(code: string, availableToolNames: Set<string>): Set<string>;
|
|
25
|
+
/**
|
|
26
|
+
* Filters tool definitions to only include tools actually used in the code.
|
|
27
|
+
* @param toolDefs - All available tool definitions
|
|
28
|
+
* @param code - The Python code to analyze
|
|
29
|
+
* @returns Filtered array of tool definitions
|
|
30
|
+
*/
|
|
31
|
+
export declare function filterToolsByUsage(toolDefs: t.LCTool[], code: string): t.LCTool[];
|
|
40
32
|
/**
|
|
41
33
|
* Makes an HTTP request to the Code API.
|
|
42
34
|
* @param endpoint - The API endpoint URL
|
|
@@ -5,7 +5,6 @@ import type { BaseMessage } from '@langchain/core/messages';
|
|
|
5
5
|
import type * as t from '@/types';
|
|
6
6
|
import { RunnableCallable } from '@/utils';
|
|
7
7
|
export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
8
|
-
tools: t.GenericTool[];
|
|
9
8
|
private toolMap;
|
|
10
9
|
private loadRuntimeTools?;
|
|
11
10
|
handleToolErrors: boolean;
|
|
@@ -13,13 +12,16 @@ export declare class ToolNode<T = any> extends RunnableCallable<T, T> {
|
|
|
13
12
|
toolCallStepIds?: Map<string, string>;
|
|
14
13
|
errorHandler?: t.ToolNodeConstructorParams['errorHandler'];
|
|
15
14
|
private toolUsageCount;
|
|
16
|
-
/**
|
|
17
|
-
private programmaticToolMap?;
|
|
18
|
-
/** Tool definitions for programmatic code execution (sent to Code API) */
|
|
19
|
-
private programmaticToolDefs?;
|
|
20
|
-
/** Tool registry for tool search (deferred tools) */
|
|
15
|
+
/** Tool registry for filtering (lazy computation of programmatic maps) */
|
|
21
16
|
private toolRegistry?;
|
|
22
|
-
|
|
17
|
+
/** Cached programmatic tools (computed once on first PTC call) */
|
|
18
|
+
private programmaticCache?;
|
|
19
|
+
constructor({ tools, toolMap, name, tags, errorHandler, toolCallStepIds, handleToolErrors, loadRuntimeTools, toolRegistry, }: t.ToolNodeConstructorParams);
|
|
20
|
+
/**
|
|
21
|
+
* Returns cached programmatic tools, computing once on first access.
|
|
22
|
+
* Single iteration builds both toolMap and toolDefs simultaneously.
|
|
23
|
+
*/
|
|
24
|
+
private getProgrammaticTools;
|
|
23
25
|
/**
|
|
24
26
|
* Returns a snapshot of the current tool usage counts.
|
|
25
27
|
* @returns A ReadonlyMap where keys are tool names and values are their usage counts.
|
|
@@ -25,11 +25,7 @@ export type ToolNodeOptions = {
|
|
|
25
25
|
loadRuntimeTools?: ToolRefGenerator;
|
|
26
26
|
toolCallStepIds?: Map<string, string>;
|
|
27
27
|
errorHandler?: (data: ToolErrorData, metadata?: Record<string, unknown>) => Promise<void>;
|
|
28
|
-
/**
|
|
29
|
-
programmaticToolMap?: ToolMap;
|
|
30
|
-
/** Tool definitions for programmatic code execution (sent to Code API for stub generation) */
|
|
31
|
-
programmaticToolDefs?: LCTool[];
|
|
32
|
-
/** Tool registry for tool search (deferred tool definitions) */
|
|
28
|
+
/** Tool registry for lazy computation of programmatic tools and tool search */
|
|
33
29
|
toolRegistry?: LCToolRegistry;
|
|
34
30
|
};
|
|
35
31
|
export type ToolNodeConstructorParams = ToolRefs & ToolNodeOptions;
|
|
@@ -97,6 +93,10 @@ export type LCTool = {
|
|
|
97
93
|
};
|
|
98
94
|
/** Map of tool names to tool definitions */
|
|
99
95
|
export type LCToolRegistry = Map<string, LCTool>;
|
|
96
|
+
export type ProgrammaticCache = {
|
|
97
|
+
toolMap: ToolMap;
|
|
98
|
+
toolDefs: LCTool[];
|
|
99
|
+
};
|
|
100
100
|
/** Parameters for creating a Tool Search Regex tool */
|
|
101
101
|
export type ToolSearchRegexParams = {
|
|
102
102
|
apiKey?: string;
|
package/package.json
CHANGED
|
@@ -13,19 +13,6 @@ import type * as t from '@/types';
|
|
|
13
13
|
import type { createPruneMessages } from '@/messages';
|
|
14
14
|
import { ContentTypes, Providers } from '@/common';
|
|
15
15
|
|
|
16
|
-
/**
|
|
17
|
-
* Checks if a tool allows the specified caller type.
|
|
18
|
-
* Default is 'direct' only if allowed_callers is not specified.
|
|
19
|
-
*/
|
|
20
|
-
function toolAllowsCaller(
|
|
21
|
-
toolDef: t.LCTool | undefined,
|
|
22
|
-
caller: t.AllowedCaller
|
|
23
|
-
): boolean {
|
|
24
|
-
if (!toolDef) return false;
|
|
25
|
-
const allowedCallers = toolDef.allowed_callers ?? ['direct'];
|
|
26
|
-
return allowedCallers.includes(caller);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
16
|
/**
|
|
30
17
|
* Encapsulates agent-specific state that can vary between agents in a multi-agent system
|
|
31
18
|
*/
|
|
@@ -73,12 +60,17 @@ export class AgentContext {
|
|
|
73
60
|
});
|
|
74
61
|
|
|
75
62
|
if (tokenCounter) {
|
|
63
|
+
// Initialize system runnable BEFORE async tool token calculation
|
|
64
|
+
// This ensures system message tokens are in instructionTokens before
|
|
65
|
+
// updateTokenMapWithInstructions is called
|
|
66
|
+
agentContext.initializeSystemRunnable();
|
|
67
|
+
|
|
76
68
|
const tokenMap = indexTokenCountMap || {};
|
|
77
69
|
agentContext.indexTokenCountMap = tokenMap;
|
|
78
70
|
agentContext.tokenCalculationPromise = agentContext
|
|
79
71
|
.calculateInstructionTokens(tokenCounter)
|
|
80
72
|
.then(() => {
|
|
81
|
-
// Update token map with instruction tokens
|
|
73
|
+
// Update token map with instruction tokens (includes system + tool tokens)
|
|
82
74
|
agentContext.updateTokenMapWithInstructions(tokenMap);
|
|
83
75
|
})
|
|
84
76
|
.catch((err) => {
|
|
@@ -139,12 +131,16 @@ export class AgentContext {
|
|
|
139
131
|
ContentTypes.TEXT;
|
|
140
132
|
/** Whether tools should end the workflow */
|
|
141
133
|
toolEnd: boolean = false;
|
|
142
|
-
/**
|
|
143
|
-
|
|
134
|
+
/** Cached system runnable (created lazily) */
|
|
135
|
+
private cachedSystemRunnable?: Runnable<
|
|
144
136
|
BaseMessage[],
|
|
145
137
|
(BaseMessage | SystemMessage)[],
|
|
146
138
|
RunnableConfig<Record<string, unknown>>
|
|
147
139
|
>;
|
|
140
|
+
/** Whether system runnable needs rebuild (set when discovered tools change) */
|
|
141
|
+
private systemRunnableStale: boolean = true;
|
|
142
|
+
/** Cached system message token count (separate from tool tokens) */
|
|
143
|
+
private systemMessageTokens: number = 0;
|
|
148
144
|
/** Promise for token calculation initialization */
|
|
149
145
|
tokenCalculationPromise?: Promise<void>;
|
|
150
146
|
/** Format content blocks as strings (for legacy compatibility) */
|
|
@@ -205,39 +201,145 @@ export class AgentContext {
|
|
|
205
201
|
}
|
|
206
202
|
|
|
207
203
|
this.useLegacyContent = useLegacyContent ?? false;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Builds instructions text for tools that are ONLY callable via programmatic code execution.
|
|
208
|
+
* These tools cannot be called directly by the LLM but are available through the
|
|
209
|
+
* run_tools_with_code tool.
|
|
210
|
+
*
|
|
211
|
+
* Includes:
|
|
212
|
+
* - Code_execution-only tools that are NOT deferred
|
|
213
|
+
* - Code_execution-only tools that ARE deferred but have been discovered via tool search
|
|
214
|
+
*/
|
|
215
|
+
private buildProgrammaticOnlyToolsInstructions(): string {
|
|
216
|
+
if (!this.toolRegistry) return '';
|
|
217
|
+
|
|
218
|
+
const programmaticOnlyTools: t.LCTool[] = [];
|
|
219
|
+
for (const [name, toolDef] of this.toolRegistry) {
|
|
220
|
+
const allowedCallers = toolDef.allowed_callers ?? ['direct'];
|
|
221
|
+
const isCodeExecutionOnly =
|
|
222
|
+
allowedCallers.includes('code_execution') &&
|
|
223
|
+
!allowedCallers.includes('direct');
|
|
224
|
+
|
|
225
|
+
if (!isCodeExecutionOnly) continue;
|
|
226
|
+
|
|
227
|
+
// Include if: not deferred OR deferred but discovered
|
|
228
|
+
const isDeferred = toolDef.defer_loading === true;
|
|
229
|
+
const isDiscovered = this.discoveredToolNames.has(name);
|
|
230
|
+
if (!isDeferred || isDiscovered) {
|
|
231
|
+
programmaticOnlyTools.push(toolDef);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (programmaticOnlyTools.length === 0) return '';
|
|
208
236
|
|
|
209
|
-
|
|
237
|
+
const toolDescriptions = programmaticOnlyTools
|
|
238
|
+
.map((tool) => {
|
|
239
|
+
let desc = `- **${tool.name}**`;
|
|
240
|
+
if (tool.description != null && tool.description !== '') {
|
|
241
|
+
desc += `: ${tool.description}`;
|
|
242
|
+
}
|
|
243
|
+
if (tool.parameters) {
|
|
244
|
+
desc += `\n Parameters: ${JSON.stringify(tool.parameters, null, 2).replace(/\n/g, '\n ')}`;
|
|
245
|
+
}
|
|
246
|
+
return desc;
|
|
247
|
+
})
|
|
248
|
+
.join('\n\n');
|
|
249
|
+
|
|
250
|
+
return (
|
|
251
|
+
'\n\n## Programmatic-Only Tools\n\n' +
|
|
252
|
+
'The following tools are available exclusively through the `run_tools_with_code` tool. ' +
|
|
253
|
+
'You cannot call these tools directly; instead, use `run_tools_with_code` with Python code that invokes them.\n\n' +
|
|
254
|
+
toolDescriptions
|
|
255
|
+
);
|
|
210
256
|
}
|
|
211
257
|
|
|
212
258
|
/**
|
|
213
|
-
*
|
|
259
|
+
* Gets the system runnable, creating it lazily if needed.
|
|
260
|
+
* Includes instructions, additional instructions, and programmatic-only tools documentation.
|
|
261
|
+
* Only rebuilds when marked stale (via markToolsAsDiscovered).
|
|
214
262
|
*/
|
|
215
|
-
|
|
263
|
+
get systemRunnable():
|
|
216
264
|
| Runnable<
|
|
217
265
|
BaseMessage[],
|
|
218
266
|
(BaseMessage | SystemMessage)[],
|
|
219
267
|
RunnableConfig<Record<string, unknown>>
|
|
220
268
|
>
|
|
221
269
|
| undefined {
|
|
222
|
-
|
|
223
|
-
|
|
270
|
+
// Return cached if not stale
|
|
271
|
+
if (!this.systemRunnableStale && this.cachedSystemRunnable !== undefined) {
|
|
272
|
+
return this.cachedSystemRunnable;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// Stale or first access - rebuild
|
|
276
|
+
const instructionsString = this.buildInstructionsString();
|
|
277
|
+
this.cachedSystemRunnable = this.buildSystemRunnable(instructionsString);
|
|
278
|
+
this.systemRunnableStale = false;
|
|
279
|
+
return this.cachedSystemRunnable;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Explicitly initializes the system runnable.
|
|
284
|
+
* Call this before async token calculation to ensure system message tokens are counted first.
|
|
285
|
+
*/
|
|
286
|
+
initializeSystemRunnable(): void {
|
|
287
|
+
if (this.systemRunnableStale || this.cachedSystemRunnable === undefined) {
|
|
288
|
+
const instructionsString = this.buildInstructionsString();
|
|
289
|
+
this.cachedSystemRunnable = this.buildSystemRunnable(instructionsString);
|
|
290
|
+
this.systemRunnableStale = false;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Builds the raw instructions string (without creating SystemMessage).
|
|
296
|
+
*/
|
|
297
|
+
private buildInstructionsString(): string {
|
|
298
|
+
let result = this.instructions ?? '';
|
|
224
299
|
|
|
225
300
|
if (
|
|
226
301
|
this.additionalInstructions != null &&
|
|
227
302
|
this.additionalInstructions !== ''
|
|
228
303
|
) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
304
|
+
result = result
|
|
305
|
+
? `${result}\n\n${this.additionalInstructions}`
|
|
306
|
+
: this.additionalInstructions;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
const programmaticToolsDoc = this.buildProgrammaticOnlyToolsInstructions();
|
|
310
|
+
if (programmaticToolsDoc) {
|
|
311
|
+
result = result
|
|
312
|
+
? `${result}${programmaticToolsDoc}`
|
|
313
|
+
: programmaticToolsDoc;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return result;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Build system runnable from pre-built instructions string.
|
|
321
|
+
* Only called when content has actually changed.
|
|
322
|
+
*/
|
|
323
|
+
private buildSystemRunnable(
|
|
324
|
+
instructionsString: string
|
|
325
|
+
):
|
|
326
|
+
| Runnable<
|
|
327
|
+
BaseMessage[],
|
|
328
|
+
(BaseMessage | SystemMessage)[],
|
|
329
|
+
RunnableConfig<Record<string, unknown>>
|
|
330
|
+
>
|
|
331
|
+
| undefined {
|
|
332
|
+
if (!instructionsString) {
|
|
333
|
+
// Remove previous tokens if we had a system message before
|
|
334
|
+
this.instructionTokens -= this.systemMessageTokens;
|
|
335
|
+
this.systemMessageTokens = 0;
|
|
336
|
+
return undefined;
|
|
233
337
|
}
|
|
234
338
|
|
|
339
|
+
let finalInstructions: string | BaseMessageFields = instructionsString;
|
|
340
|
+
|
|
235
341
|
// Handle Anthropic prompt caching
|
|
236
|
-
if (
|
|
237
|
-
finalInstructions != null &&
|
|
238
|
-
finalInstructions !== '' &&
|
|
239
|
-
this.provider === Providers.ANTHROPIC
|
|
240
|
-
) {
|
|
342
|
+
if (this.provider === Providers.ANTHROPIC) {
|
|
241
343
|
const anthropicOptions = this.clientOptions as
|
|
242
344
|
| t.AnthropicClientOptions
|
|
243
345
|
| undefined;
|
|
@@ -253,7 +355,7 @@ export class AgentContext {
|
|
|
253
355
|
content: [
|
|
254
356
|
{
|
|
255
357
|
type: 'text',
|
|
256
|
-
text:
|
|
358
|
+
text: instructionsString,
|
|
257
359
|
cache_control: { type: 'ephemeral' },
|
|
258
360
|
},
|
|
259
361
|
],
|
|
@@ -261,19 +363,18 @@ export class AgentContext {
|
|
|
261
363
|
}
|
|
262
364
|
}
|
|
263
365
|
|
|
264
|
-
|
|
265
|
-
const systemMessage = new SystemMessage(finalInstructions);
|
|
266
|
-
|
|
267
|
-
if (this.tokenCounter) {
|
|
268
|
-
this.instructionTokens += this.tokenCounter(systemMessage);
|
|
269
|
-
}
|
|
366
|
+
const systemMessage = new SystemMessage(finalInstructions);
|
|
270
367
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
368
|
+
// Update token counts (subtract old, add new)
|
|
369
|
+
if (this.tokenCounter) {
|
|
370
|
+
this.instructionTokens -= this.systemMessageTokens;
|
|
371
|
+
this.systemMessageTokens = this.tokenCounter(systemMessage);
|
|
372
|
+
this.instructionTokens += this.systemMessageTokens;
|
|
274
373
|
}
|
|
275
374
|
|
|
276
|
-
return
|
|
375
|
+
return RunnableLambda.from((messages: BaseMessage[]) => {
|
|
376
|
+
return [systemMessage, ...messages];
|
|
377
|
+
}).withConfig({ runName: 'prompt' });
|
|
277
378
|
}
|
|
278
379
|
|
|
279
380
|
/**
|
|
@@ -281,6 +382,9 @@ export class AgentContext {
|
|
|
281
382
|
*/
|
|
282
383
|
reset(): void {
|
|
283
384
|
this.instructionTokens = 0;
|
|
385
|
+
this.systemMessageTokens = 0;
|
|
386
|
+
this.cachedSystemRunnable = undefined;
|
|
387
|
+
this.systemRunnableStale = true;
|
|
284
388
|
this.lastToken = undefined;
|
|
285
389
|
this.indexTokenCountMap = {};
|
|
286
390
|
this.currentUsage = undefined;
|
|
@@ -347,48 +451,6 @@ export class AgentContext {
|
|
|
347
451
|
this.instructionTokens += toolTokens;
|
|
348
452
|
}
|
|
349
453
|
|
|
350
|
-
/**
|
|
351
|
-
* Gets a map of tools that allow programmatic (code_execution) calling.
|
|
352
|
-
* Filters toolMap based on toolRegistry's allowed_callers settings.
|
|
353
|
-
* @returns ToolMap containing only tools that allow code_execution
|
|
354
|
-
*/
|
|
355
|
-
getProgrammaticToolMap(): t.ToolMap {
|
|
356
|
-
const programmaticMap: t.ToolMap = new Map();
|
|
357
|
-
|
|
358
|
-
if (!this.toolMap) {
|
|
359
|
-
return programmaticMap;
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
for (const [name, tool] of this.toolMap) {
|
|
363
|
-
const toolDef = this.toolRegistry?.get(name);
|
|
364
|
-
if (toolAllowsCaller(toolDef, 'code_execution')) {
|
|
365
|
-
programmaticMap.set(name, tool);
|
|
366
|
-
}
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
return programmaticMap;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
/**
|
|
373
|
-
* Gets tool definitions for tools that allow programmatic calling.
|
|
374
|
-
* Used to send to the Code API for stub generation.
|
|
375
|
-
* @returns Array of LCTool definitions for programmatic tools
|
|
376
|
-
*/
|
|
377
|
-
getProgrammaticToolDefs(): t.LCTool[] {
|
|
378
|
-
if (!this.toolRegistry) {
|
|
379
|
-
return [];
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
const defs: t.LCTool[] = [];
|
|
383
|
-
for (const [_name, toolDef] of this.toolRegistry) {
|
|
384
|
-
if (toolAllowsCaller(toolDef, 'code_execution')) {
|
|
385
|
-
defs.push(toolDef);
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return defs;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
454
|
/**
|
|
393
455
|
* Gets the tool registry for deferred tools (for tool search).
|
|
394
456
|
* @param onlyDeferred If true, only returns tools with defer_loading=true
|
|
@@ -413,12 +475,22 @@ export class AgentContext {
|
|
|
413
475
|
/**
|
|
414
476
|
* Marks tools as discovered via tool search.
|
|
415
477
|
* Discovered tools will be included in the next model binding.
|
|
478
|
+
* Only marks system runnable stale if NEW tools were actually added.
|
|
416
479
|
* @param toolNames - Array of discovered tool names
|
|
480
|
+
* @returns true if any new tools were discovered
|
|
417
481
|
*/
|
|
418
|
-
markToolsAsDiscovered(toolNames: string[]):
|
|
482
|
+
markToolsAsDiscovered(toolNames: string[]): boolean {
|
|
483
|
+
let hasNewDiscoveries = false;
|
|
419
484
|
for (const name of toolNames) {
|
|
420
|
-
this.discoveredToolNames.
|
|
485
|
+
if (!this.discoveredToolNames.has(name)) {
|
|
486
|
+
this.discoveredToolNames.add(name);
|
|
487
|
+
hasNewDiscoveries = true;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
if (hasNewDiscoveries) {
|
|
491
|
+
this.systemRunnableStale = true;
|
|
421
492
|
}
|
|
493
|
+
return hasNewDiscoveries;
|
|
422
494
|
}
|
|
423
495
|
|
|
424
496
|
/**
|