@librechat/agents 3.0.66 → 3.0.68

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.
Files changed (39) hide show
  1. package/dist/cjs/common/enum.cjs +3 -1
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/main.cjs +14 -7
  4. package/dist/cjs/main.cjs.map +1 -1
  5. package/dist/cjs/messages/tools.cjs +2 -2
  6. package/dist/cjs/messages/tools.cjs.map +1 -1
  7. package/dist/cjs/tools/ToolNode.cjs +1 -1
  8. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  9. package/dist/cjs/tools/{ToolSearchRegex.cjs → ToolSearch.cjs} +318 -63
  10. package/dist/cjs/tools/ToolSearch.cjs.map +1 -0
  11. package/dist/esm/common/enum.mjs +3 -1
  12. package/dist/esm/common/enum.mjs.map +1 -1
  13. package/dist/esm/main.mjs +1 -1
  14. package/dist/esm/messages/tools.mjs +2 -2
  15. package/dist/esm/messages/tools.mjs.map +1 -1
  16. package/dist/esm/tools/ToolNode.mjs +1 -1
  17. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  18. package/dist/esm/tools/{ToolSearchRegex.mjs → ToolSearch.mjs} +311 -63
  19. package/dist/esm/tools/ToolSearch.mjs.map +1 -0
  20. package/dist/types/common/enum.d.ts +4 -2
  21. package/dist/types/index.d.ts +1 -1
  22. package/dist/types/tools/ToolSearch.d.ts +133 -0
  23. package/dist/types/types/tools.d.ts +8 -2
  24. package/package.json +2 -2
  25. package/src/common/enum.ts +3 -1
  26. package/src/index.ts +1 -1
  27. package/src/messages/__tests__/tools.test.ts +21 -21
  28. package/src/messages/tools.ts +2 -2
  29. package/src/scripts/programmatic_exec_agent.ts +4 -4
  30. package/src/scripts/{tool_search_regex.ts → tool_search.ts} +5 -5
  31. package/src/tools/ToolNode.ts +1 -1
  32. package/src/tools/{ToolSearchRegex.ts → ToolSearch.ts} +390 -69
  33. package/src/tools/__tests__/{ToolSearchRegex.integration.test.ts → ToolSearch.integration.test.ts} +6 -6
  34. package/src/tools/__tests__/ToolSearch.test.ts +734 -0
  35. package/src/types/tools.ts +9 -2
  36. package/dist/cjs/tools/ToolSearchRegex.cjs.map +0 -1
  37. package/dist/esm/tools/ToolSearchRegex.mjs.map +0 -1
  38. package/dist/types/tools/ToolSearchRegex.d.ts +0 -80
  39. package/src/tools/__tests__/ToolSearchRegex.test.ts +0 -232
@@ -0,0 +1,133 @@
1
+ import { z } from 'zod';
2
+ import { DynamicStructuredTool } from '@langchain/core/tools';
3
+ import type * as t from '@/types';
4
+ /** Zod schema type for tool search parameters */
5
+ type ToolSearchSchema = z.ZodObject<{
6
+ query: z.ZodDefault<z.ZodOptional<z.ZodString>>;
7
+ fields: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEnum<['name', 'description', 'parameters']>>>>;
8
+ max_results: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
9
+ mcp_server: z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString>]>>;
10
+ }>;
11
+ /**
12
+ * Creates the Zod schema with dynamic query description based on mode.
13
+ * @param mode - The search mode determining query interpretation
14
+ * @returns Zod schema for tool search parameters
15
+ */
16
+ declare function createToolSearchSchema(mode: t.ToolSearchMode): ToolSearchSchema;
17
+ /**
18
+ * Extracts the MCP server name from a tool name.
19
+ * MCP tools follow the pattern: toolName_mcp_serverName
20
+ * @param toolName - The full tool name
21
+ * @returns The server name if it's an MCP tool, undefined otherwise
22
+ */
23
+ declare function extractMcpServerName(toolName: string): string | undefined;
24
+ /**
25
+ * Checks if a tool belongs to a specific MCP server.
26
+ * @param toolName - The full tool name
27
+ * @param serverName - The server name to match
28
+ * @returns True if the tool belongs to the specified server
29
+ */
30
+ declare function isFromMcpServer(toolName: string, serverName: string): boolean;
31
+ /**
32
+ * Checks if a tool belongs to any of the specified MCP servers.
33
+ * @param toolName - The full tool name
34
+ * @param serverNames - Array of server names to match
35
+ * @returns True if the tool belongs to any of the specified servers
36
+ */
37
+ declare function isFromAnyMcpServer(toolName: string, serverNames: string[]): boolean;
38
+ /**
39
+ * Normalizes server filter input to always be an array.
40
+ * @param serverFilter - String, array of strings, or undefined
41
+ * @returns Array of server names (empty if none specified)
42
+ */
43
+ declare function normalizeServerFilter(serverFilter: string | string[] | undefined): string[];
44
+ /**
45
+ * Escapes special regex characters in a string to use as a literal pattern.
46
+ * @param pattern - The string to escape
47
+ * @returns The escaped string safe for use in a RegExp
48
+ */
49
+ declare function escapeRegexSpecialChars(pattern: string): string;
50
+ /**
51
+ * Counts the maximum nesting depth of groups in a regex pattern.
52
+ * @param pattern - The regex pattern to analyze
53
+ * @returns The maximum nesting depth
54
+ */
55
+ declare function countNestedGroups(pattern: string): number;
56
+ /**
57
+ * Detects nested quantifiers that can cause catastrophic backtracking.
58
+ * Patterns like (a+)+, (a*)*, (a+)*, etc.
59
+ * @param pattern - The regex pattern to check
60
+ * @returns True if nested quantifiers are detected
61
+ */
62
+ declare function hasNestedQuantifiers(pattern: string): boolean;
63
+ /**
64
+ * Checks if a regex pattern contains potentially dangerous constructs.
65
+ * @param pattern - The regex pattern to validate
66
+ * @returns True if the pattern is dangerous
67
+ */
68
+ declare function isDangerousPattern(pattern: string): boolean;
69
+ /**
70
+ * Sanitizes a regex pattern for safe execution.
71
+ * If the pattern is dangerous, it will be escaped to a literal string search.
72
+ * @param pattern - The regex pattern to sanitize
73
+ * @returns Object containing the safe pattern and whether it was escaped
74
+ */
75
+ declare function sanitizeRegex(pattern: string): {
76
+ safe: string;
77
+ wasEscaped: boolean;
78
+ };
79
+ /**
80
+ * Performs safe local substring search without regex.
81
+ * Uses case-insensitive String.includes() for complete safety against ReDoS.
82
+ * @param tools - Array of tool metadata to search
83
+ * @param query - The search term (treated as literal substring)
84
+ * @param fields - Which fields to search
85
+ * @param maxResults - Maximum results to return
86
+ * @returns Search response with matching tools
87
+ */
88
+ declare function performLocalSearch(tools: t.ToolMetadata[], query: string, fields: string[], maxResults: number): t.ToolSearchResponse;
89
+ /**
90
+ * Extracts the base tool name (without MCP server suffix) from a full tool name.
91
+ * @param toolName - The full tool name
92
+ * @returns The base tool name without server suffix
93
+ */
94
+ declare function getBaseToolName(toolName: string): string;
95
+ /**
96
+ * Formats a server listing response when listing all tools from MCP server(s).
97
+ * Provides a cohesive view of all tools grouped by server.
98
+ * NOTE: This is a PREVIEW only - tools are NOT discovered/loaded.
99
+ * @param tools - Array of tool metadata from the server(s)
100
+ * @param serverNames - The MCP server name(s)
101
+ * @returns Formatted string showing all tools from the server(s)
102
+ */
103
+ declare function formatServerListing(tools: t.ToolMetadata[], serverNames: string | string[]): string;
104
+ /**
105
+ * Creates a Tool Search tool for discovering tools from a large registry.
106
+ *
107
+ * This tool enables AI agents to dynamically discover tools from a large library
108
+ * without loading all tool definitions into the LLM context window. The agent
109
+ * can search for relevant tools on-demand.
110
+ *
111
+ * **Modes:**
112
+ * - `code_interpreter` (default): Uses external sandbox for regex search. Safer for complex patterns.
113
+ * - `local`: Uses safe substring matching locally. No network call, faster, completely safe from ReDoS.
114
+ *
115
+ * The tool registry can be provided either:
116
+ * 1. At initialization time via params.toolRegistry
117
+ * 2. At runtime via config.configurable.toolRegistry when invoking
118
+ *
119
+ * @param params - Configuration parameters for the tool (toolRegistry is optional)
120
+ * @returns A LangChain DynamicStructuredTool for tool searching
121
+ *
122
+ * @example
123
+ * // Option 1: Code interpreter mode (regex via sandbox)
124
+ * const tool = createToolSearch({ apiKey, toolRegistry });
125
+ * await tool.invoke({ query: 'expense.*report' });
126
+ *
127
+ * @example
128
+ * // Option 2: Local mode (safe substring search, no API key needed)
129
+ * const tool = createToolSearch({ mode: 'local', toolRegistry });
130
+ * await tool.invoke({ query: 'expense' });
131
+ */
132
+ declare function createToolSearch(initParams?: t.ToolSearchParams): DynamicStructuredTool<ReturnType<typeof createToolSearchSchema>>;
133
+ export { createToolSearch, performLocalSearch, extractMcpServerName, isFromMcpServer, isFromAnyMcpServer, normalizeServerFilter, getBaseToolName, formatServerListing, sanitizeRegex, escapeRegexSpecialChars, isDangerousPattern, countNestedGroups, hasNestedQuantifiers, };
@@ -99,12 +99,18 @@ export type ProgrammaticCache = {
99
99
  toolMap: ToolMap;
100
100
  toolDefs: LCTool[];
101
101
  };
102
- /** Parameters for creating a Tool Search Regex tool */
103
- export type ToolSearchRegexParams = {
102
+ /** Search mode: code_interpreter uses external sandbox, local uses safe substring matching */
103
+ export type ToolSearchMode = 'code_interpreter' | 'local';
104
+ /** Parameters for creating a Tool Search tool */
105
+ export type ToolSearchParams = {
104
106
  apiKey?: string;
105
107
  toolRegistry?: LCToolRegistry;
106
108
  onlyDeferred?: boolean;
107
109
  baseUrl?: string;
110
+ /** Search mode: 'code_interpreter' (default) uses sandbox for regex, 'local' uses safe substring matching */
111
+ mode?: ToolSearchMode;
112
+ /** Filter tools to only those from specific MCP server(s). Can be a single name or array of names. */
113
+ mcpServer?: string | string[];
108
114
  [key: string]: unknown;
109
115
  };
110
116
  /** Simplified tool metadata for search purposes */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.0.66",
3
+ "version": "3.0.68",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -57,7 +57,7 @@
57
57
  "memory": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/memory.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
58
58
  "tool": "node --trace-warnings -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'openrouter' --name 'Jo' --location 'New York, NY'",
59
59
  "search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/search.ts --provider 'bedrock' --name 'Jo' --location 'New York, NY'",
60
- "tool_search_regex": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tool_search_regex.ts",
60
+ "tool_search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tool_search.ts",
61
61
  "programmatic_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/programmatic_exec.ts",
62
62
  "code_exec_ptc": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec_ptc.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
63
63
  "programmatic_exec_agent": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/programmatic_exec_agent.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
@@ -159,11 +159,13 @@ export enum Callback {
159
159
  export enum Constants {
160
160
  OFFICIAL_CODE_BASEURL = 'https://api.librechat.ai/v1',
161
161
  EXECUTE_CODE = 'execute_code',
162
- TOOL_SEARCH_REGEX = 'tool_search_regex',
162
+ TOOL_SEARCH = 'tool_search',
163
163
  PROGRAMMATIC_TOOL_CALLING = 'run_tools_with_code',
164
164
  WEB_SEARCH = 'web_search',
165
165
  CONTENT_AND_ARTIFACT = 'content_and_artifact',
166
166
  LC_TRANSFER_TO_ = 'lc_transfer_to_',
167
+ /** Delimiter for MCP tools: toolName_mcp_serverName */
168
+ MCP_DELIMITER = '_mcp_',
167
169
  }
168
170
 
169
171
  export enum TitleMethod {
package/src/index.ts CHANGED
@@ -12,7 +12,7 @@ export * from './graphs';
12
12
  export * from './tools/Calculator';
13
13
  export * from './tools/CodeExecutor';
14
14
  export * from './tools/ProgrammaticToolCalling';
15
- export * from './tools/ToolSearchRegex';
15
+ export * from './tools/ToolSearch';
16
16
  export * from './tools/handlers';
17
17
  export * from './tools/search';
18
18
 
@@ -41,7 +41,7 @@ describe('Tool Discovery Functions', () => {
41
41
  return new ToolMessage({
42
42
  content: `Found ${discoveredTools.length} tools`,
43
43
  tool_call_id: toolCallId,
44
- name: Constants.TOOL_SEARCH_REGEX,
44
+ name: Constants.TOOL_SEARCH,
45
45
  artifact: {
46
46
  tool_references: discoveredTools.map((name) => ({
47
47
  tool_name: name,
@@ -79,7 +79,7 @@ describe('Tool Discovery Functions', () => {
79
79
  createAIMessage('Searching...', [
80
80
  {
81
81
  id: 'call_1',
82
- name: Constants.TOOL_SEARCH_REGEX,
82
+ name: Constants.TOOL_SEARCH,
83
83
  args: { pattern: 'database' },
84
84
  },
85
85
  ]),
@@ -97,12 +97,12 @@ describe('Tool Discovery Functions', () => {
97
97
  createAIMessage('Searching...', [
98
98
  {
99
99
  id: 'call_1',
100
- name: Constants.TOOL_SEARCH_REGEX,
100
+ name: Constants.TOOL_SEARCH,
101
101
  args: { pattern: 'database' },
102
102
  },
103
103
  {
104
104
  id: 'call_2',
105
- name: Constants.TOOL_SEARCH_REGEX,
105
+ name: Constants.TOOL_SEARCH,
106
106
  args: { pattern: 'file' },
107
107
  },
108
108
  ]),
@@ -137,7 +137,7 @@ describe('Tool Discovery Functions', () => {
137
137
  new ToolMessage({
138
138
  content: 'Some result',
139
139
  tool_call_id: 'orphan_call',
140
- name: Constants.TOOL_SEARCH_REGEX,
140
+ name: Constants.TOOL_SEARCH,
141
141
  }),
142
142
  ];
143
143
 
@@ -153,7 +153,7 @@ describe('Tool Discovery Functions', () => {
153
153
  createAIMessage('Searching...', [
154
154
  {
155
155
  id: 'old_call',
156
- name: Constants.TOOL_SEARCH_REGEX,
156
+ name: Constants.TOOL_SEARCH,
157
157
  args: { pattern: 'old' },
158
158
  },
159
159
  ]),
@@ -163,7 +163,7 @@ describe('Tool Discovery Functions', () => {
163
163
  createAIMessage('Searching again...', [
164
164
  {
165
165
  id: 'new_call',
166
- name: Constants.TOOL_SEARCH_REGEX,
166
+ name: Constants.TOOL_SEARCH,
167
167
  args: { pattern: 'new' },
168
168
  },
169
169
  ]),
@@ -182,7 +182,7 @@ describe('Tool Discovery Functions', () => {
182
182
  createAIMessage('Working...', [
183
183
  {
184
184
  id: 'search_call',
185
- name: Constants.TOOL_SEARCH_REGEX,
185
+ name: Constants.TOOL_SEARCH,
186
186
  args: { pattern: 'test' },
187
187
  },
188
188
  { id: 'other_call', name: 'get_weather', args: { city: 'NYC' } },
@@ -202,14 +202,14 @@ describe('Tool Discovery Functions', () => {
202
202
  createAIMessage('Searching...', [
203
203
  {
204
204
  id: 'call_1',
205
- name: Constants.TOOL_SEARCH_REGEX,
205
+ name: Constants.TOOL_SEARCH,
206
206
  args: { pattern: 'xyz' },
207
207
  },
208
208
  ]),
209
209
  new ToolMessage({
210
210
  content: 'No tools found',
211
211
  tool_call_id: 'call_1',
212
- name: Constants.TOOL_SEARCH_REGEX,
212
+ name: Constants.TOOL_SEARCH,
213
213
  artifact: {
214
214
  tool_references: [],
215
215
  metadata: { total_searched: 10, pattern: 'xyz' },
@@ -228,14 +228,14 @@ describe('Tool Discovery Functions', () => {
228
228
  createAIMessage('Searching...', [
229
229
  {
230
230
  id: 'call_1',
231
- name: Constants.TOOL_SEARCH_REGEX,
231
+ name: Constants.TOOL_SEARCH,
232
232
  args: { pattern: 'test' },
233
233
  },
234
234
  ]),
235
235
  new ToolMessage({
236
236
  content: 'Error occurred',
237
237
  tool_call_id: 'call_1',
238
- name: Constants.TOOL_SEARCH_REGEX,
238
+ name: Constants.TOOL_SEARCH,
239
239
  // No artifact
240
240
  }),
241
241
  ];
@@ -251,7 +251,7 @@ describe('Tool Discovery Functions', () => {
251
251
  createAIMessage('Searching...', [
252
252
  {
253
253
  id: 'call_1',
254
- name: Constants.TOOL_SEARCH_REGEX,
254
+ name: Constants.TOOL_SEARCH,
255
255
  args: { pattern: 'test' },
256
256
  },
257
257
  ]),
@@ -271,7 +271,7 @@ describe('Tool Discovery Functions', () => {
271
271
  createAIMessage('First search', [
272
272
  {
273
273
  id: 'first_call',
274
- name: Constants.TOOL_SEARCH_REGEX,
274
+ name: Constants.TOOL_SEARCH,
275
275
  args: { pattern: 'first' },
276
276
  },
277
277
  ]),
@@ -280,7 +280,7 @@ describe('Tool Discovery Functions', () => {
280
280
  createAIMessage('Second search', [
281
281
  {
282
282
  id: 'second_call',
283
- name: Constants.TOOL_SEARCH_REGEX,
283
+ name: Constants.TOOL_SEARCH,
284
284
  args: { pattern: 'second' },
285
285
  },
286
286
  ]),
@@ -301,7 +301,7 @@ describe('Tool Discovery Functions', () => {
301
301
  createAIMessage('Searching...', [
302
302
  {
303
303
  id: 'call_1',
304
- name: Constants.TOOL_SEARCH_REGEX,
304
+ name: Constants.TOOL_SEARCH,
305
305
  args: { pattern: 'test' },
306
306
  },
307
307
  ]),
@@ -335,7 +335,7 @@ describe('Tool Discovery Functions', () => {
335
335
  new ToolMessage({
336
336
  content: 'Result',
337
337
  tool_call_id: 'orphan',
338
- name: Constants.TOOL_SEARCH_REGEX,
338
+ name: Constants.TOOL_SEARCH,
339
339
  }),
340
340
  ];
341
341
 
@@ -364,7 +364,7 @@ describe('Tool Discovery Functions', () => {
364
364
  createAIMessage('Working...', [
365
365
  {
366
366
  id: 'search_call',
367
- name: Constants.TOOL_SEARCH_REGEX,
367
+ name: Constants.TOOL_SEARCH,
368
368
  args: { pattern: 'test' },
369
369
  },
370
370
  { id: 'weather_call', name: 'get_weather', args: { city: 'NYC' } },
@@ -384,7 +384,7 @@ describe('Tool Discovery Functions', () => {
384
384
  createAIMessage('Searching...', [
385
385
  {
386
386
  id: 'old_call',
387
- name: Constants.TOOL_SEARCH_REGEX,
387
+ name: Constants.TOOL_SEARCH,
388
388
  args: { pattern: 'old' },
389
389
  },
390
390
  ]),
@@ -410,7 +410,7 @@ describe('Tool Discovery Functions', () => {
410
410
  createAIMessage('Searching...', [
411
411
  {
412
412
  id: 'call_1',
413
- name: Constants.TOOL_SEARCH_REGEX,
413
+ name: Constants.TOOL_SEARCH,
414
414
  args: { pattern: 'test' },
415
415
  },
416
416
  ]),
@@ -446,7 +446,7 @@ describe('Tool Discovery Functions', () => {
446
446
  createAIMessage('Searching...', [
447
447
  {
448
448
  id: 'call_1',
449
- name: Constants.TOOL_SEARCH_REGEX,
449
+ name: Constants.TOOL_SEARCH,
450
450
  args: { pattern: 'test' },
451
451
  },
452
452
  ]),
@@ -43,7 +43,7 @@ export function extractToolDiscoveries(messages: BaseMessage[]): string[] {
43
43
  for (let i = latestAIParentIndex + 1; i < messages.length; i++) {
44
44
  const msg = messages[i];
45
45
  if (!(msg instanceof ToolMessage)) continue;
46
- if (msg.name !== Constants.TOOL_SEARCH_REGEX) continue;
46
+ if (msg.name !== Constants.TOOL_SEARCH) continue;
47
47
  if (!toolCallIds.has(msg.tool_call_id)) continue;
48
48
 
49
49
  // This is a tool search result from the current turn
@@ -88,7 +88,7 @@ export function hasToolSearchInCurrentTurn(messages: BaseMessage[]): boolean {
88
88
  const msg = messages[i];
89
89
  if (
90
90
  msg instanceof ToolMessage &&
91
- msg.name === Constants.TOOL_SEARCH_REGEX &&
91
+ msg.name === Constants.TOOL_SEARCH &&
92
92
  toolCallIds.has(msg.tool_call_id)
93
93
  ) {
94
94
  return true;
@@ -23,7 +23,7 @@ import type { RunnableConfig } from '@langchain/core/runnables';
23
23
  import type * as t from '@/types';
24
24
  import { createCodeExecutionTool } from '@/tools/CodeExecutor';
25
25
  import { createProgrammaticToolCallingTool } from '@/tools/ProgrammaticToolCalling';
26
- import { createToolSearchRegexTool } from '@/tools/ToolSearchRegex';
26
+ import { createToolSearch } from '@/tools/ToolSearch';
27
27
  import { getLLMConfig } from '@/utils/llmConfig';
28
28
  import { getArgs } from '@/scripts/args';
29
29
  import { Run } from '@/run';
@@ -40,7 +40,7 @@ import {
40
40
 
41
41
  /**
42
42
  * Tool registry only needs business logic tools that require filtering.
43
- * Special tools (execute_code, run_tools_with_code, tool_search_regex)
43
+ * Special tools (execute_code, run_tools_with_code, tool_search)
44
44
  * are always bound directly to the LLM and don't need registry entries.
45
45
  */
46
46
  function createAgentToolRegistry(): t.LCToolRegistry {
@@ -73,7 +73,7 @@ async function main(): Promise<void> {
73
73
  // Create special tools (PTC, code execution, tool search)
74
74
  const codeExecTool = createCodeExecutionTool();
75
75
  const ptcTool = createProgrammaticToolCallingTool();
76
- const toolSearchTool = createToolSearchRegexTool();
76
+ const toolSearchTool = createToolSearch();
77
77
 
78
78
  // Build complete tool list and map
79
79
  const allTools = [...mockTools, codeExecTool, ptcTool, toolSearchTool];
@@ -199,7 +199,7 @@ Use the run_tools_with_code tool to do this efficiently - don't call each tool s
199
199
  console.log('='.repeat(70));
200
200
  console.log('\nKey observations:');
201
201
  console.log(
202
- '1. LLM only sees tools with allowed_callers including "direct" (get_weather, execute_code, run_tools_with_code, tool_search_regex)'
202
+ '1. LLM only sees tools with allowed_callers including "direct" (get_weather, execute_code, run_tools_with_code, tool_search)'
203
203
  );
204
204
  console.log(
205
205
  '2. When PTC is invoked, ToolNode automatically injects programmatic tools (get_team_members, get_expenses, get_weather)'
@@ -1,7 +1,7 @@
1
- // src/scripts/tool_search_regex.ts
1
+ // src/scripts/tool_search.ts
2
2
  /**
3
3
  * Test script for the Tool Search Regex tool.
4
- * Run with: npm run tool_search_regex
4
+ * Run with: npm run tool_search
5
5
  *
6
6
  * Demonstrates runtime registry injection - the tool registry is passed
7
7
  * at invocation time, not at initialization time.
@@ -9,7 +9,7 @@
9
9
  import { config } from 'dotenv';
10
10
  config();
11
11
 
12
- import { createToolSearchRegexTool } from '@/tools/ToolSearchRegex';
12
+ import { createToolSearch } from '@/tools/ToolSearch';
13
13
  import type { LCToolRegistry } from '@/types';
14
14
  import { createToolSearchToolRegistry } from '@/test/mockTools';
15
15
 
@@ -22,7 +22,7 @@ interface RunTestOptions {
22
22
  }
23
23
 
24
24
  async function runTest(
25
- searchTool: ReturnType<typeof createToolSearchRegexTool>,
25
+ searchTool: ReturnType<typeof createToolSearch>,
26
26
  testName: string,
27
27
  query: string,
28
28
  options: RunTestOptions
@@ -82,7 +82,7 @@ async function main(): Promise<void> {
82
82
  );
83
83
 
84
84
  console.log('\nCreating Tool Search Regex tool WITH registry for testing...');
85
- const searchTool = createToolSearchRegexTool({ apiKey, toolRegistry });
85
+ const searchTool = createToolSearch({ apiKey, toolRegistry });
86
86
  console.log('Tool created successfully!');
87
87
  console.log(
88
88
  'Note: In production, ToolNode injects toolRegistry via params when invoked through the graph.\n'
@@ -132,7 +132,7 @@ export class ToolNode<T = any> extends RunnableCallable<T, T> {
132
132
  toolMap,
133
133
  toolDefs,
134
134
  };
135
- } else if (call.name === Constants.TOOL_SEARCH_REGEX) {
135
+ } else if (call.name === Constants.TOOL_SEARCH) {
136
136
  invokeParams = {
137
137
  ...invokeParams,
138
138
  toolRegistry: this.toolRegistry,