@librechat/agents 3.1.93 → 3.1.95

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.
@@ -464,6 +464,90 @@ function unwrapToolResponse(result, isMCPTool) {
464
464
  // Not a formatted response, return as-is
465
465
  return result;
466
466
  }
467
+ function detectSchemaKind(schema) {
468
+ const kind = { object: false, string: false };
469
+ if (!schema || typeof schema !== 'object') {
470
+ return kind;
471
+ }
472
+ const jsonSchemaType = schema.type;
473
+ if (jsonSchemaType === 'object') {
474
+ kind.object = true;
475
+ }
476
+ else if (jsonSchemaType === 'string') {
477
+ kind.string = true;
478
+ }
479
+ else if (Array.isArray(jsonSchemaType)) {
480
+ kind.object = jsonSchemaType.includes('object');
481
+ kind.string = jsonSchemaType.includes('string');
482
+ }
483
+ const zodDef = schema._def;
484
+ if (!zodDef || typeof zodDef !== 'object') {
485
+ return kind;
486
+ }
487
+ const zodType = zodDef.type;
488
+ const zodTypeName = zodDef
489
+ .typeName;
490
+ if (zodType === 'object' || zodTypeName === 'ZodObject') {
491
+ kind.object = true;
492
+ }
493
+ else if (zodType === 'string' || zodTypeName === 'ZodString') {
494
+ kind.string = true;
495
+ }
496
+ const innerSchema = zodDef.innerType ?? zodDef.schema;
497
+ if (innerSchema) {
498
+ const innerKind = detectSchemaKind(innerSchema);
499
+ kind.object ||= innerKind.object;
500
+ kind.string ||= innerKind.string;
501
+ }
502
+ const options = zodDef.options;
503
+ if (Array.isArray(options)) {
504
+ for (const option of options) {
505
+ const optionKind = detectSchemaKind(option);
506
+ kind.object ||= optionKind.object;
507
+ kind.string ||= optionKind.string;
508
+ }
509
+ }
510
+ return kind;
511
+ }
512
+ function getToolInputSchemaKind(tool) {
513
+ if (tool.constructor.name === 'DynamicTool') {
514
+ return { object: false, string: true };
515
+ }
516
+ const schema = tool.schema;
517
+ return detectSchemaKind(schema);
518
+ }
519
+ function normalizeToolInput(input, tool) {
520
+ const schemaKind = getToolInputSchemaKind(tool);
521
+ if (typeof input !== 'string') {
522
+ if (!schemaKind.string || schemaKind.object) {
523
+ return input;
524
+ }
525
+ const inputValue = input.input;
526
+ if (typeof inputValue === 'string') {
527
+ return input;
528
+ }
529
+ return JSON.stringify(input);
530
+ }
531
+ if (!schemaKind.object || schemaKind.string) {
532
+ return input;
533
+ }
534
+ const trimmed = input.trim();
535
+ if (!trimmed.startsWith('{')) {
536
+ return input;
537
+ }
538
+ try {
539
+ const parsed = JSON.parse(trimmed);
540
+ if (typeof parsed === 'object' &&
541
+ parsed !== null &&
542
+ !Array.isArray(parsed)) {
543
+ return parsed;
544
+ }
545
+ }
546
+ catch {
547
+ return input;
548
+ }
549
+ return input;
550
+ }
467
551
  /**
468
552
  * Executes tools in parallel when requested by the API.
469
553
  * Uses Promise.all for parallel execution, catching individual errors.
@@ -484,7 +568,7 @@ async function executeTools(toolCalls, toolMap, programmaticToolName = _enum.Con
484
568
  };
485
569
  }
486
570
  try {
487
- const result = await tool.invoke(call.input, {
571
+ const result = await tool.invoke(normalizeToolInput(call.input, tool), {
488
572
  metadata: { [programmaticToolName]: true },
489
573
  });
490
574
  const isMCPTool = tool.mcp === true;
@@ -1 +1 @@
1
- {"version":3,"file":"ProgrammaticToolCalling.cjs","sources":["../../../src/tools/ProgrammaticToolCalling.ts"],"sourcesContent":["// src/tools/ProgrammaticToolCalling.ts\nimport { config } from 'dotenv';\nimport fetch, { RequestInit } from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { ProgrammaticToolCallingJsonSchema } from './ptcTimeout';\nimport type * as t from '@/types';\nimport {\n CODE_ARTIFACT_PATH_GUIDANCE,\n appendCodeSessionFileSummary,\n appendFailedExecutionFileReminder,\n buildCodeApiHttpErrorMessage,\n emptyOutputMessage,\n getCodeBaseURL,\n appendTmpScratchReminder,\n resolveCodeApiAuthHeaders,\n} from './CodeExecutor';\nimport {\n clampCodeApiRunTimeoutMs,\n createCodeApiRunTimeoutSchema,\n resolveCodeApiRunTimeoutMs,\n} from './ptcTimeout';\nimport { Constants } from '@/common';\n\nconfig();\n\n/** Default max round-trips to prevent infinite loops */\nconst DEFAULT_MAX_ROUND_TRIPS = 20;\n\nconst DEFAULT_RUN_TIMEOUT_MS = resolveCodeApiRunTimeoutMs();\n\n// ============================================================================\n// Description Components (Single Source of Truth)\n// ============================================================================\n\nconst STATELESS_WARNING = `CRITICAL - STATELESS EXECUTION:\nEach call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.\nYou MUST complete your entire workflow in ONE code block: query → process → output.\nDO NOT split work across multiple calls expecting to reuse variables.`;\n\nconst CORE_RULES = `Rules:\n- One call: state does not persist\n- Auto-wrapped async; use await, no main()/asyncio.run()\n- Tools are pre-defined—DO NOT write function definitions\n- Call tools with keyword args only (await tool(arg=value), never pass a dict)\n- Tool results are decoded Python values (dict/list/str)\n- Only print() output returns to the model\n- ${CODE_ARTIFACT_PATH_GUIDANCE}\n- timeout caps one sandbox run/replay iteration, not the total multi-round-trip workflow`;\n\nconst ADDITIONAL_RULES =\n '- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix';\n\nconst EXAMPLES = `Example (Complete workflow in one call):\n # Query data\n data = await query_database(sql=\"SELECT * FROM users\")\n # Process it\n df = pd.DataFrame(data)\n summary = df.groupby('region').sum()\n # Output results\n await write_to_sheet(spreadsheet_id=sid, data=summary.to_dict())\n print(f\"Wrote {len(summary)} rows\")\n\nExample (Parallel calls):\n sf, ny = await asyncio.gather(get_weather(city=\"SF\"), get_weather(city=\"NY\"))\n print(f\"SF: {sf}, NY: {ny}\")`;\n\n// ============================================================================\n// Schema\n// ============================================================================\n\nconst CODE_PARAM_DESCRIPTION = `Python code that calls tools programmatically. Tools are available as async functions.\n\n${STATELESS_WARNING}\n\nYour code is auto-wrapped in async context. Just write logic with await—no boilerplate needed.\n\n${EXAMPLES}\n\n${CORE_RULES}`;\n\nexport function createProgrammaticToolCallingSchema(\n maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS\n): ProgrammaticToolCallingJsonSchema {\n return {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n minLength: 1,\n description: CODE_PARAM_DESCRIPTION,\n },\n timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),\n },\n required: ['code'],\n } as const;\n}\n\nexport const ProgrammaticToolCallingSchema =\n createProgrammaticToolCallingSchema();\n\nexport const ProgrammaticToolCallingName = Constants.PROGRAMMATIC_TOOL_CALLING;\n\nexport const ProgrammaticToolCallingDescription = `\nRun tools via Python code. Auto-wrapped in async context—just use \\`await\\` directly.\n\n${STATELESS_WARNING}\n\n${CORE_RULES}\n${ADDITIONAL_RULES}\n\nWhen to use: loops, conditionals, parallel (\\`asyncio.gather\\`), multi-step pipelines.\n\n${EXAMPLES}\n`.trim();\n\nexport const ProgrammaticToolCallingDefinition = {\n name: ProgrammaticToolCallingName,\n description: ProgrammaticToolCallingDescription,\n schema: ProgrammaticToolCallingSchema,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Python reserved keywords that get `_tool` suffix in Code API */\nconst PYTHON_KEYWORDS = new Set([\n 'False',\n 'None',\n 'True',\n 'and',\n 'as',\n 'assert',\n 'async',\n 'await',\n 'break',\n 'class',\n 'continue',\n 'def',\n 'del',\n 'elif',\n 'else',\n 'except',\n 'finally',\n 'for',\n 'from',\n 'global',\n 'if',\n 'import',\n 'in',\n 'is',\n 'lambda',\n 'nonlocal',\n 'not',\n 'or',\n 'pass',\n 'raise',\n 'return',\n 'try',\n 'while',\n 'with',\n 'yield',\n]);\n\nexport type FetchSessionFilesScope =\n | { kind: 'skill'; id: string; version: number }\n | { kind: 'agent' | 'user'; id: string; version?: never };\n\ntype CodeApiSessionFileWire = {\n id?: unknown;\n name?: unknown;\n metadata?: unknown;\n resource_id?: unknown;\n storage_session_id?: unknown;\n};\n\ntype CodeApiSessionFileMetadata = {\n 'original-filename'?: unknown;\n};\n\nfunction isFetchSessionFilesScope(\n value: unknown\n): value is FetchSessionFilesScope {\n if (value == null || typeof value !== 'object') {\n return false;\n }\n const scope = value as { kind?: unknown; id?: unknown; version?: unknown };\n if (\n (scope.kind === 'agent' || scope.kind === 'user') &&\n typeof scope.id === 'string'\n ) {\n return true;\n }\n return (\n scope.kind === 'skill' &&\n typeof scope.id === 'string' &&\n typeof scope.version === 'number'\n );\n}\n\nfunction isCodeApiAuthHeaders(\n value: string | t.CodeApiAuthHeaders | undefined\n): value is t.CodeApiAuthHeaders {\n return value != null && typeof value !== 'string';\n}\n\nfunction isCodeApiSessionFileWire(\n value: unknown\n): value is CodeApiSessionFileWire {\n return value != null && typeof value === 'object';\n}\n\nfunction isCodeApiSessionFileMetadata(\n value: unknown\n): value is CodeApiSessionFileMetadata {\n return value != null && typeof value === 'object';\n}\n\nfunction normalizeSessionFile(\n file: CodeApiSessionFileWire,\n sessionId: string,\n scope?: FetchSessionFilesScope\n): t.CodeEnvFile {\n const metadata = isCodeApiSessionFileMetadata(file.metadata)\n ? file.metadata\n : undefined;\n const rawName = typeof file.name === 'string' ? file.name : '';\n const nameParts = rawName.split('/');\n const fallbackId = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';\n const id =\n typeof file.id === 'string' && file.id !== '' ? file.id : fallbackId;\n const originalFilename = metadata?.['original-filename'];\n const name =\n typeof originalFilename === 'string' ? originalFilename : rawName;\n const storage_session_id =\n typeof file.storage_session_id === 'string'\n ? file.storage_session_id\n : sessionId;\n const resource_id =\n typeof file.resource_id === 'string' && file.resource_id !== ''\n ? file.resource_id\n : (scope?.id ?? id);\n\n if (scope?.kind === 'skill') {\n return {\n storage_session_id,\n kind: 'skill',\n id,\n resource_id,\n name,\n version: scope.version,\n };\n }\n if (scope != null) {\n return {\n storage_session_id,\n kind: scope.kind,\n id,\n resource_id,\n name,\n };\n }\n return {\n storage_session_id,\n kind: 'user',\n id,\n resource_id: id,\n name,\n };\n}\n\n/**\n * Normalizes a tool name to Python identifier format.\n * Must match the Code API's `normalizePythonFunctionName` exactly:\n * 1. Replace hyphens and spaces with underscores\n * 2. Remove any other invalid characters\n * 3. Prefix with underscore if starts with number\n * 4. Append `_tool` if it's a Python keyword\n * @param name - The tool name to normalize\n * @returns Normalized Python-safe identifier\n */\nexport function normalizeToPythonIdentifier(name: string): string {\n let normalized = name.replace(/[-\\s]/g, '_');\n\n normalized = normalized.replace(/[^a-zA-Z0-9_]/g, '');\n\n if (/^[0-9]/.test(normalized)) {\n normalized = '_' + normalized;\n }\n\n if (PYTHON_KEYWORDS.has(normalized)) {\n normalized = normalized + '_tool';\n }\n\n return normalized;\n}\n\n/**\n * Extracts tool names that are actually called in the Python code.\n * Handles hyphen/underscore conversion since Python identifiers use underscores.\n * @param code - The Python code to analyze\n * @param toolNameMap - Map from normalized Python name to original tool name\n * @returns Set of original tool names found in the code\n */\nexport function extractUsedToolNames(\n code: string,\n toolNameMap: Map<string, string>\n): Set<string> {\n const usedTools = new Set<string>();\n\n for (const [pythonName, originalName] of toolNameMap) {\n const escapedName = pythonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`\\\\b${escapedName}\\\\s*\\\\(`, 'g');\n\n if (pattern.test(code)) {\n usedTools.add(originalName);\n }\n }\n\n return usedTools;\n}\n\n/**\n * Filters tool definitions to only include tools actually used in the code.\n * Handles the hyphen-to-underscore conversion for Python compatibility.\n * @param toolDefs - All available tool definitions\n * @param code - The Python code to analyze\n * @param debug - Enable debug logging\n * @returns Filtered array of tool definitions\n */\nexport function filterToolsByUsage(\n toolDefs: t.LCTool[],\n code: string,\n debug = false\n): t.LCTool[] {\n const toolNameMap = new Map<string, string>();\n for (const tool of toolDefs) {\n const pythonName = normalizeToPythonIdentifier(tool.name);\n toolNameMap.set(pythonName, tool.name);\n }\n\n const usedToolNames = extractUsedToolNames(code, toolNameMap);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`\n );\n if (usedToolNames.size > 0) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(', ')}`\n );\n }\n }\n\n if (usedToolNames.size === 0) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[PTC Debug] No tools detected in code - sending all tools as fallback'\n );\n }\n return toolDefs;\n }\n\n return toolDefs.filter((tool) => usedToolNames.has(tool.name));\n}\n\n/**\n * Fetches files from a previous session to make them available for the current execution.\n * Files are returned as CodeEnvFile references to be included in the request.\n * @param baseUrl - The base URL for the Code API\n * @param sessionId - The session ID to fetch files from\n * @param scope - Resource scope used by CodeAPI to authorize the session\n * @param proxy - Optional HTTP proxy URL\n * @returns Array of CodeEnvFile references, or empty array if fetch fails\n */\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scope: FetchSessionFilesScope,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scopeOrProxy?: FetchSessionFilesScope | string,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n scopedAuthHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]> {\n try {\n const scope = isFetchSessionFilesScope(scopeOrProxy)\n ? scopeOrProxy\n : undefined;\n let proxy: string | undefined;\n let authHeaders: t.CodeApiAuthHeaders | undefined;\n if (scope == null) {\n proxy = typeof scopeOrProxy === 'string' ? scopeOrProxy : undefined;\n authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders)\n ? proxyOrAuthHeaders\n : undefined;\n } else if (typeof proxyOrAuthHeaders === 'string') {\n proxy = proxyOrAuthHeaders;\n authHeaders = scopedAuthHeaders;\n } else {\n authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;\n }\n const query = new URLSearchParams({ detail: 'full' });\n if (scope != null) {\n query.set('kind', scope.kind);\n query.set('id', scope.id);\n if (scope.kind === 'skill') {\n query.set('version', String(scope.version));\n }\n }\n const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'GET',\n headers: {\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(filesEndpoint, fetchOptions);\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('GET', filesEndpoint, response)\n );\n }\n\n const files = await response.json();\n if (!Array.isArray(files) || files.length === 0) {\n return [];\n }\n\n return files\n .filter(isCodeApiSessionFileWire)\n .map((file) => normalizeSessionFile(file, sessionId, scope));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to fetch files for session: ${sessionId}, ${(error as Error).message}`\n );\n return [];\n }\n}\n\n/**\n * Makes an HTTP request to the Code API.\n * @param endpoint - The API endpoint URL\n * @param body - The request body\n * @param proxy - Optional HTTP proxy URL\n * @returns The parsed API response\n */\nexport async function makeRequest(\n endpoint: string,\n body: Record<string, unknown>,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.ProgrammaticExecutionResponse> {\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n body: JSON.stringify(body),\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('POST', endpoint, response)\n );\n }\n\n return (await response.json()) as t.ProgrammaticExecutionResponse;\n}\n\n/**\n * Unwraps tool responses that may be formatted as tuples or content blocks.\n * MCP tools return [content, artifacts], we need to extract the raw data.\n * @param result - The raw result from tool.invoke()\n * @param isMCPTool - Whether this is an MCP tool (has mcp property)\n * @returns Unwrapped raw data (string, object, or parsed JSON)\n */\nexport function unwrapToolResponse(\n result: unknown,\n isMCPTool: boolean\n): unknown {\n // Only unwrap if this is an MCP tool and result is a tuple\n if (!isMCPTool) {\n return result;\n }\n\n /**\n * Checks if a value is a content block object (has type and text).\n */\n const isContentBlock = (value: unknown): boolean => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const obj = value as Record<string, unknown>;\n return typeof obj.type === 'string';\n };\n\n /**\n * Checks if an array is an array of content blocks.\n */\n const isContentBlockArray = (arr: unknown[]): boolean => {\n return arr.length > 0 && arr.every(isContentBlock);\n };\n\n /**\n * Extracts text from a single content block object.\n * Returns the text if it's a text block, otherwise returns null.\n */\n const extractTextFromBlock = (block: unknown): string | null => {\n if (typeof block !== 'object' || block === null) return null;\n const b = block as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n return b.text;\n }\n return null;\n };\n\n /**\n * Extracts text from content blocks (array or single object).\n * Returns combined text or null if no text blocks found.\n */\n const extractTextFromContent = (content: unknown): string | null => {\n // Single content block object: { type: 'text', text: '...' }\n if (\n typeof content === 'object' &&\n content !== null &&\n !Array.isArray(content)\n ) {\n const text = extractTextFromBlock(content);\n if (text !== null) return text;\n }\n\n // Array of content blocks: [{ type: 'text', text: '...' }, ...]\n if (Array.isArray(content) && content.length > 0) {\n const texts = content\n .map(extractTextFromBlock)\n .filter((t): t is string => t !== null);\n if (texts.length > 0) {\n return texts.join('\\n');\n }\n }\n\n return null;\n };\n\n /**\n * Tries to parse a string as JSON if it looks like JSON.\n */\n const maybeParseJSON = (str: string): unknown => {\n const trimmed = str.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.parse(trimmed);\n } catch {\n return str;\n }\n }\n return str;\n };\n\n // Handle array of content blocks at top level FIRST\n // (before checking for tuple, since both are arrays)\n if (Array.isArray(result) && isContentBlockArray(result)) {\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n }\n\n // Check if result is a tuple/array with [content, artifacts]\n if (Array.isArray(result) && result.length >= 1) {\n const [content] = result;\n\n // If first element is a string, return it (possibly parsed as JSON)\n if (typeof content === 'string') {\n return maybeParseJSON(content);\n }\n\n // Try to extract text from content blocks\n const extractedText = extractTextFromContent(content);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // If first element is an object (but not a text block), return it\n if (typeof content === 'object' && content !== null) {\n return content;\n }\n }\n\n // Handle single content block object at top level (not in tuple)\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // Not a formatted response, return as-is\n return result;\n}\n\n/**\n * Executes tools in parallel when requested by the API.\n * Uses Promise.all for parallel execution, catching individual errors.\n * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.\n * @param toolCalls - Array of tool calls from the API\n * @param toolMap - Map of tool names to executable tools\n * @returns Array of tool results\n */\nexport async function executeTools(\n toolCalls: t.PTCToolCall[],\n toolMap: t.ToolMap,\n programmaticToolName = Constants.PROGRAMMATIC_TOOL_CALLING\n): Promise<t.PTCToolResult[]> {\n const executions = toolCalls.map(async (call): Promise<t.PTCToolResult> => {\n const tool = toolMap.get(call.name);\n\n if (!tool) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(', ')}`,\n };\n }\n\n try {\n const result = await tool.invoke(call.input, {\n metadata: { [programmaticToolName]: true },\n });\n\n const isMCPTool = tool.mcp === true;\n const unwrappedResult = unwrapToolResponse(result, isMCPTool);\n\n return {\n call_id: call.id,\n result: unwrappedResult,\n is_error: false,\n };\n } catch (error) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: (error as Error).message || 'Tool execution failed',\n };\n }\n });\n\n return await Promise.all(executions);\n}\n\n/**\n * Formats the completed response for the agent.\n *\n * Output includes stdout/stderr plus a compact session-file summary\n * when artifacts were persisted. The artifact still carries every\n * file so the host's session map stays in sync.\n *\n * @param response - The completed API response\n * @returns Tuple of [formatted string, artifact]\n */\nexport function formatCompletedResponse(\n response: t.ProgrammaticExecutionResponse,\n sourceCode = ''\n): [string, t.ProgrammaticExecutionArtifact] {\n let formatted = '';\n\n if (response.stdout != null && response.stdout !== '') {\n formatted += `stdout:\\n${response.stdout}\\n`;\n } else {\n formatted += emptyOutputMessage;\n }\n\n if (response.stderr != null && response.stderr !== '') {\n formatted += `stderr:\\n${response.stderr}\\n`;\n }\n\n const outputWithReminder = appendTmpScratchReminder(formatted, sourceCode);\n\n return [\n appendCodeSessionFileSummary(outputWithReminder, response.files),\n {\n session_id: response.session_id,\n files: response.files,\n } satisfies t.ProgrammaticExecutionArtifact,\n ];\n}\n\n// ============================================================================\n// Tool Factory\n// ============================================================================\n\n/**\n * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.\n *\n * This tool enables AI agents to write Python code that orchestrates multiple\n * tool calls programmatically, reducing LLM round-trips and token usage.\n *\n * The tool map must be provided at runtime via config.configurable.toolMap.\n *\n * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)\n * @returns A LangChain DynamicStructuredTool for programmatic tool calling\n *\n * @example\n * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });\n *\n * const [output, artifact] = await ptcTool.invoke(\n * { code, tools },\n * { configurable: { toolMap } }\n * );\n */\nexport function createProgrammaticToolCallingTool(\n initParams: t.ProgrammaticToolCallingParams = {}\n): DynamicStructuredTool {\n const baseUrl = initParams.baseUrl ?? getCodeBaseURL();\n const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;\n const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);\n const proxy = initParams.proxy ?? process.env.PROXY;\n const debug = initParams.debug ?? process.env.PTC_DEBUG === 'true';\n const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;\n\n return tool(\n async (rawParams, config) => {\n const params = rawParams as { code: string; timeout?: number };\n const { code } = params;\n const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);\n\n // Extra params injected by ToolNode (follows web_search pattern).\n const toolCall = (config.toolCall ?? {}) as ToolCall &\n Partial<t.ProgrammaticCache> & {\n session_id?: string;\n _injected_files?: t.CodeEnvFile[];\n };\n const { toolMap, toolDefs, session_id, _injected_files } = toolCall;\n\n if (toolMap == null || toolMap.size === 0) {\n throw new Error(\n 'No toolMap provided. ' +\n 'ToolNode should inject this from AgentContext when invoked through the graph.'\n );\n }\n\n if (toolDefs == null || toolDefs.length === 0) {\n throw new Error(\n 'No tool definitions provided. ' +\n 'Either pass tools in the input or ensure ToolNode injects toolDefs.'\n );\n }\n\n let roundTrip = 0;\n\n try {\n // ====================================================================\n // Phase 1: Filter tools and make initial request\n // ====================================================================\n\n const effectiveTools = filterToolsByUsage(toolDefs, code, debug);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Sending ${effectiveTools.length} tools to API ` +\n `(filtered from ${toolDefs.length})`\n );\n }\n\n /**\n * File injection: `_injected_files` from ToolNode session\n * context. The legacy `/files/<session_id>` HTTP fallback was\n * removed (see `CodeExecutor.ts`) — codeapi's sessionAuth now\n * requires kind/id query params unavailable at this point.\n */\n let files: t.CodeEnvFile[] | undefined;\n if (_injected_files && _injected_files.length > 0) {\n files = _injected_files;\n } else if (session_id != null && session_id.length > 0) {\n // eslint-disable-next-line no-console\n console.debug(\n `[ProgrammaticToolCalling] No injected files for session_id=${session_id} — exec will run without input files`\n );\n }\n\n let response = await makeRequest(\n EXEC_ENDPOINT,\n {\n code,\n tools: effectiveTools,\n session_id,\n timeout,\n ...(files && files.length > 0 ? { files } : {}),\n },\n proxy,\n initParams.authHeaders\n );\n\n // ====================================================================\n // Phase 2: Handle response loop\n // ====================================================================\n\n while (response.status === 'tool_call_required') {\n roundTrip++;\n\n if (roundTrip > maxRoundTrips) {\n throw new Error(\n `Exceeded maximum round trips (${maxRoundTrips}). ` +\n 'This may indicate an infinite loop, excessive tool calls, ' +\n 'or a logic error in your code.'\n );\n }\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`\n );\n }\n\n const toolResults = await executeTools(\n response.tool_calls ?? [],\n toolMap\n );\n\n response = await makeRequest(\n EXEC_ENDPOINT,\n {\n continuation_token: response.continuation_token,\n tool_results: toolResults,\n },\n proxy,\n initParams.authHeaders\n );\n }\n\n // ====================================================================\n // Phase 3: Handle final state\n // ====================================================================\n\n if (response.status === 'completed') {\n return formatCompletedResponse(response, code);\n }\n\n if (response.status === 'error') {\n throw new Error(\n `Execution error: ${response.error}` +\n (response.stderr != null && response.stderr !== ''\n ? `\\n\\nStderr:\\n${response.stderr}`\n : '')\n );\n }\n\n throw new Error(`Unexpected response status: ${response.status}`);\n } catch (error) {\n const messageWithReminder = appendFailedExecutionFileReminder(\n (error as Error).message,\n code\n );\n throw new Error(\n `Programmatic execution failed: ${messageWithReminder}`\n );\n }\n },\n {\n name: Constants.PROGRAMMATIC_TOOL_CALLING,\n description: ProgrammaticToolCallingDescription,\n schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n"],"names":["config","resolveCodeApiRunTimeoutMs","CODE_ARTIFACT_PATH_GUIDANCE","createCodeApiRunTimeoutSchema","Constants","resolveCodeApiAuthHeaders","HttpsProxyAgent","buildCodeApiHttpErrorMessage","emptyOutputMessage","appendTmpScratchReminder","appendCodeSessionFileSummary","getCodeBaseURL","tool","clampCodeApiRunTimeoutMs","appendFailedExecutionFileReminder"],"mappings":"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"}
1
+ {"version":3,"file":"ProgrammaticToolCalling.cjs","sources":["../../../src/tools/ProgrammaticToolCalling.ts"],"sourcesContent":["// src/tools/ProgrammaticToolCalling.ts\nimport { config } from 'dotenv';\nimport fetch, { RequestInit } from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { ProgrammaticToolCallingJsonSchema } from './ptcTimeout';\nimport type * as t from '@/types';\nimport {\n CODE_ARTIFACT_PATH_GUIDANCE,\n appendCodeSessionFileSummary,\n appendFailedExecutionFileReminder,\n buildCodeApiHttpErrorMessage,\n emptyOutputMessage,\n getCodeBaseURL,\n appendTmpScratchReminder,\n resolveCodeApiAuthHeaders,\n} from './CodeExecutor';\nimport {\n clampCodeApiRunTimeoutMs,\n createCodeApiRunTimeoutSchema,\n resolveCodeApiRunTimeoutMs,\n} from './ptcTimeout';\nimport { Constants } from '@/common';\n\nconfig();\n\n/** Default max round-trips to prevent infinite loops */\nconst DEFAULT_MAX_ROUND_TRIPS = 20;\n\nconst DEFAULT_RUN_TIMEOUT_MS = resolveCodeApiRunTimeoutMs();\n\n// ============================================================================\n// Description Components (Single Source of Truth)\n// ============================================================================\n\nconst STATELESS_WARNING = `CRITICAL - STATELESS EXECUTION:\nEach call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.\nYou MUST complete your entire workflow in ONE code block: query → process → output.\nDO NOT split work across multiple calls expecting to reuse variables.`;\n\nconst CORE_RULES = `Rules:\n- One call: state does not persist\n- Auto-wrapped async; use await, no main()/asyncio.run()\n- Tools are pre-defined—DO NOT write function definitions\n- Call tools with keyword args only (await tool(arg=value), never pass a dict)\n- Tool results are decoded Python values (dict/list/str)\n- Only print() output returns to the model\n- ${CODE_ARTIFACT_PATH_GUIDANCE}\n- timeout caps one sandbox run/replay iteration, not the total multi-round-trip workflow`;\n\nconst ADDITIONAL_RULES =\n '- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix';\n\nconst EXAMPLES = `Example (Complete workflow in one call):\n # Query data\n data = await query_database(sql=\"SELECT * FROM users\")\n # Process it\n df = pd.DataFrame(data)\n summary = df.groupby('region').sum()\n # Output results\n await write_to_sheet(spreadsheet_id=sid, data=summary.to_dict())\n print(f\"Wrote {len(summary)} rows\")\n\nExample (Parallel calls):\n sf, ny = await asyncio.gather(get_weather(city=\"SF\"), get_weather(city=\"NY\"))\n print(f\"SF: {sf}, NY: {ny}\")`;\n\n// ============================================================================\n// Schema\n// ============================================================================\n\nconst CODE_PARAM_DESCRIPTION = `Python code that calls tools programmatically. Tools are available as async functions.\n\n${STATELESS_WARNING}\n\nYour code is auto-wrapped in async context. Just write logic with await—no boilerplate needed.\n\n${EXAMPLES}\n\n${CORE_RULES}`;\n\nexport function createProgrammaticToolCallingSchema(\n maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS\n): ProgrammaticToolCallingJsonSchema {\n return {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n minLength: 1,\n description: CODE_PARAM_DESCRIPTION,\n },\n timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),\n },\n required: ['code'],\n } as const;\n}\n\nexport const ProgrammaticToolCallingSchema =\n createProgrammaticToolCallingSchema();\n\nexport const ProgrammaticToolCallingName = Constants.PROGRAMMATIC_TOOL_CALLING;\n\nexport const ProgrammaticToolCallingDescription = `\nRun tools via Python code. Auto-wrapped in async context—just use \\`await\\` directly.\n\n${STATELESS_WARNING}\n\n${CORE_RULES}\n${ADDITIONAL_RULES}\n\nWhen to use: loops, conditionals, parallel (\\`asyncio.gather\\`), multi-step pipelines.\n\n${EXAMPLES}\n`.trim();\n\nexport const ProgrammaticToolCallingDefinition = {\n name: ProgrammaticToolCallingName,\n description: ProgrammaticToolCallingDescription,\n schema: ProgrammaticToolCallingSchema,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Python reserved keywords that get `_tool` suffix in Code API */\nconst PYTHON_KEYWORDS = new Set([\n 'False',\n 'None',\n 'True',\n 'and',\n 'as',\n 'assert',\n 'async',\n 'await',\n 'break',\n 'class',\n 'continue',\n 'def',\n 'del',\n 'elif',\n 'else',\n 'except',\n 'finally',\n 'for',\n 'from',\n 'global',\n 'if',\n 'import',\n 'in',\n 'is',\n 'lambda',\n 'nonlocal',\n 'not',\n 'or',\n 'pass',\n 'raise',\n 'return',\n 'try',\n 'while',\n 'with',\n 'yield',\n]);\n\nexport type FetchSessionFilesScope =\n | { kind: 'skill'; id: string; version: number }\n | { kind: 'agent' | 'user'; id: string; version?: never };\n\ntype CodeApiSessionFileWire = {\n id?: unknown;\n name?: unknown;\n metadata?: unknown;\n resource_id?: unknown;\n storage_session_id?: unknown;\n};\n\ntype CodeApiSessionFileMetadata = {\n 'original-filename'?: unknown;\n};\n\nfunction isFetchSessionFilesScope(\n value: unknown\n): value is FetchSessionFilesScope {\n if (value == null || typeof value !== 'object') {\n return false;\n }\n const scope = value as { kind?: unknown; id?: unknown; version?: unknown };\n if (\n (scope.kind === 'agent' || scope.kind === 'user') &&\n typeof scope.id === 'string'\n ) {\n return true;\n }\n return (\n scope.kind === 'skill' &&\n typeof scope.id === 'string' &&\n typeof scope.version === 'number'\n );\n}\n\nfunction isCodeApiAuthHeaders(\n value: string | t.CodeApiAuthHeaders | undefined\n): value is t.CodeApiAuthHeaders {\n return value != null && typeof value !== 'string';\n}\n\nfunction isCodeApiSessionFileWire(\n value: unknown\n): value is CodeApiSessionFileWire {\n return value != null && typeof value === 'object';\n}\n\nfunction isCodeApiSessionFileMetadata(\n value: unknown\n): value is CodeApiSessionFileMetadata {\n return value != null && typeof value === 'object';\n}\n\nfunction normalizeSessionFile(\n file: CodeApiSessionFileWire,\n sessionId: string,\n scope?: FetchSessionFilesScope\n): t.CodeEnvFile {\n const metadata = isCodeApiSessionFileMetadata(file.metadata)\n ? file.metadata\n : undefined;\n const rawName = typeof file.name === 'string' ? file.name : '';\n const nameParts = rawName.split('/');\n const fallbackId = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';\n const id =\n typeof file.id === 'string' && file.id !== '' ? file.id : fallbackId;\n const originalFilename = metadata?.['original-filename'];\n const name =\n typeof originalFilename === 'string' ? originalFilename : rawName;\n const storage_session_id =\n typeof file.storage_session_id === 'string'\n ? file.storage_session_id\n : sessionId;\n const resource_id =\n typeof file.resource_id === 'string' && file.resource_id !== ''\n ? file.resource_id\n : (scope?.id ?? id);\n\n if (scope?.kind === 'skill') {\n return {\n storage_session_id,\n kind: 'skill',\n id,\n resource_id,\n name,\n version: scope.version,\n };\n }\n if (scope != null) {\n return {\n storage_session_id,\n kind: scope.kind,\n id,\n resource_id,\n name,\n };\n }\n return {\n storage_session_id,\n kind: 'user',\n id,\n resource_id: id,\n name,\n };\n}\n\n/**\n * Normalizes a tool name to Python identifier format.\n * Must match the Code API's `normalizePythonFunctionName` exactly:\n * 1. Replace hyphens and spaces with underscores\n * 2. Remove any other invalid characters\n * 3. Prefix with underscore if starts with number\n * 4. Append `_tool` if it's a Python keyword\n * @param name - The tool name to normalize\n * @returns Normalized Python-safe identifier\n */\nexport function normalizeToPythonIdentifier(name: string): string {\n let normalized = name.replace(/[-\\s]/g, '_');\n\n normalized = normalized.replace(/[^a-zA-Z0-9_]/g, '');\n\n if (/^[0-9]/.test(normalized)) {\n normalized = '_' + normalized;\n }\n\n if (PYTHON_KEYWORDS.has(normalized)) {\n normalized = normalized + '_tool';\n }\n\n return normalized;\n}\n\n/**\n * Extracts tool names that are actually called in the Python code.\n * Handles hyphen/underscore conversion since Python identifiers use underscores.\n * @param code - The Python code to analyze\n * @param toolNameMap - Map from normalized Python name to original tool name\n * @returns Set of original tool names found in the code\n */\nexport function extractUsedToolNames(\n code: string,\n toolNameMap: Map<string, string>\n): Set<string> {\n const usedTools = new Set<string>();\n\n for (const [pythonName, originalName] of toolNameMap) {\n const escapedName = pythonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`\\\\b${escapedName}\\\\s*\\\\(`, 'g');\n\n if (pattern.test(code)) {\n usedTools.add(originalName);\n }\n }\n\n return usedTools;\n}\n\n/**\n * Filters tool definitions to only include tools actually used in the code.\n * Handles the hyphen-to-underscore conversion for Python compatibility.\n * @param toolDefs - All available tool definitions\n * @param code - The Python code to analyze\n * @param debug - Enable debug logging\n * @returns Filtered array of tool definitions\n */\nexport function filterToolsByUsage(\n toolDefs: t.LCTool[],\n code: string,\n debug = false\n): t.LCTool[] {\n const toolNameMap = new Map<string, string>();\n for (const tool of toolDefs) {\n const pythonName = normalizeToPythonIdentifier(tool.name);\n toolNameMap.set(pythonName, tool.name);\n }\n\n const usedToolNames = extractUsedToolNames(code, toolNameMap);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`\n );\n if (usedToolNames.size > 0) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(', ')}`\n );\n }\n }\n\n if (usedToolNames.size === 0) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[PTC Debug] No tools detected in code - sending all tools as fallback'\n );\n }\n return toolDefs;\n }\n\n return toolDefs.filter((tool) => usedToolNames.has(tool.name));\n}\n\n/**\n * Fetches files from a previous session to make them available for the current execution.\n * Files are returned as CodeEnvFile references to be included in the request.\n * @param baseUrl - The base URL for the Code API\n * @param sessionId - The session ID to fetch files from\n * @param scope - Resource scope used by CodeAPI to authorize the session\n * @param proxy - Optional HTTP proxy URL\n * @returns Array of CodeEnvFile references, or empty array if fetch fails\n */\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scope: FetchSessionFilesScope,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scopeOrProxy?: FetchSessionFilesScope | string,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n scopedAuthHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]> {\n try {\n const scope = isFetchSessionFilesScope(scopeOrProxy)\n ? scopeOrProxy\n : undefined;\n let proxy: string | undefined;\n let authHeaders: t.CodeApiAuthHeaders | undefined;\n if (scope == null) {\n proxy = typeof scopeOrProxy === 'string' ? scopeOrProxy : undefined;\n authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders)\n ? proxyOrAuthHeaders\n : undefined;\n } else if (typeof proxyOrAuthHeaders === 'string') {\n proxy = proxyOrAuthHeaders;\n authHeaders = scopedAuthHeaders;\n } else {\n authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;\n }\n const query = new URLSearchParams({ detail: 'full' });\n if (scope != null) {\n query.set('kind', scope.kind);\n query.set('id', scope.id);\n if (scope.kind === 'skill') {\n query.set('version', String(scope.version));\n }\n }\n const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'GET',\n headers: {\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(filesEndpoint, fetchOptions);\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('GET', filesEndpoint, response)\n );\n }\n\n const files = await response.json();\n if (!Array.isArray(files) || files.length === 0) {\n return [];\n }\n\n return files\n .filter(isCodeApiSessionFileWire)\n .map((file) => normalizeSessionFile(file, sessionId, scope));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to fetch files for session: ${sessionId}, ${(error as Error).message}`\n );\n return [];\n }\n}\n\n/**\n * Makes an HTTP request to the Code API.\n * @param endpoint - The API endpoint URL\n * @param body - The request body\n * @param proxy - Optional HTTP proxy URL\n * @returns The parsed API response\n */\nexport async function makeRequest(\n endpoint: string,\n body: Record<string, unknown>,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.ProgrammaticExecutionResponse> {\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n body: JSON.stringify(body),\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('POST', endpoint, response)\n );\n }\n\n return (await response.json()) as t.ProgrammaticExecutionResponse;\n}\n\n/**\n * Unwraps tool responses that may be formatted as tuples or content blocks.\n * MCP tools return [content, artifacts], we need to extract the raw data.\n * @param result - The raw result from tool.invoke()\n * @param isMCPTool - Whether this is an MCP tool (has mcp property)\n * @returns Unwrapped raw data (string, object, or parsed JSON)\n */\nexport function unwrapToolResponse(\n result: unknown,\n isMCPTool: boolean\n): unknown {\n // Only unwrap if this is an MCP tool and result is a tuple\n if (!isMCPTool) {\n return result;\n }\n\n /**\n * Checks if a value is a content block object (has type and text).\n */\n const isContentBlock = (value: unknown): boolean => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const obj = value as Record<string, unknown>;\n return typeof obj.type === 'string';\n };\n\n /**\n * Checks if an array is an array of content blocks.\n */\n const isContentBlockArray = (arr: unknown[]): boolean => {\n return arr.length > 0 && arr.every(isContentBlock);\n };\n\n /**\n * Extracts text from a single content block object.\n * Returns the text if it's a text block, otherwise returns null.\n */\n const extractTextFromBlock = (block: unknown): string | null => {\n if (typeof block !== 'object' || block === null) return null;\n const b = block as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n return b.text;\n }\n return null;\n };\n\n /**\n * Extracts text from content blocks (array or single object).\n * Returns combined text or null if no text blocks found.\n */\n const extractTextFromContent = (content: unknown): string | null => {\n // Single content block object: { type: 'text', text: '...' }\n if (\n typeof content === 'object' &&\n content !== null &&\n !Array.isArray(content)\n ) {\n const text = extractTextFromBlock(content);\n if (text !== null) return text;\n }\n\n // Array of content blocks: [{ type: 'text', text: '...' }, ...]\n if (Array.isArray(content) && content.length > 0) {\n const texts = content\n .map(extractTextFromBlock)\n .filter((t): t is string => t !== null);\n if (texts.length > 0) {\n return texts.join('\\n');\n }\n }\n\n return null;\n };\n\n /**\n * Tries to parse a string as JSON if it looks like JSON.\n */\n const maybeParseJSON = (str: string): unknown => {\n const trimmed = str.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.parse(trimmed);\n } catch {\n return str;\n }\n }\n return str;\n };\n\n // Handle array of content blocks at top level FIRST\n // (before checking for tuple, since both are arrays)\n if (Array.isArray(result) && isContentBlockArray(result)) {\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n }\n\n // Check if result is a tuple/array with [content, artifacts]\n if (Array.isArray(result) && result.length >= 1) {\n const [content] = result;\n\n // If first element is a string, return it (possibly parsed as JSON)\n if (typeof content === 'string') {\n return maybeParseJSON(content);\n }\n\n // Try to extract text from content blocks\n const extractedText = extractTextFromContent(content);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // If first element is an object (but not a text block), return it\n if (typeof content === 'object' && content !== null) {\n return content;\n }\n }\n\n // Handle single content block object at top level (not in tuple)\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // Not a formatted response, return as-is\n return result;\n}\n\ntype ToolInputSchemaKind = {\n object: boolean;\n string: boolean;\n};\n\nfunction detectSchemaKind(schema: unknown): ToolInputSchemaKind {\n const kind: ToolInputSchemaKind = { object: false, string: false };\n\n if (!schema || typeof schema !== 'object') {\n return kind;\n }\n\n const jsonSchemaType = (schema as { type?: unknown }).type;\n if (jsonSchemaType === 'object') {\n kind.object = true;\n } else if (jsonSchemaType === 'string') {\n kind.string = true;\n } else if (Array.isArray(jsonSchemaType)) {\n kind.object = jsonSchemaType.includes('object');\n kind.string = jsonSchemaType.includes('string');\n }\n\n const zodDef = (schema as { _def?: unknown })._def;\n if (!zodDef || typeof zodDef !== 'object') {\n return kind;\n }\n\n const zodType = (zodDef as { type?: unknown; typeName?: unknown }).type;\n const zodTypeName = (zodDef as { type?: unknown; typeName?: unknown })\n .typeName;\n\n if (zodType === 'object' || zodTypeName === 'ZodObject') {\n kind.object = true;\n } else if (zodType === 'string' || zodTypeName === 'ZodString') {\n kind.string = true;\n }\n\n const innerSchema =\n (\n zodDef as {\n innerType?: unknown;\n schema?: unknown;\n type?: unknown;\n }\n ).innerType ?? (zodDef as { schema?: unknown }).schema;\n if (innerSchema) {\n const innerKind = detectSchemaKind(innerSchema);\n kind.object ||= innerKind.object;\n kind.string ||= innerKind.string;\n }\n\n const options = (zodDef as { options?: unknown }).options;\n if (Array.isArray(options)) {\n for (const option of options) {\n const optionKind = detectSchemaKind(option);\n kind.object ||= optionKind.object;\n kind.string ||= optionKind.string;\n }\n }\n\n return kind;\n}\n\nfunction getToolInputSchemaKind(tool: t.GenericTool): ToolInputSchemaKind {\n if (tool.constructor.name === 'DynamicTool') {\n return { object: false, string: true };\n }\n\n const schema = (tool as { schema?: unknown }).schema;\n return detectSchemaKind(schema);\n}\n\nfunction normalizeToolInput(\n input: t.PTCToolCall['input'],\n tool: t.GenericTool\n): t.PTCToolCall['input'] {\n const schemaKind = getToolInputSchemaKind(tool);\n\n if (typeof input !== 'string') {\n if (!schemaKind.string || schemaKind.object) {\n return input;\n }\n\n const inputValue = (input as { input?: unknown }).input;\n if (typeof inputValue === 'string') {\n return input;\n }\n\n return JSON.stringify(input);\n }\n\n if (!schemaKind.object || schemaKind.string) {\n return input;\n }\n\n const trimmed = input.trim();\n if (!trimmed.startsWith('{')) {\n return input;\n }\n\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n !Array.isArray(parsed)\n ) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n return input;\n }\n\n return input;\n}\n\n/**\n * Executes tools in parallel when requested by the API.\n * Uses Promise.all for parallel execution, catching individual errors.\n * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.\n * @param toolCalls - Array of tool calls from the API\n * @param toolMap - Map of tool names to executable tools\n * @returns Array of tool results\n */\nexport async function executeTools(\n toolCalls: t.PTCToolCall[],\n toolMap: t.ToolMap,\n programmaticToolName = Constants.PROGRAMMATIC_TOOL_CALLING\n): Promise<t.PTCToolResult[]> {\n const executions = toolCalls.map(async (call): Promise<t.PTCToolResult> => {\n const tool = toolMap.get(call.name);\n\n if (!tool) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(', ')}`,\n };\n }\n\n try {\n const result = await tool.invoke(normalizeToolInput(call.input, tool), {\n metadata: { [programmaticToolName]: true },\n });\n\n const isMCPTool = tool.mcp === true;\n const unwrappedResult = unwrapToolResponse(result, isMCPTool);\n\n return {\n call_id: call.id,\n result: unwrappedResult,\n is_error: false,\n };\n } catch (error) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: (error as Error).message || 'Tool execution failed',\n };\n }\n });\n\n return await Promise.all(executions);\n}\n\n/**\n * Formats the completed response for the agent.\n *\n * Output includes stdout/stderr plus a compact session-file summary\n * when artifacts were persisted. The artifact still carries every\n * file so the host's session map stays in sync.\n *\n * @param response - The completed API response\n * @returns Tuple of [formatted string, artifact]\n */\nexport function formatCompletedResponse(\n response: t.ProgrammaticExecutionResponse,\n sourceCode = ''\n): [string, t.ProgrammaticExecutionArtifact] {\n let formatted = '';\n\n if (response.stdout != null && response.stdout !== '') {\n formatted += `stdout:\\n${response.stdout}\\n`;\n } else {\n formatted += emptyOutputMessage;\n }\n\n if (response.stderr != null && response.stderr !== '') {\n formatted += `stderr:\\n${response.stderr}\\n`;\n }\n\n const outputWithReminder = appendTmpScratchReminder(formatted, sourceCode);\n\n return [\n appendCodeSessionFileSummary(outputWithReminder, response.files),\n {\n session_id: response.session_id,\n files: response.files,\n } satisfies t.ProgrammaticExecutionArtifact,\n ];\n}\n\n// ============================================================================\n// Tool Factory\n// ============================================================================\n\n/**\n * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.\n *\n * This tool enables AI agents to write Python code that orchestrates multiple\n * tool calls programmatically, reducing LLM round-trips and token usage.\n *\n * The tool map must be provided at runtime via config.configurable.toolMap.\n *\n * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)\n * @returns A LangChain DynamicStructuredTool for programmatic tool calling\n *\n * @example\n * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });\n *\n * const [output, artifact] = await ptcTool.invoke(\n * { code, tools },\n * { configurable: { toolMap } }\n * );\n */\nexport function createProgrammaticToolCallingTool(\n initParams: t.ProgrammaticToolCallingParams = {}\n): DynamicStructuredTool {\n const baseUrl = initParams.baseUrl ?? getCodeBaseURL();\n const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;\n const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);\n const proxy = initParams.proxy ?? process.env.PROXY;\n const debug = initParams.debug ?? process.env.PTC_DEBUG === 'true';\n const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;\n\n return tool(\n async (rawParams, config) => {\n const params = rawParams as { code: string; timeout?: number };\n const { code } = params;\n const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);\n\n // Extra params injected by ToolNode (follows web_search pattern).\n const toolCall = (config.toolCall ?? {}) as ToolCall &\n Partial<t.ProgrammaticCache> & {\n session_id?: string;\n _injected_files?: t.CodeEnvFile[];\n };\n const { toolMap, toolDefs, session_id, _injected_files } = toolCall;\n\n if (toolMap == null || toolMap.size === 0) {\n throw new Error(\n 'No toolMap provided. ' +\n 'ToolNode should inject this from AgentContext when invoked through the graph.'\n );\n }\n\n if (toolDefs == null || toolDefs.length === 0) {\n throw new Error(\n 'No tool definitions provided. ' +\n 'Either pass tools in the input or ensure ToolNode injects toolDefs.'\n );\n }\n\n let roundTrip = 0;\n\n try {\n // ====================================================================\n // Phase 1: Filter tools and make initial request\n // ====================================================================\n\n const effectiveTools = filterToolsByUsage(toolDefs, code, debug);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Sending ${effectiveTools.length} tools to API ` +\n `(filtered from ${toolDefs.length})`\n );\n }\n\n /**\n * File injection: `_injected_files` from ToolNode session\n * context. The legacy `/files/<session_id>` HTTP fallback was\n * removed (see `CodeExecutor.ts`) — codeapi's sessionAuth now\n * requires kind/id query params unavailable at this point.\n */\n let files: t.CodeEnvFile[] | undefined;\n if (_injected_files && _injected_files.length > 0) {\n files = _injected_files;\n } else if (session_id != null && session_id.length > 0) {\n // eslint-disable-next-line no-console\n console.debug(\n `[ProgrammaticToolCalling] No injected files for session_id=${session_id} — exec will run without input files`\n );\n }\n\n let response = await makeRequest(\n EXEC_ENDPOINT,\n {\n code,\n tools: effectiveTools,\n session_id,\n timeout,\n ...(files && files.length > 0 ? { files } : {}),\n },\n proxy,\n initParams.authHeaders\n );\n\n // ====================================================================\n // Phase 2: Handle response loop\n // ====================================================================\n\n while (response.status === 'tool_call_required') {\n roundTrip++;\n\n if (roundTrip > maxRoundTrips) {\n throw new Error(\n `Exceeded maximum round trips (${maxRoundTrips}). ` +\n 'This may indicate an infinite loop, excessive tool calls, ' +\n 'or a logic error in your code.'\n );\n }\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`\n );\n }\n\n const toolResults = await executeTools(\n response.tool_calls ?? [],\n toolMap\n );\n\n response = await makeRequest(\n EXEC_ENDPOINT,\n {\n continuation_token: response.continuation_token,\n tool_results: toolResults,\n },\n proxy,\n initParams.authHeaders\n );\n }\n\n // ====================================================================\n // Phase 3: Handle final state\n // ====================================================================\n\n if (response.status === 'completed') {\n return formatCompletedResponse(response, code);\n }\n\n if (response.status === 'error') {\n throw new Error(\n `Execution error: ${response.error}` +\n (response.stderr != null && response.stderr !== ''\n ? `\\n\\nStderr:\\n${response.stderr}`\n : '')\n );\n }\n\n throw new Error(`Unexpected response status: ${response.status}`);\n } catch (error) {\n const messageWithReminder = appendFailedExecutionFileReminder(\n (error as Error).message,\n code\n );\n throw new Error(\n `Programmatic execution failed: ${messageWithReminder}`\n );\n }\n },\n {\n name: Constants.PROGRAMMATIC_TOOL_CALLING,\n description: ProgrammaticToolCallingDescription,\n schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n"],"names":["config","resolveCodeApiRunTimeoutMs","CODE_ARTIFACT_PATH_GUIDANCE","createCodeApiRunTimeoutSchema","Constants","resolveCodeApiAuthHeaders","HttpsProxyAgent","buildCodeApiHttpErrorMessage","emptyOutputMessage","appendTmpScratchReminder","appendCodeSessionFileSummary","getCodeBaseURL","tool","clampCodeApiRunTimeoutMs","appendFailedExecutionFileReminder"],"mappings":"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"}
@@ -4,6 +4,7 @@ var _enum = require('../common/enum.cjs');
4
4
 
5
5
  const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;
6
6
  const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;
7
+ const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300_000;
7
8
  function normalizeTimeoutMs(value) {
8
9
  if (value == null || !Number.isFinite(value)) {
9
10
  return undefined;
@@ -36,19 +37,24 @@ function clampCodeApiRunTimeoutMs(timeoutMs, maxRunTimeoutMs = resolveCodeApiRun
36
37
  }
37
38
  function createCodeApiRunTimeoutSchema(maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()) {
38
39
  const normalizedMaxRunTimeoutMs = normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;
40
+ const normalizedSchemaMaxRunTimeoutMs = Math.max(normalizedMaxRunTimeoutMs, MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS);
39
41
  const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);
42
+ const formattedSchemaMaxTimeout = formatTimeout(normalizedSchemaMaxRunTimeoutMs);
40
43
  return {
41
44
  type: 'integer',
42
45
  minimum: MIN_CODE_API_RUN_TIMEOUT_MS,
43
- maximum: normalizedMaxRunTimeoutMs,
46
+ maximum: normalizedSchemaMaxRunTimeoutMs,
44
47
  default: normalizedMaxRunTimeoutMs,
45
48
  description: 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +
46
49
  'This is not the total multi-round-trip task budget. ' +
47
- `Default: ${formattedTimeout}. Max: ${formattedTimeout}.`,
50
+ `Default: ${formattedTimeout}. ` +
51
+ 'Accepted values above the configured cap are clamped before execution. ' +
52
+ `Schema max: ${formattedSchemaMaxTimeout}. Configured cap: ${formattedTimeout}.`,
48
53
  };
49
54
  }
50
55
 
51
56
  exports.DEFAULT_CODE_API_RUN_TIMEOUT_MS = DEFAULT_CODE_API_RUN_TIMEOUT_MS;
57
+ exports.MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS;
52
58
  exports.MIN_CODE_API_RUN_TIMEOUT_MS = MIN_CODE_API_RUN_TIMEOUT_MS;
53
59
  exports.clampCodeApiRunTimeoutMs = clampCodeApiRunTimeoutMs;
54
60
  exports.createCodeApiRunTimeoutSchema = createCodeApiRunTimeoutSchema;
@@ -1 +1 @@
1
- {"version":3,"file":"ptcTimeout.cjs","sources":["../../../src/tools/ptcTimeout.ts"],"sourcesContent":["import { EnvVar } from '@/common';\n\nexport const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;\nexport const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;\n\ntype TimeoutSchema = {\n type: 'integer';\n minimum: number;\n maximum: number;\n default: number;\n description: string;\n};\n\nexport type ProgrammaticToolCallingJsonSchema = {\n type: 'object';\n properties: {\n code: {\n type: 'string';\n minLength: number;\n description: string;\n };\n timeout: TimeoutSchema;\n };\n required: readonly ['code'];\n};\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value == null || !Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(MIN_CODE_API_RUN_TIMEOUT_MS, Math.floor(value));\n}\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (value == null || value.trim() === '') {\n return undefined;\n }\n\n return normalizeTimeoutMs(Number(value));\n}\n\nfunction formatTimeout(timeoutMs: number): string {\n return timeoutMs % 1000 === 0\n ? `${timeoutMs / 1000} seconds`\n : `${timeoutMs} milliseconds`;\n}\n\nexport function resolveCodeApiRunTimeoutMs(override?: number): number {\n return (\n normalizeTimeoutMs(override) ??\n parseTimeoutMs(process.env[EnvVar.CODE_API_RUN_TIMEOUT_MS]) ??\n DEFAULT_CODE_API_RUN_TIMEOUT_MS\n );\n}\n\nexport function clampCodeApiRunTimeoutMs(\n timeoutMs: number | undefined,\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): number {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedTimeoutMs = normalizeTimeoutMs(timeoutMs);\n\n if (normalizedTimeoutMs == null) {\n return normalizedMaxRunTimeoutMs;\n }\n\n return Math.min(normalizedTimeoutMs, normalizedMaxRunTimeoutMs);\n}\n\nexport function createCodeApiRunTimeoutSchema(\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): TimeoutSchema {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);\n\n return {\n type: 'integer',\n minimum: MIN_CODE_API_RUN_TIMEOUT_MS,\n maximum: normalizedMaxRunTimeoutMs,\n default: normalizedMaxRunTimeoutMs,\n description:\n 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +\n 'This is not the total multi-round-trip task budget. ' +\n `Default: ${formattedTimeout}. Max: ${formattedTimeout}.`,\n };\n}\n"],"names":["EnvVar"],"mappings":";;;;AAEO,MAAM,+BAA+B,GAAG;AACxC,MAAM,2BAA2B,GAAG;AAuB3C,SAAS,kBAAkB,CAAC,KAAyB,EAAA;AACnD,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC5C,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,cAAc,CAAC,KAAyB,EAAA;IAC/C,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACxC,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1C;AAEA,SAAS,aAAa,CAAC,SAAiB,EAAA;AACtC,IAAA,OAAO,SAAS,GAAG,IAAI,KAAK;AAC1B,UAAE,CAAA,EAAG,SAAS,GAAG,IAAI,CAAA,QAAA;AACrB,UAAE,CAAA,EAAG,SAAS,CAAA,aAAA,CAAe;AACjC;AAEM,SAAU,0BAA0B,CAAC,QAAiB,EAAA;AAC1D,IAAA,QACE,kBAAkB,CAAC,QAAQ,CAAC;QAC5B,cAAc,CAAC,OAAO,CAAC,GAAG,CAACA,YAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3D,QAAA,+BAA+B;AAEnC;AAEM,SAAU,wBAAwB,CACtC,SAA6B,EAC7B,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,SAAS,CAAC;AAEzD,IAAA,IAAI,mBAAmB,IAAI,IAAI,EAAE;AAC/B,QAAA,OAAO,yBAAyB;IAClC;IAEA,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AACjE;SAEgB,6BAA6B,CAC3C,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,gBAAgB,GAAG,aAAa,CAAC,yBAAyB,CAAC;IAEjE,OAAO;AACL,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,2BAA2B;AACpC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,WAAW,EACT,mFAAmF;YACnF,sDAAsD;YACtD,CAAA,SAAA,EAAY,gBAAgB,CAAA,OAAA,EAAU,gBAAgB,CAAA,CAAA,CAAG;KAC5D;AACH;;;;;;;;"}
1
+ {"version":3,"file":"ptcTimeout.cjs","sources":["../../../src/tools/ptcTimeout.ts"],"sourcesContent":["import { EnvVar } from '@/common';\n\nexport const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;\nexport const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;\nexport const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300_000;\n\ntype TimeoutSchema = {\n type: 'integer';\n minimum: number;\n maximum: number;\n default: number;\n description: string;\n};\n\nexport type ProgrammaticToolCallingJsonSchema = {\n type: 'object';\n properties: {\n code: {\n type: 'string';\n minLength: number;\n description: string;\n };\n timeout: TimeoutSchema;\n };\n required: readonly ['code'];\n};\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value == null || !Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(MIN_CODE_API_RUN_TIMEOUT_MS, Math.floor(value));\n}\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (value == null || value.trim() === '') {\n return undefined;\n }\n\n return normalizeTimeoutMs(Number(value));\n}\n\nfunction formatTimeout(timeoutMs: number): string {\n return timeoutMs % 1000 === 0\n ? `${timeoutMs / 1000} seconds`\n : `${timeoutMs} milliseconds`;\n}\n\nexport function resolveCodeApiRunTimeoutMs(override?: number): number {\n return (\n normalizeTimeoutMs(override) ??\n parseTimeoutMs(process.env[EnvVar.CODE_API_RUN_TIMEOUT_MS]) ??\n DEFAULT_CODE_API_RUN_TIMEOUT_MS\n );\n}\n\nexport function clampCodeApiRunTimeoutMs(\n timeoutMs: number | undefined,\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): number {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedTimeoutMs = normalizeTimeoutMs(timeoutMs);\n\n if (normalizedTimeoutMs == null) {\n return normalizedMaxRunTimeoutMs;\n }\n\n return Math.min(normalizedTimeoutMs, normalizedMaxRunTimeoutMs);\n}\n\nexport function createCodeApiRunTimeoutSchema(\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): TimeoutSchema {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedSchemaMaxRunTimeoutMs = Math.max(\n normalizedMaxRunTimeoutMs,\n MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS\n );\n const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);\n const formattedSchemaMaxTimeout = formatTimeout(\n normalizedSchemaMaxRunTimeoutMs\n );\n\n return {\n type: 'integer',\n minimum: MIN_CODE_API_RUN_TIMEOUT_MS,\n maximum: normalizedSchemaMaxRunTimeoutMs,\n default: normalizedMaxRunTimeoutMs,\n description:\n 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +\n 'This is not the total multi-round-trip task budget. ' +\n `Default: ${formattedTimeout}. ` +\n 'Accepted values above the configured cap are clamped before execution. ' +\n `Schema max: ${formattedSchemaMaxTimeout}. Configured cap: ${formattedTimeout}.`,\n };\n}\n"],"names":["EnvVar"],"mappings":";;;;AAEO,MAAM,+BAA+B,GAAG;AACxC,MAAM,2BAA2B,GAAG;AACpC,MAAM,kCAAkC,GAAG;AAuBlD,SAAS,kBAAkB,CAAC,KAAyB,EAAA;AACnD,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC5C,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,cAAc,CAAC,KAAyB,EAAA;IAC/C,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACxC,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1C;AAEA,SAAS,aAAa,CAAC,SAAiB,EAAA;AACtC,IAAA,OAAO,SAAS,GAAG,IAAI,KAAK;AAC1B,UAAE,CAAA,EAAG,SAAS,GAAG,IAAI,CAAA,QAAA;AACrB,UAAE,CAAA,EAAG,SAAS,CAAA,aAAA,CAAe;AACjC;AAEM,SAAU,0BAA0B,CAAC,QAAiB,EAAA;AAC1D,IAAA,QACE,kBAAkB,CAAC,QAAQ,CAAC;QAC5B,cAAc,CAAC,OAAO,CAAC,GAAG,CAACA,YAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3D,QAAA,+BAA+B;AAEnC;AAEM,SAAU,wBAAwB,CACtC,SAA6B,EAC7B,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,SAAS,CAAC;AAEzD,IAAA,IAAI,mBAAmB,IAAI,IAAI,EAAE;AAC/B,QAAA,OAAO,yBAAyB;IAClC;IAEA,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AACjE;SAEgB,6BAA6B,CAC3C,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;IACxE,MAAM,+BAA+B,GAAG,IAAI,CAAC,GAAG,CAC9C,yBAAyB,EACzB,kCAAkC,CACnC;AACD,IAAA,MAAM,gBAAgB,GAAG,aAAa,CAAC,yBAAyB,CAAC;AACjE,IAAA,MAAM,yBAAyB,GAAG,aAAa,CAC7C,+BAA+B,CAChC;IAED,OAAO;AACL,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,2BAA2B;AACpC,QAAA,OAAO,EAAE,+BAA+B;AACxC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,WAAW,EACT,mFAAmF;YACnF,sDAAsD;AACtD,YAAA,CAAA,SAAA,EAAY,gBAAgB,CAAA,EAAA,CAAI;YAChC,yEAAyE;YACzE,CAAA,YAAA,EAAe,yBAAyB,CAAA,kBAAA,EAAqB,gBAAgB,CAAA,CAAA,CAAG;KACnF;AACH;;;;;;;;;"}
@@ -462,6 +462,90 @@ function unwrapToolResponse(result, isMCPTool) {
462
462
  // Not a formatted response, return as-is
463
463
  return result;
464
464
  }
465
+ function detectSchemaKind(schema) {
466
+ const kind = { object: false, string: false };
467
+ if (!schema || typeof schema !== 'object') {
468
+ return kind;
469
+ }
470
+ const jsonSchemaType = schema.type;
471
+ if (jsonSchemaType === 'object') {
472
+ kind.object = true;
473
+ }
474
+ else if (jsonSchemaType === 'string') {
475
+ kind.string = true;
476
+ }
477
+ else if (Array.isArray(jsonSchemaType)) {
478
+ kind.object = jsonSchemaType.includes('object');
479
+ kind.string = jsonSchemaType.includes('string');
480
+ }
481
+ const zodDef = schema._def;
482
+ if (!zodDef || typeof zodDef !== 'object') {
483
+ return kind;
484
+ }
485
+ const zodType = zodDef.type;
486
+ const zodTypeName = zodDef
487
+ .typeName;
488
+ if (zodType === 'object' || zodTypeName === 'ZodObject') {
489
+ kind.object = true;
490
+ }
491
+ else if (zodType === 'string' || zodTypeName === 'ZodString') {
492
+ kind.string = true;
493
+ }
494
+ const innerSchema = zodDef.innerType ?? zodDef.schema;
495
+ if (innerSchema) {
496
+ const innerKind = detectSchemaKind(innerSchema);
497
+ kind.object ||= innerKind.object;
498
+ kind.string ||= innerKind.string;
499
+ }
500
+ const options = zodDef.options;
501
+ if (Array.isArray(options)) {
502
+ for (const option of options) {
503
+ const optionKind = detectSchemaKind(option);
504
+ kind.object ||= optionKind.object;
505
+ kind.string ||= optionKind.string;
506
+ }
507
+ }
508
+ return kind;
509
+ }
510
+ function getToolInputSchemaKind(tool) {
511
+ if (tool.constructor.name === 'DynamicTool') {
512
+ return { object: false, string: true };
513
+ }
514
+ const schema = tool.schema;
515
+ return detectSchemaKind(schema);
516
+ }
517
+ function normalizeToolInput(input, tool) {
518
+ const schemaKind = getToolInputSchemaKind(tool);
519
+ if (typeof input !== 'string') {
520
+ if (!schemaKind.string || schemaKind.object) {
521
+ return input;
522
+ }
523
+ const inputValue = input.input;
524
+ if (typeof inputValue === 'string') {
525
+ return input;
526
+ }
527
+ return JSON.stringify(input);
528
+ }
529
+ if (!schemaKind.object || schemaKind.string) {
530
+ return input;
531
+ }
532
+ const trimmed = input.trim();
533
+ if (!trimmed.startsWith('{')) {
534
+ return input;
535
+ }
536
+ try {
537
+ const parsed = JSON.parse(trimmed);
538
+ if (typeof parsed === 'object' &&
539
+ parsed !== null &&
540
+ !Array.isArray(parsed)) {
541
+ return parsed;
542
+ }
543
+ }
544
+ catch {
545
+ return input;
546
+ }
547
+ return input;
548
+ }
465
549
  /**
466
550
  * Executes tools in parallel when requested by the API.
467
551
  * Uses Promise.all for parallel execution, catching individual errors.
@@ -482,7 +566,7 @@ async function executeTools(toolCalls, toolMap, programmaticToolName = Constants
482
566
  };
483
567
  }
484
568
  try {
485
- const result = await tool.invoke(call.input, {
569
+ const result = await tool.invoke(normalizeToolInput(call.input, tool), {
486
570
  metadata: { [programmaticToolName]: true },
487
571
  });
488
572
  const isMCPTool = tool.mcp === true;
@@ -1 +1 @@
1
- {"version":3,"file":"ProgrammaticToolCalling.mjs","sources":["../../../src/tools/ProgrammaticToolCalling.ts"],"sourcesContent":["// src/tools/ProgrammaticToolCalling.ts\nimport { config } from 'dotenv';\nimport fetch, { RequestInit } from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { ProgrammaticToolCallingJsonSchema } from './ptcTimeout';\nimport type * as t from '@/types';\nimport {\n CODE_ARTIFACT_PATH_GUIDANCE,\n appendCodeSessionFileSummary,\n appendFailedExecutionFileReminder,\n buildCodeApiHttpErrorMessage,\n emptyOutputMessage,\n getCodeBaseURL,\n appendTmpScratchReminder,\n resolveCodeApiAuthHeaders,\n} from './CodeExecutor';\nimport {\n clampCodeApiRunTimeoutMs,\n createCodeApiRunTimeoutSchema,\n resolveCodeApiRunTimeoutMs,\n} from './ptcTimeout';\nimport { Constants } from '@/common';\n\nconfig();\n\n/** Default max round-trips to prevent infinite loops */\nconst DEFAULT_MAX_ROUND_TRIPS = 20;\n\nconst DEFAULT_RUN_TIMEOUT_MS = resolveCodeApiRunTimeoutMs();\n\n// ============================================================================\n// Description Components (Single Source of Truth)\n// ============================================================================\n\nconst STATELESS_WARNING = `CRITICAL - STATELESS EXECUTION:\nEach call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.\nYou MUST complete your entire workflow in ONE code block: query → process → output.\nDO NOT split work across multiple calls expecting to reuse variables.`;\n\nconst CORE_RULES = `Rules:\n- One call: state does not persist\n- Auto-wrapped async; use await, no main()/asyncio.run()\n- Tools are pre-defined—DO NOT write function definitions\n- Call tools with keyword args only (await tool(arg=value), never pass a dict)\n- Tool results are decoded Python values (dict/list/str)\n- Only print() output returns to the model\n- ${CODE_ARTIFACT_PATH_GUIDANCE}\n- timeout caps one sandbox run/replay iteration, not the total multi-round-trip workflow`;\n\nconst ADDITIONAL_RULES =\n '- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix';\n\nconst EXAMPLES = `Example (Complete workflow in one call):\n # Query data\n data = await query_database(sql=\"SELECT * FROM users\")\n # Process it\n df = pd.DataFrame(data)\n summary = df.groupby('region').sum()\n # Output results\n await write_to_sheet(spreadsheet_id=sid, data=summary.to_dict())\n print(f\"Wrote {len(summary)} rows\")\n\nExample (Parallel calls):\n sf, ny = await asyncio.gather(get_weather(city=\"SF\"), get_weather(city=\"NY\"))\n print(f\"SF: {sf}, NY: {ny}\")`;\n\n// ============================================================================\n// Schema\n// ============================================================================\n\nconst CODE_PARAM_DESCRIPTION = `Python code that calls tools programmatically. Tools are available as async functions.\n\n${STATELESS_WARNING}\n\nYour code is auto-wrapped in async context. Just write logic with await—no boilerplate needed.\n\n${EXAMPLES}\n\n${CORE_RULES}`;\n\nexport function createProgrammaticToolCallingSchema(\n maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS\n): ProgrammaticToolCallingJsonSchema {\n return {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n minLength: 1,\n description: CODE_PARAM_DESCRIPTION,\n },\n timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),\n },\n required: ['code'],\n } as const;\n}\n\nexport const ProgrammaticToolCallingSchema =\n createProgrammaticToolCallingSchema();\n\nexport const ProgrammaticToolCallingName = Constants.PROGRAMMATIC_TOOL_CALLING;\n\nexport const ProgrammaticToolCallingDescription = `\nRun tools via Python code. Auto-wrapped in async context—just use \\`await\\` directly.\n\n${STATELESS_WARNING}\n\n${CORE_RULES}\n${ADDITIONAL_RULES}\n\nWhen to use: loops, conditionals, parallel (\\`asyncio.gather\\`), multi-step pipelines.\n\n${EXAMPLES}\n`.trim();\n\nexport const ProgrammaticToolCallingDefinition = {\n name: ProgrammaticToolCallingName,\n description: ProgrammaticToolCallingDescription,\n schema: ProgrammaticToolCallingSchema,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Python reserved keywords that get `_tool` suffix in Code API */\nconst PYTHON_KEYWORDS = new Set([\n 'False',\n 'None',\n 'True',\n 'and',\n 'as',\n 'assert',\n 'async',\n 'await',\n 'break',\n 'class',\n 'continue',\n 'def',\n 'del',\n 'elif',\n 'else',\n 'except',\n 'finally',\n 'for',\n 'from',\n 'global',\n 'if',\n 'import',\n 'in',\n 'is',\n 'lambda',\n 'nonlocal',\n 'not',\n 'or',\n 'pass',\n 'raise',\n 'return',\n 'try',\n 'while',\n 'with',\n 'yield',\n]);\n\nexport type FetchSessionFilesScope =\n | { kind: 'skill'; id: string; version: number }\n | { kind: 'agent' | 'user'; id: string; version?: never };\n\ntype CodeApiSessionFileWire = {\n id?: unknown;\n name?: unknown;\n metadata?: unknown;\n resource_id?: unknown;\n storage_session_id?: unknown;\n};\n\ntype CodeApiSessionFileMetadata = {\n 'original-filename'?: unknown;\n};\n\nfunction isFetchSessionFilesScope(\n value: unknown\n): value is FetchSessionFilesScope {\n if (value == null || typeof value !== 'object') {\n return false;\n }\n const scope = value as { kind?: unknown; id?: unknown; version?: unknown };\n if (\n (scope.kind === 'agent' || scope.kind === 'user') &&\n typeof scope.id === 'string'\n ) {\n return true;\n }\n return (\n scope.kind === 'skill' &&\n typeof scope.id === 'string' &&\n typeof scope.version === 'number'\n );\n}\n\nfunction isCodeApiAuthHeaders(\n value: string | t.CodeApiAuthHeaders | undefined\n): value is t.CodeApiAuthHeaders {\n return value != null && typeof value !== 'string';\n}\n\nfunction isCodeApiSessionFileWire(\n value: unknown\n): value is CodeApiSessionFileWire {\n return value != null && typeof value === 'object';\n}\n\nfunction isCodeApiSessionFileMetadata(\n value: unknown\n): value is CodeApiSessionFileMetadata {\n return value != null && typeof value === 'object';\n}\n\nfunction normalizeSessionFile(\n file: CodeApiSessionFileWire,\n sessionId: string,\n scope?: FetchSessionFilesScope\n): t.CodeEnvFile {\n const metadata = isCodeApiSessionFileMetadata(file.metadata)\n ? file.metadata\n : undefined;\n const rawName = typeof file.name === 'string' ? file.name : '';\n const nameParts = rawName.split('/');\n const fallbackId = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';\n const id =\n typeof file.id === 'string' && file.id !== '' ? file.id : fallbackId;\n const originalFilename = metadata?.['original-filename'];\n const name =\n typeof originalFilename === 'string' ? originalFilename : rawName;\n const storage_session_id =\n typeof file.storage_session_id === 'string'\n ? file.storage_session_id\n : sessionId;\n const resource_id =\n typeof file.resource_id === 'string' && file.resource_id !== ''\n ? file.resource_id\n : (scope?.id ?? id);\n\n if (scope?.kind === 'skill') {\n return {\n storage_session_id,\n kind: 'skill',\n id,\n resource_id,\n name,\n version: scope.version,\n };\n }\n if (scope != null) {\n return {\n storage_session_id,\n kind: scope.kind,\n id,\n resource_id,\n name,\n };\n }\n return {\n storage_session_id,\n kind: 'user',\n id,\n resource_id: id,\n name,\n };\n}\n\n/**\n * Normalizes a tool name to Python identifier format.\n * Must match the Code API's `normalizePythonFunctionName` exactly:\n * 1. Replace hyphens and spaces with underscores\n * 2. Remove any other invalid characters\n * 3. Prefix with underscore if starts with number\n * 4. Append `_tool` if it's a Python keyword\n * @param name - The tool name to normalize\n * @returns Normalized Python-safe identifier\n */\nexport function normalizeToPythonIdentifier(name: string): string {\n let normalized = name.replace(/[-\\s]/g, '_');\n\n normalized = normalized.replace(/[^a-zA-Z0-9_]/g, '');\n\n if (/^[0-9]/.test(normalized)) {\n normalized = '_' + normalized;\n }\n\n if (PYTHON_KEYWORDS.has(normalized)) {\n normalized = normalized + '_tool';\n }\n\n return normalized;\n}\n\n/**\n * Extracts tool names that are actually called in the Python code.\n * Handles hyphen/underscore conversion since Python identifiers use underscores.\n * @param code - The Python code to analyze\n * @param toolNameMap - Map from normalized Python name to original tool name\n * @returns Set of original tool names found in the code\n */\nexport function extractUsedToolNames(\n code: string,\n toolNameMap: Map<string, string>\n): Set<string> {\n const usedTools = new Set<string>();\n\n for (const [pythonName, originalName] of toolNameMap) {\n const escapedName = pythonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`\\\\b${escapedName}\\\\s*\\\\(`, 'g');\n\n if (pattern.test(code)) {\n usedTools.add(originalName);\n }\n }\n\n return usedTools;\n}\n\n/**\n * Filters tool definitions to only include tools actually used in the code.\n * Handles the hyphen-to-underscore conversion for Python compatibility.\n * @param toolDefs - All available tool definitions\n * @param code - The Python code to analyze\n * @param debug - Enable debug logging\n * @returns Filtered array of tool definitions\n */\nexport function filterToolsByUsage(\n toolDefs: t.LCTool[],\n code: string,\n debug = false\n): t.LCTool[] {\n const toolNameMap = new Map<string, string>();\n for (const tool of toolDefs) {\n const pythonName = normalizeToPythonIdentifier(tool.name);\n toolNameMap.set(pythonName, tool.name);\n }\n\n const usedToolNames = extractUsedToolNames(code, toolNameMap);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`\n );\n if (usedToolNames.size > 0) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(', ')}`\n );\n }\n }\n\n if (usedToolNames.size === 0) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[PTC Debug] No tools detected in code - sending all tools as fallback'\n );\n }\n return toolDefs;\n }\n\n return toolDefs.filter((tool) => usedToolNames.has(tool.name));\n}\n\n/**\n * Fetches files from a previous session to make them available for the current execution.\n * Files are returned as CodeEnvFile references to be included in the request.\n * @param baseUrl - The base URL for the Code API\n * @param sessionId - The session ID to fetch files from\n * @param scope - Resource scope used by CodeAPI to authorize the session\n * @param proxy - Optional HTTP proxy URL\n * @returns Array of CodeEnvFile references, or empty array if fetch fails\n */\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scope: FetchSessionFilesScope,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scopeOrProxy?: FetchSessionFilesScope | string,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n scopedAuthHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]> {\n try {\n const scope = isFetchSessionFilesScope(scopeOrProxy)\n ? scopeOrProxy\n : undefined;\n let proxy: string | undefined;\n let authHeaders: t.CodeApiAuthHeaders | undefined;\n if (scope == null) {\n proxy = typeof scopeOrProxy === 'string' ? scopeOrProxy : undefined;\n authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders)\n ? proxyOrAuthHeaders\n : undefined;\n } else if (typeof proxyOrAuthHeaders === 'string') {\n proxy = proxyOrAuthHeaders;\n authHeaders = scopedAuthHeaders;\n } else {\n authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;\n }\n const query = new URLSearchParams({ detail: 'full' });\n if (scope != null) {\n query.set('kind', scope.kind);\n query.set('id', scope.id);\n if (scope.kind === 'skill') {\n query.set('version', String(scope.version));\n }\n }\n const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'GET',\n headers: {\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(filesEndpoint, fetchOptions);\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('GET', filesEndpoint, response)\n );\n }\n\n const files = await response.json();\n if (!Array.isArray(files) || files.length === 0) {\n return [];\n }\n\n return files\n .filter(isCodeApiSessionFileWire)\n .map((file) => normalizeSessionFile(file, sessionId, scope));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to fetch files for session: ${sessionId}, ${(error as Error).message}`\n );\n return [];\n }\n}\n\n/**\n * Makes an HTTP request to the Code API.\n * @param endpoint - The API endpoint URL\n * @param body - The request body\n * @param proxy - Optional HTTP proxy URL\n * @returns The parsed API response\n */\nexport async function makeRequest(\n endpoint: string,\n body: Record<string, unknown>,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.ProgrammaticExecutionResponse> {\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n body: JSON.stringify(body),\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('POST', endpoint, response)\n );\n }\n\n return (await response.json()) as t.ProgrammaticExecutionResponse;\n}\n\n/**\n * Unwraps tool responses that may be formatted as tuples or content blocks.\n * MCP tools return [content, artifacts], we need to extract the raw data.\n * @param result - The raw result from tool.invoke()\n * @param isMCPTool - Whether this is an MCP tool (has mcp property)\n * @returns Unwrapped raw data (string, object, or parsed JSON)\n */\nexport function unwrapToolResponse(\n result: unknown,\n isMCPTool: boolean\n): unknown {\n // Only unwrap if this is an MCP tool and result is a tuple\n if (!isMCPTool) {\n return result;\n }\n\n /**\n * Checks if a value is a content block object (has type and text).\n */\n const isContentBlock = (value: unknown): boolean => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const obj = value as Record<string, unknown>;\n return typeof obj.type === 'string';\n };\n\n /**\n * Checks if an array is an array of content blocks.\n */\n const isContentBlockArray = (arr: unknown[]): boolean => {\n return arr.length > 0 && arr.every(isContentBlock);\n };\n\n /**\n * Extracts text from a single content block object.\n * Returns the text if it's a text block, otherwise returns null.\n */\n const extractTextFromBlock = (block: unknown): string | null => {\n if (typeof block !== 'object' || block === null) return null;\n const b = block as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n return b.text;\n }\n return null;\n };\n\n /**\n * Extracts text from content blocks (array or single object).\n * Returns combined text or null if no text blocks found.\n */\n const extractTextFromContent = (content: unknown): string | null => {\n // Single content block object: { type: 'text', text: '...' }\n if (\n typeof content === 'object' &&\n content !== null &&\n !Array.isArray(content)\n ) {\n const text = extractTextFromBlock(content);\n if (text !== null) return text;\n }\n\n // Array of content blocks: [{ type: 'text', text: '...' }, ...]\n if (Array.isArray(content) && content.length > 0) {\n const texts = content\n .map(extractTextFromBlock)\n .filter((t): t is string => t !== null);\n if (texts.length > 0) {\n return texts.join('\\n');\n }\n }\n\n return null;\n };\n\n /**\n * Tries to parse a string as JSON if it looks like JSON.\n */\n const maybeParseJSON = (str: string): unknown => {\n const trimmed = str.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.parse(trimmed);\n } catch {\n return str;\n }\n }\n return str;\n };\n\n // Handle array of content blocks at top level FIRST\n // (before checking for tuple, since both are arrays)\n if (Array.isArray(result) && isContentBlockArray(result)) {\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n }\n\n // Check if result is a tuple/array with [content, artifacts]\n if (Array.isArray(result) && result.length >= 1) {\n const [content] = result;\n\n // If first element is a string, return it (possibly parsed as JSON)\n if (typeof content === 'string') {\n return maybeParseJSON(content);\n }\n\n // Try to extract text from content blocks\n const extractedText = extractTextFromContent(content);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // If first element is an object (but not a text block), return it\n if (typeof content === 'object' && content !== null) {\n return content;\n }\n }\n\n // Handle single content block object at top level (not in tuple)\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // Not a formatted response, return as-is\n return result;\n}\n\n/**\n * Executes tools in parallel when requested by the API.\n * Uses Promise.all for parallel execution, catching individual errors.\n * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.\n * @param toolCalls - Array of tool calls from the API\n * @param toolMap - Map of tool names to executable tools\n * @returns Array of tool results\n */\nexport async function executeTools(\n toolCalls: t.PTCToolCall[],\n toolMap: t.ToolMap,\n programmaticToolName = Constants.PROGRAMMATIC_TOOL_CALLING\n): Promise<t.PTCToolResult[]> {\n const executions = toolCalls.map(async (call): Promise<t.PTCToolResult> => {\n const tool = toolMap.get(call.name);\n\n if (!tool) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(', ')}`,\n };\n }\n\n try {\n const result = await tool.invoke(call.input, {\n metadata: { [programmaticToolName]: true },\n });\n\n const isMCPTool = tool.mcp === true;\n const unwrappedResult = unwrapToolResponse(result, isMCPTool);\n\n return {\n call_id: call.id,\n result: unwrappedResult,\n is_error: false,\n };\n } catch (error) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: (error as Error).message || 'Tool execution failed',\n };\n }\n });\n\n return await Promise.all(executions);\n}\n\n/**\n * Formats the completed response for the agent.\n *\n * Output includes stdout/stderr plus a compact session-file summary\n * when artifacts were persisted. The artifact still carries every\n * file so the host's session map stays in sync.\n *\n * @param response - The completed API response\n * @returns Tuple of [formatted string, artifact]\n */\nexport function formatCompletedResponse(\n response: t.ProgrammaticExecutionResponse,\n sourceCode = ''\n): [string, t.ProgrammaticExecutionArtifact] {\n let formatted = '';\n\n if (response.stdout != null && response.stdout !== '') {\n formatted += `stdout:\\n${response.stdout}\\n`;\n } else {\n formatted += emptyOutputMessage;\n }\n\n if (response.stderr != null && response.stderr !== '') {\n formatted += `stderr:\\n${response.stderr}\\n`;\n }\n\n const outputWithReminder = appendTmpScratchReminder(formatted, sourceCode);\n\n return [\n appendCodeSessionFileSummary(outputWithReminder, response.files),\n {\n session_id: response.session_id,\n files: response.files,\n } satisfies t.ProgrammaticExecutionArtifact,\n ];\n}\n\n// ============================================================================\n// Tool Factory\n// ============================================================================\n\n/**\n * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.\n *\n * This tool enables AI agents to write Python code that orchestrates multiple\n * tool calls programmatically, reducing LLM round-trips and token usage.\n *\n * The tool map must be provided at runtime via config.configurable.toolMap.\n *\n * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)\n * @returns A LangChain DynamicStructuredTool for programmatic tool calling\n *\n * @example\n * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });\n *\n * const [output, artifact] = await ptcTool.invoke(\n * { code, tools },\n * { configurable: { toolMap } }\n * );\n */\nexport function createProgrammaticToolCallingTool(\n initParams: t.ProgrammaticToolCallingParams = {}\n): DynamicStructuredTool {\n const baseUrl = initParams.baseUrl ?? getCodeBaseURL();\n const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;\n const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);\n const proxy = initParams.proxy ?? process.env.PROXY;\n const debug = initParams.debug ?? process.env.PTC_DEBUG === 'true';\n const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;\n\n return tool(\n async (rawParams, config) => {\n const params = rawParams as { code: string; timeout?: number };\n const { code } = params;\n const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);\n\n // Extra params injected by ToolNode (follows web_search pattern).\n const toolCall = (config.toolCall ?? {}) as ToolCall &\n Partial<t.ProgrammaticCache> & {\n session_id?: string;\n _injected_files?: t.CodeEnvFile[];\n };\n const { toolMap, toolDefs, session_id, _injected_files } = toolCall;\n\n if (toolMap == null || toolMap.size === 0) {\n throw new Error(\n 'No toolMap provided. ' +\n 'ToolNode should inject this from AgentContext when invoked through the graph.'\n );\n }\n\n if (toolDefs == null || toolDefs.length === 0) {\n throw new Error(\n 'No tool definitions provided. ' +\n 'Either pass tools in the input or ensure ToolNode injects toolDefs.'\n );\n }\n\n let roundTrip = 0;\n\n try {\n // ====================================================================\n // Phase 1: Filter tools and make initial request\n // ====================================================================\n\n const effectiveTools = filterToolsByUsage(toolDefs, code, debug);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Sending ${effectiveTools.length} tools to API ` +\n `(filtered from ${toolDefs.length})`\n );\n }\n\n /**\n * File injection: `_injected_files` from ToolNode session\n * context. The legacy `/files/<session_id>` HTTP fallback was\n * removed (see `CodeExecutor.ts`) — codeapi's sessionAuth now\n * requires kind/id query params unavailable at this point.\n */\n let files: t.CodeEnvFile[] | undefined;\n if (_injected_files && _injected_files.length > 0) {\n files = _injected_files;\n } else if (session_id != null && session_id.length > 0) {\n // eslint-disable-next-line no-console\n console.debug(\n `[ProgrammaticToolCalling] No injected files for session_id=${session_id} — exec will run without input files`\n );\n }\n\n let response = await makeRequest(\n EXEC_ENDPOINT,\n {\n code,\n tools: effectiveTools,\n session_id,\n timeout,\n ...(files && files.length > 0 ? { files } : {}),\n },\n proxy,\n initParams.authHeaders\n );\n\n // ====================================================================\n // Phase 2: Handle response loop\n // ====================================================================\n\n while (response.status === 'tool_call_required') {\n roundTrip++;\n\n if (roundTrip > maxRoundTrips) {\n throw new Error(\n `Exceeded maximum round trips (${maxRoundTrips}). ` +\n 'This may indicate an infinite loop, excessive tool calls, ' +\n 'or a logic error in your code.'\n );\n }\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`\n );\n }\n\n const toolResults = await executeTools(\n response.tool_calls ?? [],\n toolMap\n );\n\n response = await makeRequest(\n EXEC_ENDPOINT,\n {\n continuation_token: response.continuation_token,\n tool_results: toolResults,\n },\n proxy,\n initParams.authHeaders\n );\n }\n\n // ====================================================================\n // Phase 3: Handle final state\n // ====================================================================\n\n if (response.status === 'completed') {\n return formatCompletedResponse(response, code);\n }\n\n if (response.status === 'error') {\n throw new Error(\n `Execution error: ${response.error}` +\n (response.stderr != null && response.stderr !== ''\n ? `\\n\\nStderr:\\n${response.stderr}`\n : '')\n );\n }\n\n throw new Error(`Unexpected response status: ${response.status}`);\n } catch (error) {\n const messageWithReminder = appendFailedExecutionFileReminder(\n (error as Error).message,\n code\n );\n throw new Error(\n `Programmatic execution failed: ${messageWithReminder}`\n );\n }\n },\n {\n name: Constants.PROGRAMMATIC_TOOL_CALLING,\n description: ProgrammaticToolCallingDescription,\n schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ProgrammaticToolCalling.mjs","sources":["../../../src/tools/ProgrammaticToolCalling.ts"],"sourcesContent":["// src/tools/ProgrammaticToolCalling.ts\nimport { config } from 'dotenv';\nimport fetch, { RequestInit } from 'node-fetch';\nimport { HttpsProxyAgent } from 'https-proxy-agent';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\nimport type { ToolCall } from '@langchain/core/messages/tool';\nimport type { ProgrammaticToolCallingJsonSchema } from './ptcTimeout';\nimport type * as t from '@/types';\nimport {\n CODE_ARTIFACT_PATH_GUIDANCE,\n appendCodeSessionFileSummary,\n appendFailedExecutionFileReminder,\n buildCodeApiHttpErrorMessage,\n emptyOutputMessage,\n getCodeBaseURL,\n appendTmpScratchReminder,\n resolveCodeApiAuthHeaders,\n} from './CodeExecutor';\nimport {\n clampCodeApiRunTimeoutMs,\n createCodeApiRunTimeoutSchema,\n resolveCodeApiRunTimeoutMs,\n} from './ptcTimeout';\nimport { Constants } from '@/common';\n\nconfig();\n\n/** Default max round-trips to prevent infinite loops */\nconst DEFAULT_MAX_ROUND_TRIPS = 20;\n\nconst DEFAULT_RUN_TIMEOUT_MS = resolveCodeApiRunTimeoutMs();\n\n// ============================================================================\n// Description Components (Single Source of Truth)\n// ============================================================================\n\nconst STATELESS_WARNING = `CRITICAL - STATELESS EXECUTION:\nEach call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.\nYou MUST complete your entire workflow in ONE code block: query → process → output.\nDO NOT split work across multiple calls expecting to reuse variables.`;\n\nconst CORE_RULES = `Rules:\n- One call: state does not persist\n- Auto-wrapped async; use await, no main()/asyncio.run()\n- Tools are pre-defined—DO NOT write function definitions\n- Call tools with keyword args only (await tool(arg=value), never pass a dict)\n- Tool results are decoded Python values (dict/list/str)\n- Only print() output returns to the model\n- ${CODE_ARTIFACT_PATH_GUIDANCE}\n- timeout caps one sandbox run/replay iteration, not the total multi-round-trip workflow`;\n\nconst ADDITIONAL_RULES =\n '- Tool names normalized: hyphens→underscores, keywords get `_tool` suffix';\n\nconst EXAMPLES = `Example (Complete workflow in one call):\n # Query data\n data = await query_database(sql=\"SELECT * FROM users\")\n # Process it\n df = pd.DataFrame(data)\n summary = df.groupby('region').sum()\n # Output results\n await write_to_sheet(spreadsheet_id=sid, data=summary.to_dict())\n print(f\"Wrote {len(summary)} rows\")\n\nExample (Parallel calls):\n sf, ny = await asyncio.gather(get_weather(city=\"SF\"), get_weather(city=\"NY\"))\n print(f\"SF: {sf}, NY: {ny}\")`;\n\n// ============================================================================\n// Schema\n// ============================================================================\n\nconst CODE_PARAM_DESCRIPTION = `Python code that calls tools programmatically. Tools are available as async functions.\n\n${STATELESS_WARNING}\n\nYour code is auto-wrapped in async context. Just write logic with await—no boilerplate needed.\n\n${EXAMPLES}\n\n${CORE_RULES}`;\n\nexport function createProgrammaticToolCallingSchema(\n maxRunTimeoutMs = DEFAULT_RUN_TIMEOUT_MS\n): ProgrammaticToolCallingJsonSchema {\n return {\n type: 'object',\n properties: {\n code: {\n type: 'string',\n minLength: 1,\n description: CODE_PARAM_DESCRIPTION,\n },\n timeout: createCodeApiRunTimeoutSchema(maxRunTimeoutMs),\n },\n required: ['code'],\n } as const;\n}\n\nexport const ProgrammaticToolCallingSchema =\n createProgrammaticToolCallingSchema();\n\nexport const ProgrammaticToolCallingName = Constants.PROGRAMMATIC_TOOL_CALLING;\n\nexport const ProgrammaticToolCallingDescription = `\nRun tools via Python code. Auto-wrapped in async context—just use \\`await\\` directly.\n\n${STATELESS_WARNING}\n\n${CORE_RULES}\n${ADDITIONAL_RULES}\n\nWhen to use: loops, conditionals, parallel (\\`asyncio.gather\\`), multi-step pipelines.\n\n${EXAMPLES}\n`.trim();\n\nexport const ProgrammaticToolCallingDefinition = {\n name: ProgrammaticToolCallingName,\n description: ProgrammaticToolCallingDescription,\n schema: ProgrammaticToolCallingSchema,\n} as const;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/** Python reserved keywords that get `_tool` suffix in Code API */\nconst PYTHON_KEYWORDS = new Set([\n 'False',\n 'None',\n 'True',\n 'and',\n 'as',\n 'assert',\n 'async',\n 'await',\n 'break',\n 'class',\n 'continue',\n 'def',\n 'del',\n 'elif',\n 'else',\n 'except',\n 'finally',\n 'for',\n 'from',\n 'global',\n 'if',\n 'import',\n 'in',\n 'is',\n 'lambda',\n 'nonlocal',\n 'not',\n 'or',\n 'pass',\n 'raise',\n 'return',\n 'try',\n 'while',\n 'with',\n 'yield',\n]);\n\nexport type FetchSessionFilesScope =\n | { kind: 'skill'; id: string; version: number }\n | { kind: 'agent' | 'user'; id: string; version?: never };\n\ntype CodeApiSessionFileWire = {\n id?: unknown;\n name?: unknown;\n metadata?: unknown;\n resource_id?: unknown;\n storage_session_id?: unknown;\n};\n\ntype CodeApiSessionFileMetadata = {\n 'original-filename'?: unknown;\n};\n\nfunction isFetchSessionFilesScope(\n value: unknown\n): value is FetchSessionFilesScope {\n if (value == null || typeof value !== 'object') {\n return false;\n }\n const scope = value as { kind?: unknown; id?: unknown; version?: unknown };\n if (\n (scope.kind === 'agent' || scope.kind === 'user') &&\n typeof scope.id === 'string'\n ) {\n return true;\n }\n return (\n scope.kind === 'skill' &&\n typeof scope.id === 'string' &&\n typeof scope.version === 'number'\n );\n}\n\nfunction isCodeApiAuthHeaders(\n value: string | t.CodeApiAuthHeaders | undefined\n): value is t.CodeApiAuthHeaders {\n return value != null && typeof value !== 'string';\n}\n\nfunction isCodeApiSessionFileWire(\n value: unknown\n): value is CodeApiSessionFileWire {\n return value != null && typeof value === 'object';\n}\n\nfunction isCodeApiSessionFileMetadata(\n value: unknown\n): value is CodeApiSessionFileMetadata {\n return value != null && typeof value === 'object';\n}\n\nfunction normalizeSessionFile(\n file: CodeApiSessionFileWire,\n sessionId: string,\n scope?: FetchSessionFilesScope\n): t.CodeEnvFile {\n const metadata = isCodeApiSessionFileMetadata(file.metadata)\n ? file.metadata\n : undefined;\n const rawName = typeof file.name === 'string' ? file.name : '';\n const nameParts = rawName.split('/');\n const fallbackId = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';\n const id =\n typeof file.id === 'string' && file.id !== '' ? file.id : fallbackId;\n const originalFilename = metadata?.['original-filename'];\n const name =\n typeof originalFilename === 'string' ? originalFilename : rawName;\n const storage_session_id =\n typeof file.storage_session_id === 'string'\n ? file.storage_session_id\n : sessionId;\n const resource_id =\n typeof file.resource_id === 'string' && file.resource_id !== ''\n ? file.resource_id\n : (scope?.id ?? id);\n\n if (scope?.kind === 'skill') {\n return {\n storage_session_id,\n kind: 'skill',\n id,\n resource_id,\n name,\n version: scope.version,\n };\n }\n if (scope != null) {\n return {\n storage_session_id,\n kind: scope.kind,\n id,\n resource_id,\n name,\n };\n }\n return {\n storage_session_id,\n kind: 'user',\n id,\n resource_id: id,\n name,\n };\n}\n\n/**\n * Normalizes a tool name to Python identifier format.\n * Must match the Code API's `normalizePythonFunctionName` exactly:\n * 1. Replace hyphens and spaces with underscores\n * 2. Remove any other invalid characters\n * 3. Prefix with underscore if starts with number\n * 4. Append `_tool` if it's a Python keyword\n * @param name - The tool name to normalize\n * @returns Normalized Python-safe identifier\n */\nexport function normalizeToPythonIdentifier(name: string): string {\n let normalized = name.replace(/[-\\s]/g, '_');\n\n normalized = normalized.replace(/[^a-zA-Z0-9_]/g, '');\n\n if (/^[0-9]/.test(normalized)) {\n normalized = '_' + normalized;\n }\n\n if (PYTHON_KEYWORDS.has(normalized)) {\n normalized = normalized + '_tool';\n }\n\n return normalized;\n}\n\n/**\n * Extracts tool names that are actually called in the Python code.\n * Handles hyphen/underscore conversion since Python identifiers use underscores.\n * @param code - The Python code to analyze\n * @param toolNameMap - Map from normalized Python name to original tool name\n * @returns Set of original tool names found in the code\n */\nexport function extractUsedToolNames(\n code: string,\n toolNameMap: Map<string, string>\n): Set<string> {\n const usedTools = new Set<string>();\n\n for (const [pythonName, originalName] of toolNameMap) {\n const escapedName = pythonName.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n const pattern = new RegExp(`\\\\b${escapedName}\\\\s*\\\\(`, 'g');\n\n if (pattern.test(code)) {\n usedTools.add(originalName);\n }\n }\n\n return usedTools;\n}\n\n/**\n * Filters tool definitions to only include tools actually used in the code.\n * Handles the hyphen-to-underscore conversion for Python compatibility.\n * @param toolDefs - All available tool definitions\n * @param code - The Python code to analyze\n * @param debug - Enable debug logging\n * @returns Filtered array of tool definitions\n */\nexport function filterToolsByUsage(\n toolDefs: t.LCTool[],\n code: string,\n debug = false\n): t.LCTool[] {\n const toolNameMap = new Map<string, string>();\n for (const tool of toolDefs) {\n const pythonName = normalizeToPythonIdentifier(tool.name);\n toolNameMap.set(pythonName, tool.name);\n }\n\n const usedToolNames = extractUsedToolNames(code, toolNameMap);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Tool filtering: found ${usedToolNames.size}/${toolDefs.length} tools in code`\n );\n if (usedToolNames.size > 0) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Matched tools: ${Array.from(usedToolNames).join(', ')}`\n );\n }\n }\n\n if (usedToolNames.size === 0) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[PTC Debug] No tools detected in code - sending all tools as fallback'\n );\n }\n return toolDefs;\n }\n\n return toolDefs.filter((tool) => usedToolNames.has(tool.name));\n}\n\n/**\n * Fetches files from a previous session to make them available for the current execution.\n * Files are returned as CodeEnvFile references to be included in the request.\n * @param baseUrl - The base URL for the Code API\n * @param sessionId - The session ID to fetch files from\n * @param scope - Resource scope used by CodeAPI to authorize the session\n * @param proxy - Optional HTTP proxy URL\n * @returns Array of CodeEnvFile references, or empty array if fetch fails\n */\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scope: FetchSessionFilesScope,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]>;\nexport async function fetchSessionFiles(\n baseUrl: string,\n sessionId: string,\n scopeOrProxy?: FetchSessionFilesScope | string,\n proxyOrAuthHeaders?: string | t.CodeApiAuthHeaders,\n scopedAuthHeaders?: t.CodeApiAuthHeaders\n): Promise<t.CodeEnvFile[]> {\n try {\n const scope = isFetchSessionFilesScope(scopeOrProxy)\n ? scopeOrProxy\n : undefined;\n let proxy: string | undefined;\n let authHeaders: t.CodeApiAuthHeaders | undefined;\n if (scope == null) {\n proxy = typeof scopeOrProxy === 'string' ? scopeOrProxy : undefined;\n authHeaders = isCodeApiAuthHeaders(proxyOrAuthHeaders)\n ? proxyOrAuthHeaders\n : undefined;\n } else if (typeof proxyOrAuthHeaders === 'string') {\n proxy = proxyOrAuthHeaders;\n authHeaders = scopedAuthHeaders;\n } else {\n authHeaders = proxyOrAuthHeaders ?? scopedAuthHeaders;\n }\n const query = new URLSearchParams({ detail: 'full' });\n if (scope != null) {\n query.set('kind', scope.kind);\n query.set('id', scope.id);\n if (scope.kind === 'skill') {\n query.set('version', String(scope.version));\n }\n }\n const filesEndpoint = `${baseUrl}/files/${encodeURIComponent(sessionId)}?${query.toString()}`;\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'GET',\n headers: {\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(filesEndpoint, fetchOptions);\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('GET', filesEndpoint, response)\n );\n }\n\n const files = await response.json();\n if (!Array.isArray(files) || files.length === 0) {\n return [];\n }\n\n return files\n .filter(isCodeApiSessionFileWire)\n .map((file) => normalizeSessionFile(file, sessionId, scope));\n } catch (error) {\n // eslint-disable-next-line no-console\n console.warn(\n `Failed to fetch files for session: ${sessionId}, ${(error as Error).message}`\n );\n return [];\n }\n}\n\n/**\n * Makes an HTTP request to the Code API.\n * @param endpoint - The API endpoint URL\n * @param body - The request body\n * @param proxy - Optional HTTP proxy URL\n * @returns The parsed API response\n */\nexport async function makeRequest(\n endpoint: string,\n body: Record<string, unknown>,\n proxy?: string,\n authHeaders?: t.CodeApiAuthHeaders\n): Promise<t.ProgrammaticExecutionResponse> {\n const resolvedAuthHeaders = await resolveCodeApiAuthHeaders(authHeaders);\n const fetchOptions: RequestInit = {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n ...resolvedAuthHeaders,\n },\n body: JSON.stringify(body),\n };\n\n if (proxy != null && proxy !== '') {\n fetchOptions.agent = new HttpsProxyAgent(proxy);\n }\n\n const response = await fetch(endpoint, fetchOptions);\n\n if (!response.ok) {\n throw new Error(\n await buildCodeApiHttpErrorMessage('POST', endpoint, response)\n );\n }\n\n return (await response.json()) as t.ProgrammaticExecutionResponse;\n}\n\n/**\n * Unwraps tool responses that may be formatted as tuples or content blocks.\n * MCP tools return [content, artifacts], we need to extract the raw data.\n * @param result - The raw result from tool.invoke()\n * @param isMCPTool - Whether this is an MCP tool (has mcp property)\n * @returns Unwrapped raw data (string, object, or parsed JSON)\n */\nexport function unwrapToolResponse(\n result: unknown,\n isMCPTool: boolean\n): unknown {\n // Only unwrap if this is an MCP tool and result is a tuple\n if (!isMCPTool) {\n return result;\n }\n\n /**\n * Checks if a value is a content block object (has type and text).\n */\n const isContentBlock = (value: unknown): boolean => {\n if (typeof value !== 'object' || value === null || Array.isArray(value)) {\n return false;\n }\n const obj = value as Record<string, unknown>;\n return typeof obj.type === 'string';\n };\n\n /**\n * Checks if an array is an array of content blocks.\n */\n const isContentBlockArray = (arr: unknown[]): boolean => {\n return arr.length > 0 && arr.every(isContentBlock);\n };\n\n /**\n * Extracts text from a single content block object.\n * Returns the text if it's a text block, otherwise returns null.\n */\n const extractTextFromBlock = (block: unknown): string | null => {\n if (typeof block !== 'object' || block === null) return null;\n const b = block as Record<string, unknown>;\n if (b.type === 'text' && typeof b.text === 'string') {\n return b.text;\n }\n return null;\n };\n\n /**\n * Extracts text from content blocks (array or single object).\n * Returns combined text or null if no text blocks found.\n */\n const extractTextFromContent = (content: unknown): string | null => {\n // Single content block object: { type: 'text', text: '...' }\n if (\n typeof content === 'object' &&\n content !== null &&\n !Array.isArray(content)\n ) {\n const text = extractTextFromBlock(content);\n if (text !== null) return text;\n }\n\n // Array of content blocks: [{ type: 'text', text: '...' }, ...]\n if (Array.isArray(content) && content.length > 0) {\n const texts = content\n .map(extractTextFromBlock)\n .filter((t): t is string => t !== null);\n if (texts.length > 0) {\n return texts.join('\\n');\n }\n }\n\n return null;\n };\n\n /**\n * Tries to parse a string as JSON if it looks like JSON.\n */\n const maybeParseJSON = (str: string): unknown => {\n const trimmed = str.trim();\n if (trimmed.startsWith('{') || trimmed.startsWith('[')) {\n try {\n return JSON.parse(trimmed);\n } catch {\n return str;\n }\n }\n return str;\n };\n\n // Handle array of content blocks at top level FIRST\n // (before checking for tuple, since both are arrays)\n if (Array.isArray(result) && isContentBlockArray(result)) {\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n }\n\n // Check if result is a tuple/array with [content, artifacts]\n if (Array.isArray(result) && result.length >= 1) {\n const [content] = result;\n\n // If first element is a string, return it (possibly parsed as JSON)\n if (typeof content === 'string') {\n return maybeParseJSON(content);\n }\n\n // Try to extract text from content blocks\n const extractedText = extractTextFromContent(content);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // If first element is an object (but not a text block), return it\n if (typeof content === 'object' && content !== null) {\n return content;\n }\n }\n\n // Handle single content block object at top level (not in tuple)\n const extractedText = extractTextFromContent(result);\n if (extractedText !== null) {\n return maybeParseJSON(extractedText);\n }\n\n // Not a formatted response, return as-is\n return result;\n}\n\ntype ToolInputSchemaKind = {\n object: boolean;\n string: boolean;\n};\n\nfunction detectSchemaKind(schema: unknown): ToolInputSchemaKind {\n const kind: ToolInputSchemaKind = { object: false, string: false };\n\n if (!schema || typeof schema !== 'object') {\n return kind;\n }\n\n const jsonSchemaType = (schema as { type?: unknown }).type;\n if (jsonSchemaType === 'object') {\n kind.object = true;\n } else if (jsonSchemaType === 'string') {\n kind.string = true;\n } else if (Array.isArray(jsonSchemaType)) {\n kind.object = jsonSchemaType.includes('object');\n kind.string = jsonSchemaType.includes('string');\n }\n\n const zodDef = (schema as { _def?: unknown })._def;\n if (!zodDef || typeof zodDef !== 'object') {\n return kind;\n }\n\n const zodType = (zodDef as { type?: unknown; typeName?: unknown }).type;\n const zodTypeName = (zodDef as { type?: unknown; typeName?: unknown })\n .typeName;\n\n if (zodType === 'object' || zodTypeName === 'ZodObject') {\n kind.object = true;\n } else if (zodType === 'string' || zodTypeName === 'ZodString') {\n kind.string = true;\n }\n\n const innerSchema =\n (\n zodDef as {\n innerType?: unknown;\n schema?: unknown;\n type?: unknown;\n }\n ).innerType ?? (zodDef as { schema?: unknown }).schema;\n if (innerSchema) {\n const innerKind = detectSchemaKind(innerSchema);\n kind.object ||= innerKind.object;\n kind.string ||= innerKind.string;\n }\n\n const options = (zodDef as { options?: unknown }).options;\n if (Array.isArray(options)) {\n for (const option of options) {\n const optionKind = detectSchemaKind(option);\n kind.object ||= optionKind.object;\n kind.string ||= optionKind.string;\n }\n }\n\n return kind;\n}\n\nfunction getToolInputSchemaKind(tool: t.GenericTool): ToolInputSchemaKind {\n if (tool.constructor.name === 'DynamicTool') {\n return { object: false, string: true };\n }\n\n const schema = (tool as { schema?: unknown }).schema;\n return detectSchemaKind(schema);\n}\n\nfunction normalizeToolInput(\n input: t.PTCToolCall['input'],\n tool: t.GenericTool\n): t.PTCToolCall['input'] {\n const schemaKind = getToolInputSchemaKind(tool);\n\n if (typeof input !== 'string') {\n if (!schemaKind.string || schemaKind.object) {\n return input;\n }\n\n const inputValue = (input as { input?: unknown }).input;\n if (typeof inputValue === 'string') {\n return input;\n }\n\n return JSON.stringify(input);\n }\n\n if (!schemaKind.object || schemaKind.string) {\n return input;\n }\n\n const trimmed = input.trim();\n if (!trimmed.startsWith('{')) {\n return input;\n }\n\n try {\n const parsed: unknown = JSON.parse(trimmed);\n if (\n typeof parsed === 'object' &&\n parsed !== null &&\n !Array.isArray(parsed)\n ) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n return input;\n }\n\n return input;\n}\n\n/**\n * Executes tools in parallel when requested by the API.\n * Uses Promise.all for parallel execution, catching individual errors.\n * Unwraps formatted responses (e.g., MCP tool tuples) to raw data.\n * @param toolCalls - Array of tool calls from the API\n * @param toolMap - Map of tool names to executable tools\n * @returns Array of tool results\n */\nexport async function executeTools(\n toolCalls: t.PTCToolCall[],\n toolMap: t.ToolMap,\n programmaticToolName = Constants.PROGRAMMATIC_TOOL_CALLING\n): Promise<t.PTCToolResult[]> {\n const executions = toolCalls.map(async (call): Promise<t.PTCToolResult> => {\n const tool = toolMap.get(call.name);\n\n if (!tool) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: `Tool '${call.name}' not found. Available tools: ${Array.from(toolMap.keys()).join(', ')}`,\n };\n }\n\n try {\n const result = await tool.invoke(normalizeToolInput(call.input, tool), {\n metadata: { [programmaticToolName]: true },\n });\n\n const isMCPTool = tool.mcp === true;\n const unwrappedResult = unwrapToolResponse(result, isMCPTool);\n\n return {\n call_id: call.id,\n result: unwrappedResult,\n is_error: false,\n };\n } catch (error) {\n return {\n call_id: call.id,\n result: null,\n is_error: true,\n error_message: (error as Error).message || 'Tool execution failed',\n };\n }\n });\n\n return await Promise.all(executions);\n}\n\n/**\n * Formats the completed response for the agent.\n *\n * Output includes stdout/stderr plus a compact session-file summary\n * when artifacts were persisted. The artifact still carries every\n * file so the host's session map stays in sync.\n *\n * @param response - The completed API response\n * @returns Tuple of [formatted string, artifact]\n */\nexport function formatCompletedResponse(\n response: t.ProgrammaticExecutionResponse,\n sourceCode = ''\n): [string, t.ProgrammaticExecutionArtifact] {\n let formatted = '';\n\n if (response.stdout != null && response.stdout !== '') {\n formatted += `stdout:\\n${response.stdout}\\n`;\n } else {\n formatted += emptyOutputMessage;\n }\n\n if (response.stderr != null && response.stderr !== '') {\n formatted += `stderr:\\n${response.stderr}\\n`;\n }\n\n const outputWithReminder = appendTmpScratchReminder(formatted, sourceCode);\n\n return [\n appendCodeSessionFileSummary(outputWithReminder, response.files),\n {\n session_id: response.session_id,\n files: response.files,\n } satisfies t.ProgrammaticExecutionArtifact,\n ];\n}\n\n// ============================================================================\n// Tool Factory\n// ============================================================================\n\n/**\n * Creates a Programmatic Tool Calling tool for complex multi-tool workflows.\n *\n * This tool enables AI agents to write Python code that orchestrates multiple\n * tool calls programmatically, reducing LLM round-trips and token usage.\n *\n * The tool map must be provided at runtime via config.configurable.toolMap.\n *\n * @param params - Configuration parameters (baseUrl, maxRoundTrips, proxy)\n * @returns A LangChain DynamicStructuredTool for programmatic tool calling\n *\n * @example\n * const ptcTool = createProgrammaticToolCallingTool({ maxRoundTrips: 20 });\n *\n * const [output, artifact] = await ptcTool.invoke(\n * { code, tools },\n * { configurable: { toolMap } }\n * );\n */\nexport function createProgrammaticToolCallingTool(\n initParams: t.ProgrammaticToolCallingParams = {}\n): DynamicStructuredTool {\n const baseUrl = initParams.baseUrl ?? getCodeBaseURL();\n const maxRoundTrips = initParams.maxRoundTrips ?? DEFAULT_MAX_ROUND_TRIPS;\n const maxRunTimeoutMs = resolveCodeApiRunTimeoutMs(initParams.runTimeoutMs);\n const proxy = initParams.proxy ?? process.env.PROXY;\n const debug = initParams.debug ?? process.env.PTC_DEBUG === 'true';\n const EXEC_ENDPOINT = `${baseUrl}/exec/programmatic`;\n\n return tool(\n async (rawParams, config) => {\n const params = rawParams as { code: string; timeout?: number };\n const { code } = params;\n const timeout = clampCodeApiRunTimeoutMs(params.timeout, maxRunTimeoutMs);\n\n // Extra params injected by ToolNode (follows web_search pattern).\n const toolCall = (config.toolCall ?? {}) as ToolCall &\n Partial<t.ProgrammaticCache> & {\n session_id?: string;\n _injected_files?: t.CodeEnvFile[];\n };\n const { toolMap, toolDefs, session_id, _injected_files } = toolCall;\n\n if (toolMap == null || toolMap.size === 0) {\n throw new Error(\n 'No toolMap provided. ' +\n 'ToolNode should inject this from AgentContext when invoked through the graph.'\n );\n }\n\n if (toolDefs == null || toolDefs.length === 0) {\n throw new Error(\n 'No tool definitions provided. ' +\n 'Either pass tools in the input or ensure ToolNode injects toolDefs.'\n );\n }\n\n let roundTrip = 0;\n\n try {\n // ====================================================================\n // Phase 1: Filter tools and make initial request\n // ====================================================================\n\n const effectiveTools = filterToolsByUsage(toolDefs, code, debug);\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Sending ${effectiveTools.length} tools to API ` +\n `(filtered from ${toolDefs.length})`\n );\n }\n\n /**\n * File injection: `_injected_files` from ToolNode session\n * context. The legacy `/files/<session_id>` HTTP fallback was\n * removed (see `CodeExecutor.ts`) — codeapi's sessionAuth now\n * requires kind/id query params unavailable at this point.\n */\n let files: t.CodeEnvFile[] | undefined;\n if (_injected_files && _injected_files.length > 0) {\n files = _injected_files;\n } else if (session_id != null && session_id.length > 0) {\n // eslint-disable-next-line no-console\n console.debug(\n `[ProgrammaticToolCalling] No injected files for session_id=${session_id} — exec will run without input files`\n );\n }\n\n let response = await makeRequest(\n EXEC_ENDPOINT,\n {\n code,\n tools: effectiveTools,\n session_id,\n timeout,\n ...(files && files.length > 0 ? { files } : {}),\n },\n proxy,\n initParams.authHeaders\n );\n\n // ====================================================================\n // Phase 2: Handle response loop\n // ====================================================================\n\n while (response.status === 'tool_call_required') {\n roundTrip++;\n\n if (roundTrip > maxRoundTrips) {\n throw new Error(\n `Exceeded maximum round trips (${maxRoundTrips}). ` +\n 'This may indicate an infinite loop, excessive tool calls, ' +\n 'or a logic error in your code.'\n );\n }\n\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[PTC Debug] Round trip ${roundTrip}: ${response.tool_calls?.length ?? 0} tool(s) to execute`\n );\n }\n\n const toolResults = await executeTools(\n response.tool_calls ?? [],\n toolMap\n );\n\n response = await makeRequest(\n EXEC_ENDPOINT,\n {\n continuation_token: response.continuation_token,\n tool_results: toolResults,\n },\n proxy,\n initParams.authHeaders\n );\n }\n\n // ====================================================================\n // Phase 3: Handle final state\n // ====================================================================\n\n if (response.status === 'completed') {\n return formatCompletedResponse(response, code);\n }\n\n if (response.status === 'error') {\n throw new Error(\n `Execution error: ${response.error}` +\n (response.stderr != null && response.stderr !== ''\n ? `\\n\\nStderr:\\n${response.stderr}`\n : '')\n );\n }\n\n throw new Error(`Unexpected response status: ${response.status}`);\n } catch (error) {\n const messageWithReminder = appendFailedExecutionFileReminder(\n (error as Error).message,\n code\n );\n throw new Error(\n `Programmatic execution failed: ${messageWithReminder}`\n );\n }\n },\n {\n name: Constants.PROGRAMMATIC_TOOL_CALLING,\n description: ProgrammaticToolCallingDescription,\n schema: createProgrammaticToolCallingSchema(maxRunTimeoutMs),\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n"],"names":[],"mappings":"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"}
@@ -2,6 +2,7 @@ import { EnvVar } from '../common/enum.mjs';
2
2
 
3
3
  const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;
4
4
  const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;
5
+ const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300_000;
5
6
  function normalizeTimeoutMs(value) {
6
7
  if (value == null || !Number.isFinite(value)) {
7
8
  return undefined;
@@ -34,17 +35,21 @@ function clampCodeApiRunTimeoutMs(timeoutMs, maxRunTimeoutMs = resolveCodeApiRun
34
35
  }
35
36
  function createCodeApiRunTimeoutSchema(maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()) {
36
37
  const normalizedMaxRunTimeoutMs = normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;
38
+ const normalizedSchemaMaxRunTimeoutMs = Math.max(normalizedMaxRunTimeoutMs, MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS);
37
39
  const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);
40
+ const formattedSchemaMaxTimeout = formatTimeout(normalizedSchemaMaxRunTimeoutMs);
38
41
  return {
39
42
  type: 'integer',
40
43
  minimum: MIN_CODE_API_RUN_TIMEOUT_MS,
41
- maximum: normalizedMaxRunTimeoutMs,
44
+ maximum: normalizedSchemaMaxRunTimeoutMs,
42
45
  default: normalizedMaxRunTimeoutMs,
43
46
  description: 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +
44
47
  'This is not the total multi-round-trip task budget. ' +
45
- `Default: ${formattedTimeout}. Max: ${formattedTimeout}.`,
48
+ `Default: ${formattedTimeout}. ` +
49
+ 'Accepted values above the configured cap are clamped before execution. ' +
50
+ `Schema max: ${formattedSchemaMaxTimeout}. Configured cap: ${formattedTimeout}.`,
46
51
  };
47
52
  }
48
53
 
49
- export { DEFAULT_CODE_API_RUN_TIMEOUT_MS, MIN_CODE_API_RUN_TIMEOUT_MS, clampCodeApiRunTimeoutMs, createCodeApiRunTimeoutSchema, resolveCodeApiRunTimeoutMs };
54
+ export { DEFAULT_CODE_API_RUN_TIMEOUT_MS, MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS, MIN_CODE_API_RUN_TIMEOUT_MS, clampCodeApiRunTimeoutMs, createCodeApiRunTimeoutSchema, resolveCodeApiRunTimeoutMs };
50
55
  //# sourceMappingURL=ptcTimeout.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ptcTimeout.mjs","sources":["../../../src/tools/ptcTimeout.ts"],"sourcesContent":["import { EnvVar } from '@/common';\n\nexport const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;\nexport const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;\n\ntype TimeoutSchema = {\n type: 'integer';\n minimum: number;\n maximum: number;\n default: number;\n description: string;\n};\n\nexport type ProgrammaticToolCallingJsonSchema = {\n type: 'object';\n properties: {\n code: {\n type: 'string';\n minLength: number;\n description: string;\n };\n timeout: TimeoutSchema;\n };\n required: readonly ['code'];\n};\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value == null || !Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(MIN_CODE_API_RUN_TIMEOUT_MS, Math.floor(value));\n}\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (value == null || value.trim() === '') {\n return undefined;\n }\n\n return normalizeTimeoutMs(Number(value));\n}\n\nfunction formatTimeout(timeoutMs: number): string {\n return timeoutMs % 1000 === 0\n ? `${timeoutMs / 1000} seconds`\n : `${timeoutMs} milliseconds`;\n}\n\nexport function resolveCodeApiRunTimeoutMs(override?: number): number {\n return (\n normalizeTimeoutMs(override) ??\n parseTimeoutMs(process.env[EnvVar.CODE_API_RUN_TIMEOUT_MS]) ??\n DEFAULT_CODE_API_RUN_TIMEOUT_MS\n );\n}\n\nexport function clampCodeApiRunTimeoutMs(\n timeoutMs: number | undefined,\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): number {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedTimeoutMs = normalizeTimeoutMs(timeoutMs);\n\n if (normalizedTimeoutMs == null) {\n return normalizedMaxRunTimeoutMs;\n }\n\n return Math.min(normalizedTimeoutMs, normalizedMaxRunTimeoutMs);\n}\n\nexport function createCodeApiRunTimeoutSchema(\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): TimeoutSchema {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);\n\n return {\n type: 'integer',\n minimum: MIN_CODE_API_RUN_TIMEOUT_MS,\n maximum: normalizedMaxRunTimeoutMs,\n default: normalizedMaxRunTimeoutMs,\n description:\n 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +\n 'This is not the total multi-round-trip task budget. ' +\n `Default: ${formattedTimeout}. Max: ${formattedTimeout}.`,\n };\n}\n"],"names":[],"mappings":";;AAEO,MAAM,+BAA+B,GAAG;AACxC,MAAM,2BAA2B,GAAG;AAuB3C,SAAS,kBAAkB,CAAC,KAAyB,EAAA;AACnD,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC5C,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,cAAc,CAAC,KAAyB,EAAA;IAC/C,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACxC,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1C;AAEA,SAAS,aAAa,CAAC,SAAiB,EAAA;AACtC,IAAA,OAAO,SAAS,GAAG,IAAI,KAAK;AAC1B,UAAE,CAAA,EAAG,SAAS,GAAG,IAAI,CAAA,QAAA;AACrB,UAAE,CAAA,EAAG,SAAS,CAAA,aAAA,CAAe;AACjC;AAEM,SAAU,0BAA0B,CAAC,QAAiB,EAAA;AAC1D,IAAA,QACE,kBAAkB,CAAC,QAAQ,CAAC;QAC5B,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3D,QAAA,+BAA+B;AAEnC;AAEM,SAAU,wBAAwB,CACtC,SAA6B,EAC7B,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,SAAS,CAAC;AAEzD,IAAA,IAAI,mBAAmB,IAAI,IAAI,EAAE;AAC/B,QAAA,OAAO,yBAAyB;IAClC;IAEA,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AACjE;SAEgB,6BAA6B,CAC3C,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,gBAAgB,GAAG,aAAa,CAAC,yBAAyB,CAAC;IAEjE,OAAO;AACL,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,2BAA2B;AACpC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,WAAW,EACT,mFAAmF;YACnF,sDAAsD;YACtD,CAAA,SAAA,EAAY,gBAAgB,CAAA,OAAA,EAAU,gBAAgB,CAAA,CAAA,CAAG;KAC5D;AACH;;;;"}
1
+ {"version":3,"file":"ptcTimeout.mjs","sources":["../../../src/tools/ptcTimeout.ts"],"sourcesContent":["import { EnvVar } from '@/common';\n\nexport const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;\nexport const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;\nexport const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300_000;\n\ntype TimeoutSchema = {\n type: 'integer';\n minimum: number;\n maximum: number;\n default: number;\n description: string;\n};\n\nexport type ProgrammaticToolCallingJsonSchema = {\n type: 'object';\n properties: {\n code: {\n type: 'string';\n minLength: number;\n description: string;\n };\n timeout: TimeoutSchema;\n };\n required: readonly ['code'];\n};\n\nfunction normalizeTimeoutMs(value: number | undefined): number | undefined {\n if (value == null || !Number.isFinite(value)) {\n return undefined;\n }\n\n return Math.max(MIN_CODE_API_RUN_TIMEOUT_MS, Math.floor(value));\n}\n\nfunction parseTimeoutMs(value: string | undefined): number | undefined {\n if (value == null || value.trim() === '') {\n return undefined;\n }\n\n return normalizeTimeoutMs(Number(value));\n}\n\nfunction formatTimeout(timeoutMs: number): string {\n return timeoutMs % 1000 === 0\n ? `${timeoutMs / 1000} seconds`\n : `${timeoutMs} milliseconds`;\n}\n\nexport function resolveCodeApiRunTimeoutMs(override?: number): number {\n return (\n normalizeTimeoutMs(override) ??\n parseTimeoutMs(process.env[EnvVar.CODE_API_RUN_TIMEOUT_MS]) ??\n DEFAULT_CODE_API_RUN_TIMEOUT_MS\n );\n}\n\nexport function clampCodeApiRunTimeoutMs(\n timeoutMs: number | undefined,\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): number {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedTimeoutMs = normalizeTimeoutMs(timeoutMs);\n\n if (normalizedTimeoutMs == null) {\n return normalizedMaxRunTimeoutMs;\n }\n\n return Math.min(normalizedTimeoutMs, normalizedMaxRunTimeoutMs);\n}\n\nexport function createCodeApiRunTimeoutSchema(\n maxRunTimeoutMs = resolveCodeApiRunTimeoutMs()\n): TimeoutSchema {\n const normalizedMaxRunTimeoutMs =\n normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;\n const normalizedSchemaMaxRunTimeoutMs = Math.max(\n normalizedMaxRunTimeoutMs,\n MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS\n );\n const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);\n const formattedSchemaMaxTimeout = formatTimeout(\n normalizedSchemaMaxRunTimeoutMs\n );\n\n return {\n type: 'integer',\n minimum: MIN_CODE_API_RUN_TIMEOUT_MS,\n maximum: normalizedSchemaMaxRunTimeoutMs,\n default: normalizedMaxRunTimeoutMs,\n description:\n 'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +\n 'This is not the total multi-round-trip task budget. ' +\n `Default: ${formattedTimeout}. ` +\n 'Accepted values above the configured cap are clamped before execution. ' +\n `Schema max: ${formattedSchemaMaxTimeout}. Configured cap: ${formattedTimeout}.`,\n };\n}\n"],"names":[],"mappings":";;AAEO,MAAM,+BAA+B,GAAG;AACxC,MAAM,2BAA2B,GAAG;AACpC,MAAM,kCAAkC,GAAG;AAuBlD,SAAS,kBAAkB,CAAC,KAAyB,EAAA;AACnD,IAAA,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE;AAC5C,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,IAAI,CAAC,GAAG,CAAC,2BAA2B,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACjE;AAEA,SAAS,cAAc,CAAC,KAAyB,EAAA;IAC/C,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;AACxC,QAAA,OAAO,SAAS;IAClB;AAEA,IAAA,OAAO,kBAAkB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAC1C;AAEA,SAAS,aAAa,CAAC,SAAiB,EAAA;AACtC,IAAA,OAAO,SAAS,GAAG,IAAI,KAAK;AAC1B,UAAE,CAAA,EAAG,SAAS,GAAG,IAAI,CAAA,QAAA;AACrB,UAAE,CAAA,EAAG,SAAS,CAAA,aAAA,CAAe;AACjC;AAEM,SAAU,0BAA0B,CAAC,QAAiB,EAAA;AAC1D,IAAA,QACE,kBAAkB,CAAC,QAAQ,CAAC;QAC5B,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,uBAAuB,CAAC,CAAC;AAC3D,QAAA,+BAA+B;AAEnC;AAEM,SAAU,wBAAwB,CACtC,SAA6B,EAC7B,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;AACxE,IAAA,MAAM,mBAAmB,GAAG,kBAAkB,CAAC,SAAS,CAAC;AAEzD,IAAA,IAAI,mBAAmB,IAAI,IAAI,EAAE;AAC/B,QAAA,OAAO,yBAAyB;IAClC;IAEA,OAAO,IAAI,CAAC,GAAG,CAAC,mBAAmB,EAAE,yBAAyB,CAAC;AACjE;SAEgB,6BAA6B,CAC3C,eAAe,GAAG,0BAA0B,EAAE,EAAA;IAE9C,MAAM,yBAAyB,GAC7B,kBAAkB,CAAC,eAAe,CAAC,IAAI,+BAA+B;IACxE,MAAM,+BAA+B,GAAG,IAAI,CAAC,GAAG,CAC9C,yBAAyB,EACzB,kCAAkC,CACnC;AACD,IAAA,MAAM,gBAAgB,GAAG,aAAa,CAAC,yBAAyB,CAAC;AACjE,IAAA,MAAM,yBAAyB,GAAG,aAAa,CAC7C,+BAA+B,CAChC;IAED,OAAO;AACL,QAAA,IAAI,EAAE,SAAS;AACf,QAAA,OAAO,EAAE,2BAA2B;AACpC,QAAA,OAAO,EAAE,+BAA+B;AACxC,QAAA,OAAO,EAAE,yBAAyB;AAClC,QAAA,WAAW,EACT,mFAAmF;YACnF,sDAAsD;AACtD,YAAA,CAAA,SAAA,EAAY,gBAAgB,CAAA,EAAA,CAAI;YAChC,yEAAyE;YACzE,CAAA,YAAA,EAAe,yBAAyB,CAAA,kBAAA,EAAqB,gBAAgB,CAAA,CAAA,CAAG;KACnF;AACH;;;;"}
@@ -1,5 +1,6 @@
1
1
  export declare const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15000;
2
2
  export declare const MIN_CODE_API_RUN_TIMEOUT_MS = 1000;
3
+ export declare const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300000;
3
4
  type TimeoutSchema = {
4
5
  type: 'integer';
5
6
  minimum: number;
@@ -938,8 +938,8 @@ export type PTCToolCall = {
938
938
  id: string;
939
939
  /** Tool name */
940
940
  name: string;
941
- /** Input parameters */
942
- input: Record<string, any>;
941
+ /** Input parameters. Some bridges may serialize object input as JSON text. */
942
+ input: Record<string, any> | string;
943
943
  };
944
944
  /**
945
945
  * Tool result sent back to the Code API
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.1.93",
3
+ "version": "3.1.95",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -630,6 +630,122 @@ export function unwrapToolResponse(
630
630
  return result;
631
631
  }
632
632
 
633
+ type ToolInputSchemaKind = {
634
+ object: boolean;
635
+ string: boolean;
636
+ };
637
+
638
+ function detectSchemaKind(schema: unknown): ToolInputSchemaKind {
639
+ const kind: ToolInputSchemaKind = { object: false, string: false };
640
+
641
+ if (!schema || typeof schema !== 'object') {
642
+ return kind;
643
+ }
644
+
645
+ const jsonSchemaType = (schema as { type?: unknown }).type;
646
+ if (jsonSchemaType === 'object') {
647
+ kind.object = true;
648
+ } else if (jsonSchemaType === 'string') {
649
+ kind.string = true;
650
+ } else if (Array.isArray(jsonSchemaType)) {
651
+ kind.object = jsonSchemaType.includes('object');
652
+ kind.string = jsonSchemaType.includes('string');
653
+ }
654
+
655
+ const zodDef = (schema as { _def?: unknown })._def;
656
+ if (!zodDef || typeof zodDef !== 'object') {
657
+ return kind;
658
+ }
659
+
660
+ const zodType = (zodDef as { type?: unknown; typeName?: unknown }).type;
661
+ const zodTypeName = (zodDef as { type?: unknown; typeName?: unknown })
662
+ .typeName;
663
+
664
+ if (zodType === 'object' || zodTypeName === 'ZodObject') {
665
+ kind.object = true;
666
+ } else if (zodType === 'string' || zodTypeName === 'ZodString') {
667
+ kind.string = true;
668
+ }
669
+
670
+ const innerSchema =
671
+ (
672
+ zodDef as {
673
+ innerType?: unknown;
674
+ schema?: unknown;
675
+ type?: unknown;
676
+ }
677
+ ).innerType ?? (zodDef as { schema?: unknown }).schema;
678
+ if (innerSchema) {
679
+ const innerKind = detectSchemaKind(innerSchema);
680
+ kind.object ||= innerKind.object;
681
+ kind.string ||= innerKind.string;
682
+ }
683
+
684
+ const options = (zodDef as { options?: unknown }).options;
685
+ if (Array.isArray(options)) {
686
+ for (const option of options) {
687
+ const optionKind = detectSchemaKind(option);
688
+ kind.object ||= optionKind.object;
689
+ kind.string ||= optionKind.string;
690
+ }
691
+ }
692
+
693
+ return kind;
694
+ }
695
+
696
+ function getToolInputSchemaKind(tool: t.GenericTool): ToolInputSchemaKind {
697
+ if (tool.constructor.name === 'DynamicTool') {
698
+ return { object: false, string: true };
699
+ }
700
+
701
+ const schema = (tool as { schema?: unknown }).schema;
702
+ return detectSchemaKind(schema);
703
+ }
704
+
705
+ function normalizeToolInput(
706
+ input: t.PTCToolCall['input'],
707
+ tool: t.GenericTool
708
+ ): t.PTCToolCall['input'] {
709
+ const schemaKind = getToolInputSchemaKind(tool);
710
+
711
+ if (typeof input !== 'string') {
712
+ if (!schemaKind.string || schemaKind.object) {
713
+ return input;
714
+ }
715
+
716
+ const inputValue = (input as { input?: unknown }).input;
717
+ if (typeof inputValue === 'string') {
718
+ return input;
719
+ }
720
+
721
+ return JSON.stringify(input);
722
+ }
723
+
724
+ if (!schemaKind.object || schemaKind.string) {
725
+ return input;
726
+ }
727
+
728
+ const trimmed = input.trim();
729
+ if (!trimmed.startsWith('{')) {
730
+ return input;
731
+ }
732
+
733
+ try {
734
+ const parsed: unknown = JSON.parse(trimmed);
735
+ if (
736
+ typeof parsed === 'object' &&
737
+ parsed !== null &&
738
+ !Array.isArray(parsed)
739
+ ) {
740
+ return parsed as Record<string, unknown>;
741
+ }
742
+ } catch {
743
+ return input;
744
+ }
745
+
746
+ return input;
747
+ }
748
+
633
749
  /**
634
750
  * Executes tools in parallel when requested by the API.
635
751
  * Uses Promise.all for parallel execution, catching individual errors.
@@ -656,7 +772,7 @@ export async function executeTools(
656
772
  }
657
773
 
658
774
  try {
659
- const result = await tool.invoke(call.input, {
775
+ const result = await tool.invoke(normalizeToolInput(call.input, tool), {
660
776
  metadata: { [programmaticToolName]: true },
661
777
  });
662
778
 
@@ -16,6 +16,7 @@ import { createBashProgrammaticToolCallingTool } from '../BashProgrammaticToolCa
16
16
  import {
17
17
  clampCodeApiRunTimeoutMs,
18
18
  createCodeApiRunTimeoutSchema,
19
+ MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS,
19
20
  } from '../ptcTimeout';
20
21
  import {
21
22
  createLocalProgrammaticToolCallingTool,
@@ -267,6 +268,26 @@ describe('CodeAPI auth header injection', () => {
267
268
  expect(requestBodyAt(0).timeout).toBe(15000);
268
269
  });
269
270
 
271
+ it('accepts larger programmatic timeout inputs and clamps before execution', async () => {
272
+ const tool = createProgrammaticToolCallingTool({
273
+ runTimeoutMs: 15000,
274
+ });
275
+
276
+ await tool.invoke(
277
+ { code: 'result = await lookup_user()\nprint(result)', timeout: 30000 },
278
+ {
279
+ toolCall: {
280
+ name: 'programmatic_code_execution',
281
+ args: {},
282
+ toolMap: toolMap(),
283
+ toolDefs,
284
+ },
285
+ }
286
+ );
287
+
288
+ expect(requestBodyAt(0).timeout).toBe(15000);
289
+ });
290
+
270
291
  it('defaults bash programmatic timeout to the configured CodeAPI run cap', async () => {
271
292
  const tool = createBashProgrammaticToolCallingTool({
272
293
  runTimeoutMs: 15000,
@@ -287,14 +308,36 @@ describe('CodeAPI auth header injection', () => {
287
308
  expect(requestBodyAt(0).timeout).toBe(15000);
288
309
  });
289
310
 
311
+ it('accepts larger bash programmatic timeout inputs and clamps before execution', async () => {
312
+ const tool = createBashProgrammaticToolCallingTool({
313
+ runTimeoutMs: 15000,
314
+ });
315
+
316
+ await tool.invoke(
317
+ { code: 'lookup_user "{}"', timeout: 30000 },
318
+ {
319
+ toolCall: {
320
+ name: 'bash_programmatic_code_execution',
321
+ args: {},
322
+ toolMap: toolMap(),
323
+ toolDefs,
324
+ },
325
+ }
326
+ );
327
+
328
+ expect(requestBodyAt(0).timeout).toBe(15000);
329
+ });
330
+
290
331
  it('describes the PTC timeout as a single sandbox run cap', () => {
291
332
  const schema = createCodeApiRunTimeoutSchema(15000);
292
333
 
293
334
  expect(clampCodeApiRunTimeoutMs(60000, 15000)).toBe(15000);
294
335
  expect(schema.default).toBe(15000);
295
- expect(schema.maximum).toBe(15000);
336
+ expect(schema.maximum).toBe(MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS);
296
337
  expect(schema.description).toContain('one sandbox run');
297
338
  expect(schema.description).toContain('not the total multi-round-trip');
339
+ expect(schema.description).toContain('clamped before execution');
340
+ expect(schema.description).toContain('Configured cap: 15 seconds');
298
341
  });
299
342
 
300
343
  it('keeps local programmatic timeout schemas aligned with local execution defaults', () => {
@@ -86,6 +86,211 @@ describe('ProgrammaticToolCalling', () => {
86
86
  });
87
87
  });
88
88
 
89
+ it('parses JSON-string inputs before invoking structured tools', async () => {
90
+ const toolCalls: t.PTCToolCall[] = [
91
+ {
92
+ id: 'call_001',
93
+ name: 'get_weather',
94
+ input: '{"city":"San Francisco"}',
95
+ },
96
+ ];
97
+
98
+ const results = await executeTools(toolCalls, toolMap);
99
+
100
+ expect(results).toHaveLength(1);
101
+ expect(results[0].call_id).toBe('call_001');
102
+ expect(results[0].is_error).toBe(false);
103
+ expect(results[0].result).toEqual({
104
+ temperature: 65,
105
+ condition: 'Foggy',
106
+ });
107
+ });
108
+
109
+ it('parses ClickHouse-style JSON strings with SQL punctuation for object-schema tools', async () => {
110
+ const invoke = jest.fn<
111
+ (_input: unknown, _config: unknown) => Promise<unknown>
112
+ >(async (input) => input);
113
+ const customTool = {
114
+ name: 'run_select_query_mcp_ClickHouse',
115
+ schema: {
116
+ type: 'object',
117
+ properties: {
118
+ serviceId: { type: 'string' },
119
+ query: { type: 'string' },
120
+ },
121
+ required: ['serviceId', 'query'],
122
+ },
123
+ invoke,
124
+ } as unknown as t.GenericTool;
125
+ const customToolMap: t.ToolMap = new Map([
126
+ ['run_select_query_mcp_ClickHouse', customTool],
127
+ ]);
128
+ const input = {
129
+ serviceId: '45886e06-932b-4cff-bb49-3f7281d80717',
130
+ query:
131
+ 'SELECT name, round(avg(tempAvg)/10.0, 2) AS avg_temp_c ' +
132
+ 'FROM system.columns WHERE database=\'default\' ' +
133
+ 'AND table=\'uk_prices_3\' AND tempAvg != -9999',
134
+ };
135
+ const toolCalls: t.PTCToolCall[] = [
136
+ {
137
+ id: 'call_001',
138
+ name: 'run_select_query_mcp_ClickHouse',
139
+ input: JSON.stringify(input),
140
+ },
141
+ ];
142
+
143
+ const results = await executeTools(toolCalls, customToolMap);
144
+
145
+ expect(results[0].is_error).toBe(false);
146
+ expect(results[0].result).toEqual(input);
147
+ expect(invoke).toHaveBeenCalledWith(input, {
148
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
149
+ });
150
+ });
151
+
152
+ it('preserves JSON-looking strings for string-input tools', async () => {
153
+ const invoke = jest.fn<
154
+ (_input: unknown, _config: unknown) => Promise<unknown>
155
+ >(async (input) => input);
156
+ const customTool = {
157
+ name: 'string_tool',
158
+ schema: { type: 'string' },
159
+ invoke,
160
+ } as unknown as t.GenericTool;
161
+ const customToolMap: t.ToolMap = new Map([['string_tool', customTool]]);
162
+ const toolCalls: t.PTCToolCall[] = [
163
+ {
164
+ id: 'call_001',
165
+ name: 'string_tool',
166
+ input: '{"raw":true}',
167
+ },
168
+ ];
169
+
170
+ const results = await executeTools(toolCalls, customToolMap);
171
+
172
+ expect(results[0].is_error).toBe(false);
173
+ expect(results[0].result).toBe('{"raw":true}');
174
+ expect(invoke).toHaveBeenCalledWith('{"raw":true}', {
175
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
176
+ });
177
+ });
178
+
179
+ it('preserves ClickHouse-style JSON strings for raw string-input tools', async () => {
180
+ const invoke = jest.fn<
181
+ (_input: unknown, _config: unknown) => Promise<unknown>
182
+ >(async (input) => input);
183
+ const customTool = {
184
+ name: 'string_tool',
185
+ schema: { type: 'string' },
186
+ invoke,
187
+ } as unknown as t.GenericTool;
188
+ const customToolMap: t.ToolMap = new Map([['string_tool', customTool]]);
189
+ const input = JSON.stringify({
190
+ serviceId: '45886e06-932b-4cff-bb49-3f7281d80717',
191
+ query:
192
+ 'SELECT round(avg(tempAvg)/10.0, 2) AS avg_temp_c ' +
193
+ 'FROM default.weather_noaa_mt WHERE database=\'default\'',
194
+ });
195
+ const toolCalls: t.PTCToolCall[] = [
196
+ {
197
+ id: 'call_001',
198
+ name: 'string_tool',
199
+ input,
200
+ },
201
+ ];
202
+
203
+ const results = await executeTools(toolCalls, customToolMap);
204
+
205
+ expect(results[0].is_error).toBe(false);
206
+ expect(results[0].result).toBe(input);
207
+ expect(invoke).toHaveBeenCalledWith(input, {
208
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
209
+ });
210
+ });
211
+
212
+ it('stringifies object inputs before invoking string-input tools', async () => {
213
+ const invoke = jest.fn<
214
+ (_input: unknown, _config: unknown) => Promise<unknown>
215
+ >(async (input) => input);
216
+ const customTool = {
217
+ name: 'string_tool',
218
+ schema: { type: 'string' },
219
+ invoke,
220
+ } as unknown as t.GenericTool;
221
+ const customToolMap: t.ToolMap = new Map([['string_tool', customTool]]);
222
+ const toolCalls: t.PTCToolCall[] = [
223
+ {
224
+ id: 'call_001',
225
+ name: 'string_tool',
226
+ input: { raw: true },
227
+ },
228
+ ];
229
+
230
+ const results = await executeTools(toolCalls, customToolMap);
231
+
232
+ expect(results[0].is_error).toBe(false);
233
+ expect(results[0].result).toBe('{"raw":true}');
234
+ expect(invoke).toHaveBeenCalledWith('{"raw":true}', {
235
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
236
+ });
237
+ });
238
+
239
+ it('preserves object inputs for mixed object-or-string schemas', async () => {
240
+ const invoke = jest.fn<
241
+ (_input: unknown, _config: unknown) => Promise<unknown>
242
+ >(async (input) => input);
243
+ const customTool = {
244
+ name: 'mixed_tool',
245
+ schema: { type: ['object', 'string'] },
246
+ invoke,
247
+ } as unknown as t.GenericTool;
248
+ const customToolMap: t.ToolMap = new Map([['mixed_tool', customTool]]);
249
+ const input = { raw: true };
250
+ const toolCalls: t.PTCToolCall[] = [
251
+ {
252
+ id: 'call_001',
253
+ name: 'mixed_tool',
254
+ input,
255
+ },
256
+ ];
257
+
258
+ const results = await executeTools(toolCalls, customToolMap);
259
+
260
+ expect(results[0].is_error).toBe(false);
261
+ expect(results[0].result).toBe(input);
262
+ expect(invoke).toHaveBeenCalledWith(input, {
263
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
264
+ });
265
+ });
266
+
267
+ it('preserves JSON-looking strings for mixed object-or-string schemas', async () => {
268
+ const invoke = jest.fn<
269
+ (_input: unknown, _config: unknown) => Promise<unknown>
270
+ >(async (input) => input);
271
+ const customTool = {
272
+ name: 'mixed_tool',
273
+ schema: { type: ['object', 'string'] },
274
+ invoke,
275
+ } as unknown as t.GenericTool;
276
+ const customToolMap: t.ToolMap = new Map([['mixed_tool', customTool]]);
277
+ const toolCalls: t.PTCToolCall[] = [
278
+ {
279
+ id: 'call_001',
280
+ name: 'mixed_tool',
281
+ input: '{"raw":true}',
282
+ },
283
+ ];
284
+
285
+ const results = await executeTools(toolCalls, customToolMap);
286
+
287
+ expect(results[0].is_error).toBe(false);
288
+ expect(results[0].result).toBe('{"raw":true}');
289
+ expect(invoke).toHaveBeenCalledWith('{"raw":true}', {
290
+ metadata: { [Constants.PROGRAMMATIC_TOOL_CALLING]: true },
291
+ });
292
+ });
293
+
89
294
  it('marks bash PTC inner tool invocations with bash metadata', async () => {
90
295
  const invoke = jest.fn<
91
296
  (_input: unknown, _config: unknown) => Promise<{ ok: boolean }>
@@ -2,6 +2,7 @@ import { EnvVar } from '@/common';
2
2
 
3
3
  export const DEFAULT_CODE_API_RUN_TIMEOUT_MS = 15_000;
4
4
  export const MIN_CODE_API_RUN_TIMEOUT_MS = 1_000;
5
+ export const MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS = 300_000;
5
6
 
6
7
  type TimeoutSchema = {
7
8
  type: 'integer';
@@ -74,16 +75,25 @@ export function createCodeApiRunTimeoutSchema(
74
75
  ): TimeoutSchema {
75
76
  const normalizedMaxRunTimeoutMs =
76
77
  normalizeTimeoutMs(maxRunTimeoutMs) ?? DEFAULT_CODE_API_RUN_TIMEOUT_MS;
78
+ const normalizedSchemaMaxRunTimeoutMs = Math.max(
79
+ normalizedMaxRunTimeoutMs,
80
+ MAX_CODE_API_RUN_TIMEOUT_SCHEMA_MS
81
+ );
77
82
  const formattedTimeout = formatTimeout(normalizedMaxRunTimeoutMs);
83
+ const formattedSchemaMaxTimeout = formatTimeout(
84
+ normalizedSchemaMaxRunTimeoutMs
85
+ );
78
86
 
79
87
  return {
80
88
  type: 'integer',
81
89
  minimum: MIN_CODE_API_RUN_TIMEOUT_MS,
82
- maximum: normalizedMaxRunTimeoutMs,
90
+ maximum: normalizedSchemaMaxRunTimeoutMs,
83
91
  default: normalizedMaxRunTimeoutMs,
84
92
  description:
85
93
  'Maximum wall-clock time in milliseconds for one sandbox run or replay iteration. ' +
86
94
  'This is not the total multi-round-trip task budget. ' +
87
- `Default: ${formattedTimeout}. Max: ${formattedTimeout}.`,
95
+ `Default: ${formattedTimeout}. ` +
96
+ 'Accepted values above the configured cap are clamped before execution. ' +
97
+ `Schema max: ${formattedSchemaMaxTimeout}. Configured cap: ${formattedTimeout}.`,
88
98
  };
89
99
  }
@@ -1025,9 +1025,9 @@ export type PTCToolCall = {
1025
1025
  id: string;
1026
1026
  /** Tool name */
1027
1027
  name: string;
1028
- /** Input parameters */
1028
+ /** Input parameters. Some bridges may serialize object input as JSON text. */
1029
1029
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
1030
- input: Record<string, any>;
1030
+ input: Record<string, any> | string;
1031
1031
  };
1032
1032
 
1033
1033
  /**