@librechat/agents 3.1.77 → 3.1.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/dist/cjs/common/enum.cjs +54 -0
  2. package/dist/cjs/common/enum.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +155 -4
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +291 -0
  6. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -0
  7. package/dist/cjs/main.cjs +90 -0
  8. package/dist/cjs/main.cjs.map +1 -1
  9. package/dist/cjs/messages/anthropicToolCache.cjs +102 -0
  10. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -0
  11. package/dist/cjs/messages/prune.cjs +27 -0
  12. package/dist/cjs/messages/prune.cjs.map +1 -1
  13. package/dist/cjs/messages/recency.cjs +99 -0
  14. package/dist/cjs/messages/recency.cjs.map +1 -0
  15. package/dist/cjs/run.cjs +30 -0
  16. package/dist/cjs/run.cjs.map +1 -1
  17. package/dist/cjs/summarization/node.cjs +100 -6
  18. package/dist/cjs/summarization/node.cjs.map +1 -1
  19. package/dist/cjs/tools/ToolNode.cjs +635 -23
  20. package/dist/cjs/tools/ToolNode.cjs.map +1 -1
  21. package/dist/cjs/tools/local/CompileCheckTool.cjs +227 -0
  22. package/dist/cjs/tools/local/CompileCheckTool.cjs.map +1 -0
  23. package/dist/cjs/tools/local/FileCheckpointer.cjs +90 -0
  24. package/dist/cjs/tools/local/FileCheckpointer.cjs.map +1 -0
  25. package/dist/cjs/tools/local/LocalCodingTools.cjs +1098 -0
  26. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -0
  27. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +1042 -0
  28. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -0
  29. package/dist/cjs/tools/local/LocalExecutionTools.cjs +122 -0
  30. package/dist/cjs/tools/local/LocalExecutionTools.cjs.map +1 -0
  31. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs +453 -0
  32. package/dist/cjs/tools/local/LocalProgrammaticToolCalling.cjs.map +1 -0
  33. package/dist/cjs/tools/local/attachments.cjs +183 -0
  34. package/dist/cjs/tools/local/attachments.cjs.map +1 -0
  35. package/dist/cjs/tools/local/bashAst.cjs +129 -0
  36. package/dist/cjs/tools/local/bashAst.cjs.map +1 -0
  37. package/dist/cjs/tools/local/editStrategies.cjs +188 -0
  38. package/dist/cjs/tools/local/editStrategies.cjs.map +1 -0
  39. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +141 -0
  40. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -0
  41. package/dist/cjs/tools/local/syntaxCheck.cjs +182 -0
  42. package/dist/cjs/tools/local/syntaxCheck.cjs.map +1 -0
  43. package/dist/cjs/tools/local/textEncoding.cjs +30 -0
  44. package/dist/cjs/tools/local/textEncoding.cjs.map +1 -0
  45. package/dist/cjs/tools/local/workspaceFS.cjs +51 -0
  46. package/dist/cjs/tools/local/workspaceFS.cjs.map +1 -0
  47. package/dist/cjs/tools/subagent/SubagentExecutor.cjs +31 -0
  48. package/dist/cjs/tools/subagent/SubagentExecutor.cjs.map +1 -1
  49. package/dist/esm/common/enum.mjs +53 -1
  50. package/dist/esm/common/enum.mjs.map +1 -1
  51. package/dist/esm/graphs/Graph.mjs +156 -5
  52. package/dist/esm/graphs/Graph.mjs.map +1 -1
  53. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +289 -0
  54. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -0
  55. package/dist/esm/main.mjs +17 -2
  56. package/dist/esm/main.mjs.map +1 -1
  57. package/dist/esm/messages/anthropicToolCache.mjs +99 -0
  58. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -0
  59. package/dist/esm/messages/prune.mjs +26 -1
  60. package/dist/esm/messages/prune.mjs.map +1 -1
  61. package/dist/esm/messages/recency.mjs +97 -0
  62. package/dist/esm/messages/recency.mjs.map +1 -0
  63. package/dist/esm/run.mjs +30 -0
  64. package/dist/esm/run.mjs.map +1 -1
  65. package/dist/esm/summarization/node.mjs +100 -6
  66. package/dist/esm/summarization/node.mjs.map +1 -1
  67. package/dist/esm/tools/ToolNode.mjs +635 -23
  68. package/dist/esm/tools/ToolNode.mjs.map +1 -1
  69. package/dist/esm/tools/local/CompileCheckTool.mjs +223 -0
  70. package/dist/esm/tools/local/CompileCheckTool.mjs.map +1 -0
  71. package/dist/esm/tools/local/FileCheckpointer.mjs +87 -0
  72. package/dist/esm/tools/local/FileCheckpointer.mjs.map +1 -0
  73. package/dist/esm/tools/local/LocalCodingTools.mjs +1075 -0
  74. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -0
  75. package/dist/esm/tools/local/LocalExecutionEngine.mjs +1022 -0
  76. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -0
  77. package/dist/esm/tools/local/LocalExecutionTools.mjs +117 -0
  78. package/dist/esm/tools/local/LocalExecutionTools.mjs.map +1 -0
  79. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs +448 -0
  80. package/dist/esm/tools/local/LocalProgrammaticToolCalling.mjs.map +1 -0
  81. package/dist/esm/tools/local/attachments.mjs +180 -0
  82. package/dist/esm/tools/local/attachments.mjs.map +1 -0
  83. package/dist/esm/tools/local/bashAst.mjs +126 -0
  84. package/dist/esm/tools/local/bashAst.mjs.map +1 -0
  85. package/dist/esm/tools/local/editStrategies.mjs +185 -0
  86. package/dist/esm/tools/local/editStrategies.mjs.map +1 -0
  87. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +137 -0
  88. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -0
  89. package/dist/esm/tools/local/syntaxCheck.mjs +179 -0
  90. package/dist/esm/tools/local/syntaxCheck.mjs.map +1 -0
  91. package/dist/esm/tools/local/textEncoding.mjs +27 -0
  92. package/dist/esm/tools/local/textEncoding.mjs.map +1 -0
  93. package/dist/esm/tools/local/workspaceFS.mjs +49 -0
  94. package/dist/esm/tools/local/workspaceFS.mjs.map +1 -0
  95. package/dist/esm/tools/subagent/SubagentExecutor.mjs +31 -0
  96. package/dist/esm/tools/subagent/SubagentExecutor.mjs.map +1 -1
  97. package/dist/types/common/enum.d.ts +39 -1
  98. package/dist/types/graphs/Graph.d.ts +34 -0
  99. package/dist/types/hooks/createWorkspacePolicyHook.d.ts +95 -0
  100. package/dist/types/hooks/index.d.ts +2 -0
  101. package/dist/types/index.d.ts +1 -0
  102. package/dist/types/messages/anthropicToolCache.d.ts +51 -0
  103. package/dist/types/messages/index.d.ts +2 -0
  104. package/dist/types/messages/prune.d.ts +11 -0
  105. package/dist/types/messages/recency.d.ts +64 -0
  106. package/dist/types/run.d.ts +21 -0
  107. package/dist/types/tools/ToolNode.d.ts +145 -2
  108. package/dist/types/tools/local/CompileCheckTool.d.ts +31 -0
  109. package/dist/types/tools/local/FileCheckpointer.d.ts +39 -0
  110. package/dist/types/tools/local/LocalCodingTools.d.ts +57 -0
  111. package/dist/types/tools/local/LocalExecutionEngine.d.ts +149 -0
  112. package/dist/types/tools/local/LocalExecutionTools.d.ts +9 -0
  113. package/dist/types/tools/local/LocalProgrammaticToolCalling.d.ts +21 -0
  114. package/dist/types/tools/local/attachments.d.ts +84 -0
  115. package/dist/types/tools/local/bashAst.d.ts +11 -0
  116. package/dist/types/tools/local/editStrategies.d.ts +28 -0
  117. package/dist/types/tools/local/index.d.ts +12 -0
  118. package/dist/types/tools/local/resolveLocalExecutionTools.d.ts +38 -0
  119. package/dist/types/tools/local/syntaxCheck.d.ts +42 -0
  120. package/dist/types/tools/local/textEncoding.d.ts +21 -0
  121. package/dist/types/tools/local/workspaceFS.d.ts +49 -0
  122. package/dist/types/tools/subagent/SubagentExecutor.d.ts +29 -0
  123. package/dist/types/types/hitl.d.ts +56 -27
  124. package/dist/types/types/run.d.ts +8 -1
  125. package/dist/types/types/summarize.d.ts +30 -0
  126. package/dist/types/types/tools.d.ts +341 -6
  127. package/package.json +21 -2
  128. package/src/common/enum.ts +54 -0
  129. package/src/graphs/Graph.ts +173 -6
  130. package/src/hooks/__tests__/compactHooks.test.ts +38 -2
  131. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +393 -0
  132. package/src/hooks/createWorkspacePolicyHook.ts +355 -0
  133. package/src/hooks/index.ts +6 -0
  134. package/src/index.ts +1 -0
  135. package/src/messages/__tests__/anthropicToolCache.test.ts +125 -0
  136. package/src/messages/__tests__/recency.test.ts +267 -0
  137. package/src/messages/anthropicToolCache.ts +116 -0
  138. package/src/messages/index.ts +2 -0
  139. package/src/messages/prune.ts +27 -1
  140. package/src/messages/recency.ts +155 -0
  141. package/src/run.ts +31 -0
  142. package/src/scripts/compare_pi_vs_ours.ts +840 -0
  143. package/src/scripts/local_engine.ts +166 -0
  144. package/src/scripts/local_engine_checkpointer.ts +205 -0
  145. package/src/scripts/local_engine_compile.ts +263 -0
  146. package/src/scripts/local_engine_hooks.ts +226 -0
  147. package/src/scripts/local_engine_image.ts +201 -0
  148. package/src/scripts/local_engine_ptc.ts +151 -0
  149. package/src/scripts/local_engine_workspace.ts +258 -0
  150. package/src/scripts/subagent-configurable-inheritance.ts +252 -0
  151. package/src/scripts/summarization-recency.ts +462 -0
  152. package/src/specs/prune.test.ts +39 -0
  153. package/src/summarization/__tests__/node.test.ts +499 -3
  154. package/src/summarization/node.ts +124 -7
  155. package/src/tools/ToolNode.ts +769 -20
  156. package/src/tools/__tests__/LocalExecutionTools.test.ts +2647 -0
  157. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +175 -0
  158. package/src/tools/__tests__/SubagentExecutor.test.ts +148 -0
  159. package/src/tools/__tests__/ToolNode.outputReferences.test.ts +114 -0
  160. package/src/tools/__tests__/ToolNode.session.test.ts +84 -0
  161. package/src/tools/__tests__/directToolHITLResumeScope.test.ts +467 -0
  162. package/src/tools/__tests__/directToolHooks.test.ts +411 -0
  163. package/src/tools/__tests__/localToolNames.test.ts +73 -0
  164. package/src/tools/__tests__/workspaceSeam.test.ts +134 -0
  165. package/src/tools/local/CompileCheckTool.ts +278 -0
  166. package/src/tools/local/FileCheckpointer.ts +93 -0
  167. package/src/tools/local/LocalCodingTools.ts +1342 -0
  168. package/src/tools/local/LocalExecutionEngine.ts +1329 -0
  169. package/src/tools/local/LocalExecutionTools.ts +167 -0
  170. package/src/tools/local/LocalProgrammaticToolCalling.ts +594 -0
  171. package/src/tools/local/__tests__/FileCheckpointer.test.ts +120 -0
  172. package/src/tools/local/__tests__/editStrategies.test.ts +134 -0
  173. package/src/tools/local/attachments.ts +251 -0
  174. package/src/tools/local/bashAst.ts +151 -0
  175. package/src/tools/local/editStrategies.ts +188 -0
  176. package/src/tools/local/index.ts +12 -0
  177. package/src/tools/local/resolveLocalExecutionTools.ts +208 -0
  178. package/src/tools/local/syntaxCheck.ts +243 -0
  179. package/src/tools/local/textEncoding.ts +37 -0
  180. package/src/tools/local/workspaceFS.ts +89 -0
  181. package/src/tools/subagent/SubagentExecutor.ts +60 -0
  182. package/src/types/hitl.ts +56 -27
  183. package/src/types/run.ts +12 -1
  184. package/src/types/summarize.ts +31 -0
  185. package/src/types/tools.ts +359 -7
@@ -0,0 +1,453 @@
1
+ 'use strict';
2
+
3
+ var crypto = require('crypto');
4
+ var http = require('http');
5
+ var tools = require('@langchain/core/tools');
6
+ var executeHooks = require('../../hooks/executeHooks.cjs');
7
+ require('../../hooks/createWorkspacePolicyHook.cjs');
8
+ var ProgrammaticToolCalling = require('../ProgrammaticToolCalling.cjs');
9
+ var BashProgrammaticToolCalling = require('../BashProgrammaticToolCalling.cjs');
10
+ var LocalExecutionEngine = require('./LocalExecutionEngine.cjs');
11
+ var _enum = require('../../common/enum.cjs');
12
+
13
+ const DEFAULT_TIMEOUT = 60000;
14
+ const LocalProgrammaticToolCallingSchema = {
15
+ ...ProgrammaticToolCalling.ProgrammaticToolCallingSchema,
16
+ properties: {
17
+ ...ProgrammaticToolCalling.ProgrammaticToolCallingSchema.properties,
18
+ lang: {
19
+ type: 'string',
20
+ enum: ['py', 'python', 'bash', 'sh'],
21
+ default: 'bash',
22
+ description: 'Local engine runtime for orchestration code. Defaults to bash; use py/python for Python orchestration.',
23
+ },
24
+ },
25
+ };
26
+ const BRIDGE_AUTH_HEADER = 'x-librechat-bridge-token';
27
+ function constantTimeEquals(a, b) {
28
+ const aBuf = Buffer.from(a, 'utf8');
29
+ const bBuf = Buffer.from(b, 'utf8');
30
+ if (aBuf.length !== bBuf.length) {
31
+ return false;
32
+ }
33
+ return crypto.timingSafeEqual(aBuf, bBuf);
34
+ }
35
+ function resolveRuntime(params) {
36
+ const rawRuntime = params.lang ?? params.runtime ?? params.language ?? 'bash';
37
+ return rawRuntime === 'py' || rawRuntime === 'python' ? 'python' : 'bash';
38
+ }
39
+ function toSerializable(value) {
40
+ if (value === undefined) {
41
+ return null;
42
+ }
43
+ return value;
44
+ }
45
+ async function readRequestBody(req) {
46
+ const chunks = [];
47
+ for await (const chunk of req) {
48
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
49
+ }
50
+ const raw = Buffer.concat(chunks).toString('utf8');
51
+ if (raw === '') {
52
+ return {};
53
+ }
54
+ return JSON.parse(raw);
55
+ }
56
+ function writeJson(res, status, value) {
57
+ res.writeHead(status, { 'Content-Type': 'application/json' });
58
+ res.end(JSON.stringify(value));
59
+ }
60
+ /**
61
+ * Run the host's `PreToolUse` hook chain for a single bridge call.
62
+ * Returns the (possibly rewritten) input and a `denyReason` if any
63
+ * matcher returned `decision: 'deny'` or `'ask'`. `'ask'` collapses
64
+ * to deny because the bridge can't raise a LangGraph interrupt from
65
+ * inside an HTTP handler — fail-closed matches the rest of the SDK
66
+ * when HITL is unavailable.
67
+ *
68
+ * @internal Exported for tests so the deny / allow / updatedInput /
69
+ * ask branches can be exercised without standing up the full HTTP
70
+ * bridge.
71
+ */
72
+ async function applyPreToolUseHooksForBridge(hookContext, toolName, toolUseId, toolInput) {
73
+ if (hookContext.registry == null) {
74
+ return { input: toolInput };
75
+ }
76
+ const result = await executeHooks.executeHooks({
77
+ registry: hookContext.registry,
78
+ input: {
79
+ hook_event_name: 'PreToolUse',
80
+ runId: hookContext.runId,
81
+ threadId: hookContext.threadId,
82
+ agentId: hookContext.agentId,
83
+ toolName,
84
+ toolInput,
85
+ toolUseId,
86
+ stepId: '',
87
+ turn: 0,
88
+ },
89
+ sessionId: hookContext.runId,
90
+ matchQuery: toolName,
91
+ }).catch(() => undefined);
92
+ if (result == null) {
93
+ return { input: toolInput };
94
+ }
95
+ const nextInput = result.updatedInput != null
96
+ ? result.updatedInput
97
+ : toolInput;
98
+ if (result.decision === 'deny' || result.decision === 'ask') {
99
+ return {
100
+ input: nextInput,
101
+ denyReason: result.reason ??
102
+ (result.decision === 'ask'
103
+ ? `Tool "${toolName}" requires human approval; bridge cannot raise an interrupt — denying.`
104
+ : `Tool "${toolName}" denied by PreToolUse hook.`),
105
+ };
106
+ }
107
+ return { input: nextInput };
108
+ }
109
+ async function createToolBridge(toolMap, hookContext) {
110
+ const token = crypto.randomBytes(32).toString('hex');
111
+ const server = http.createServer((req, res) => {
112
+ // `?mode=text` returns the already-serialized result as the body
113
+ // (or the error message at non-2xx). Python/Node callers stay on
114
+ // JSON; bash callers using curl can avoid pulling in a JSON
115
+ // parser dependency (Codex P2 #19 — `python3` was a hard
116
+ // requirement for the bash bridge, breaking minimal containers).
117
+ const url = new URL(req.url ?? '/', 'http://127.0.0.1');
118
+ const isTextMode = url.searchParams.get('mode') === 'text';
119
+ if (req.method !== 'POST' || url.pathname !== '/tool') {
120
+ if (isTextMode) {
121
+ res.writeHead(404, { 'Content-Type': 'text/plain' });
122
+ res.end('Not found');
123
+ }
124
+ else {
125
+ writeJson(res, 404, { error: 'Not found' });
126
+ }
127
+ return;
128
+ }
129
+ const presented = req.headers[BRIDGE_AUTH_HEADER];
130
+ const presentedToken = Array.isArray(presented) ? presented[0] : presented;
131
+ if (typeof presentedToken !== 'string' ||
132
+ !constantTimeEquals(presentedToken, token)) {
133
+ if (isTextMode) {
134
+ res.writeHead(401, { 'Content-Type': 'text/plain' });
135
+ res.end('Unauthorized');
136
+ }
137
+ else {
138
+ writeJson(res, 401, { error: 'Unauthorized' });
139
+ }
140
+ return;
141
+ }
142
+ readRequestBody(req)
143
+ .then(async (body) => {
144
+ if (typeof body.name !== 'string' || body.name === '') {
145
+ const message = 'Tool request is missing a tool name.';
146
+ if (isTextMode) {
147
+ res.writeHead(400, { 'Content-Type': 'text/plain' });
148
+ res.end(message);
149
+ }
150
+ else {
151
+ writeJson(res, 400, {
152
+ call_id: body.id ?? 'invalid',
153
+ result: null,
154
+ is_error: true,
155
+ error_message: message,
156
+ });
157
+ }
158
+ return;
159
+ }
160
+ const callId = body.id ?? `local_call_${crypto.randomUUID()}`;
161
+ let effectiveInput = body.input ?? {};
162
+ if (hookContext != null) {
163
+ const gate = await applyPreToolUseHooksForBridge(hookContext, body.name, callId, effectiveInput);
164
+ if (gate.denyReason != null) {
165
+ const denyMsg = gate.denyReason;
166
+ if (isTextMode) {
167
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
168
+ res.end(denyMsg);
169
+ }
170
+ else {
171
+ writeJson(res, 500, {
172
+ call_id: callId,
173
+ result: null,
174
+ is_error: true,
175
+ error_message: denyMsg,
176
+ });
177
+ }
178
+ return;
179
+ }
180
+ effectiveInput = gate.input;
181
+ }
182
+ const [result] = await ProgrammaticToolCalling.executeTools([
183
+ {
184
+ id: callId,
185
+ name: body.name,
186
+ input: effectiveInput,
187
+ },
188
+ ], toolMap);
189
+ if (isTextMode) {
190
+ if (result.is_error === true) {
191
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
192
+ res.end(result.error_message ?? `Tool ${body.name} failed`);
193
+ }
194
+ else {
195
+ const value = toSerializable(result.result);
196
+ const text = typeof value === 'string' ? value : JSON.stringify(value);
197
+ res.writeHead(200, { 'Content-Type': 'text/plain' });
198
+ res.end(text);
199
+ }
200
+ return;
201
+ }
202
+ writeJson(res, 200, {
203
+ ...result,
204
+ result: toSerializable(result.result),
205
+ });
206
+ })
207
+ .catch((error) => {
208
+ if (isTextMode) {
209
+ res.writeHead(500, { 'Content-Type': 'text/plain' });
210
+ res.end(error.message);
211
+ }
212
+ else {
213
+ writeJson(res, 500, {
214
+ call_id: 'error',
215
+ result: null,
216
+ is_error: true,
217
+ error_message: error.message,
218
+ });
219
+ }
220
+ });
221
+ });
222
+ await new Promise((resolve, reject) => {
223
+ server.once('error', reject);
224
+ server.listen(0, '127.0.0.1', resolve);
225
+ });
226
+ const address = server.address();
227
+ return {
228
+ url: `http://127.0.0.1:${address.port}/tool`,
229
+ token,
230
+ close: () => new Promise((resolve, reject) => {
231
+ server.close((error) => (error ? reject(error) : resolve()));
232
+ }),
233
+ };
234
+ }
235
+ function indent(code) {
236
+ return code
237
+ .split('\n')
238
+ .map((line) => ` ${line}`)
239
+ .join('\n');
240
+ }
241
+ function createPythonProgram(code, toolDefs, bridgeUrl, bridgeToken) {
242
+ const functionDefs = toolDefs
243
+ .map((def) => {
244
+ const pythonName = ProgrammaticToolCalling.normalizeToPythonIdentifier(def.name);
245
+ return [
246
+ `async def ${pythonName}(**kwargs):`,
247
+ ` return await __librechat_call_tool(${JSON.stringify(def.name)}, kwargs)`,
248
+ ].join('\n');
249
+ })
250
+ .join('\n\n');
251
+ return `
252
+ import asyncio
253
+ import json
254
+ import urllib.request
255
+
256
+ __LIBRECHAT_TOOL_BRIDGE = ${JSON.stringify(bridgeUrl)}
257
+ __LIBRECHAT_TOOL_TOKEN = ${JSON.stringify(bridgeToken)}
258
+
259
+ async def __librechat_call_tool(name, payload):
260
+ body = json.dumps({"name": name, "input": payload}).encode("utf-8")
261
+ headers = {
262
+ "Content-Type": "application/json",
263
+ ${JSON.stringify(BRIDGE_AUTH_HEADER)}: __LIBRECHAT_TOOL_TOKEN,
264
+ }
265
+
266
+ def request():
267
+ req = urllib.request.Request(__LIBRECHAT_TOOL_BRIDGE, data=body, headers=headers, method="POST")
268
+ with urllib.request.urlopen(req, timeout=300) as response:
269
+ return response.read().decode("utf-8")
270
+
271
+ raw = await asyncio.to_thread(request)
272
+ result = json.loads(raw)
273
+ if result.get("is_error"):
274
+ raise RuntimeError(result.get("error_message") or f"Tool {name} failed")
275
+ return result.get("result")
276
+
277
+ ${functionDefs}
278
+
279
+ async def __librechat_main():
280
+ ${indent(code)}
281
+
282
+ asyncio.run(__librechat_main())
283
+ `.trimStart();
284
+ }
285
+ function _createBashProgramForTests(code, toolDefs, bridgeUrl, bridgeToken) {
286
+ return createBashProgram(code, toolDefs, bridgeUrl, bridgeToken);
287
+ }
288
+ function createBashProgram(code, toolDefs, bridgeUrl, bridgeToken) {
289
+ const functions = toolDefs
290
+ .map((def) => {
291
+ const bashName = BashProgrammaticToolCalling.normalizeToBashIdentifier(def.name);
292
+ return [
293
+ `${bashName}() {`,
294
+ ' local payload="${1:-}"',
295
+ ' if [ -z "$payload" ]; then payload=\'{}\'; fi',
296
+ ` __librechat_call_tool ${LocalExecutionEngine.shellQuote(def.name)} "$payload"`,
297
+ '}',
298
+ ].join('\n');
299
+ })
300
+ .join('\n\n');
301
+ return `
302
+ __LIBRECHAT_TOOL_BRIDGE=${LocalExecutionEngine.shellQuote(bridgeUrl)}
303
+ __LIBRECHAT_TOOL_HEADER=${LocalExecutionEngine.shellQuote(BRIDGE_AUTH_HEADER)}
304
+ __LIBRECHAT_TOOL_TOKEN=${LocalExecutionEngine.shellQuote(bridgeToken)}
305
+
306
+ # Bridge call helper. Tries curl first (universally available, no
307
+ # JSON parser needed thanks to the bridge's ?mode=text endpoint),
308
+ # falls back to python3 for environments without curl. Codex P2 #19
309
+ # flagged that the prior python3-only path broke minimal containers
310
+ # (and Windows hosts without a python3 binary on PATH). Tool names
311
+ # come from Constants.* and are always safe identifiers, so we can
312
+ # splice them into JSON without an escape pass.
313
+ __librechat_call_tool() {
314
+ local tool_name="$1"
315
+ local payload="$2"
316
+ if command -v curl >/dev/null 2>&1; then
317
+ local body="{\\"name\\":\\"$tool_name\\",\\"input\\":$payload}"
318
+ local response
319
+ local http_code
320
+ response=$(curl -sS -X POST \
321
+ -H "Content-Type: application/json" \
322
+ -H "$__LIBRECHAT_TOOL_HEADER: $__LIBRECHAT_TOOL_TOKEN" \
323
+ --data-binary "$body" \
324
+ -w '\\n__LIBRECHAT_HTTP_CODE_%{http_code}__' \
325
+ "$__LIBRECHAT_TOOL_BRIDGE?mode=text")
326
+ http_code=$(printf '%s' "$response" | sed -n 's/.*__LIBRECHAT_HTTP_CODE_\\([0-9][0-9]*\\)__$/\\1/p')
327
+ local body_only
328
+ body_only=$(printf '%s' "$response" | sed 's/__LIBRECHAT_HTTP_CODE_[0-9][0-9]*__$//')
329
+ if [ "$http_code" = "200" ]; then
330
+ printf '%s' "$body_only"
331
+ return 0
332
+ fi
333
+ printf '%s\\n' "$body_only" >&2
334
+ return 1
335
+ elif command -v python3 >/dev/null 2>&1; then
336
+ python3 - "$__LIBRECHAT_TOOL_BRIDGE" "$tool_name" "$payload" "$__LIBRECHAT_TOOL_HEADER" "$__LIBRECHAT_TOOL_TOKEN" <<'PY'
337
+ import json
338
+ import sys
339
+ import urllib.request
340
+
341
+ url, name, payload, header, token = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]
342
+ body = json.dumps({"name": name, "input": json.loads(payload)}).encode("utf-8")
343
+ req = urllib.request.Request(url, data=body, headers={"Content-Type": "application/json", header: token}, method="POST")
344
+ with urllib.request.urlopen(req, timeout=300) as response:
345
+ result = json.loads(response.read().decode("utf-8"))
346
+ if result.get("is_error"):
347
+ print(result.get("error_message") or f"Tool {name} failed", file=sys.stderr)
348
+ sys.exit(1)
349
+ value = result.get("result")
350
+ if isinstance(value, str):
351
+ print(value)
352
+ else:
353
+ print(json.dumps(value))
354
+ PY
355
+ else
356
+ printf 'librechat: tool bridge needs either curl or python3 on PATH\\n' >&2
357
+ return 1
358
+ fi
359
+ }
360
+
361
+ ${functions}
362
+
363
+ ${code}
364
+ `.trimStart();
365
+ }
366
+ function getProgrammaticContext(config) {
367
+ return (config?.toolCall ?? {});
368
+ }
369
+ function createEffectiveToolMap(toolMap, toolDefs, code, filterTools) {
370
+ const effectiveTools = filterTools(toolDefs, code);
371
+ const effectiveMap = new Map(effectiveTools
372
+ .map((def) => {
373
+ const executable = toolMap.get(def.name);
374
+ return executable == null
375
+ ? undefined
376
+ : [def.name, executable];
377
+ })
378
+ .filter((entry) => entry != null));
379
+ return { effectiveTools, effectiveMap };
380
+ }
381
+ async function runLocalProgrammaticTool(args) {
382
+ const { toolMap, toolDefs, hookContext } = getProgrammaticContext(args.config);
383
+ if (toolMap == null || toolMap.size === 0) {
384
+ throw new Error('No toolMap provided for local programmatic execution.');
385
+ }
386
+ if (toolDefs == null || toolDefs.length === 0) {
387
+ throw new Error('No tool definitions provided for local programmatic execution.');
388
+ }
389
+ const { effectiveTools, effectiveMap } = createEffectiveToolMap(toolMap, toolDefs, args.params.code, args.runtime === 'bash' ? BashProgrammaticToolCalling.filterBashToolsByUsage : ProgrammaticToolCalling.filterToolsByUsage);
390
+ const bridge = await createToolBridge(effectiveMap, hookContext);
391
+ try {
392
+ const timeoutMs = args.params.timeout ?? args.localConfig.timeoutMs ?? DEFAULT_TIMEOUT;
393
+ const result = args.runtime === 'bash'
394
+ ? await LocalExecutionEngine.executeLocalBash(createBashProgram(args.params.code, effectiveTools, bridge.url, bridge.token), { ...args.localConfig, timeoutMs })
395
+ : await LocalExecutionEngine.executeLocalCode({
396
+ lang: 'py',
397
+ code: createPythonProgram(args.params.code, effectiveTools, bridge.url, bridge.token),
398
+ }, { ...args.localConfig, timeoutMs });
399
+ if (result.exitCode !== 0 || result.timedOut) {
400
+ throw new Error(result.stderr !== ''
401
+ ? result.stderr
402
+ : `Local ${args.runtime} programmatic execution exited with code ${result.exitCode ?? 'unknown'}`);
403
+ }
404
+ return ProgrammaticToolCalling.formatCompletedResponse({
405
+ status: 'completed',
406
+ session_id: LocalExecutionEngine.getLocalSessionId(args.localConfig),
407
+ stdout: result.stdout,
408
+ stderr: result.stderr,
409
+ files: [],
410
+ });
411
+ }
412
+ finally {
413
+ await bridge.close();
414
+ }
415
+ }
416
+ function createLocalProgrammaticToolCallingTool(localConfig = {}) {
417
+ return tools.tool(async (rawParams, config) => {
418
+ const params = rawParams;
419
+ return runLocalProgrammaticTool({
420
+ params,
421
+ config,
422
+ localConfig,
423
+ runtime: resolveRuntime(params),
424
+ });
425
+ }, {
426
+ name: ProgrammaticToolCalling.ProgrammaticToolCallingName,
427
+ description: `${ProgrammaticToolCalling.ProgrammaticToolCallingDescription}\n\nLocal engine: runs bash by default, or Python when \`lang\` is \`py\` or \`python\`, on the host machine and calls tools through an in-process localhost bridge.`,
428
+ schema: LocalProgrammaticToolCallingSchema,
429
+ responseFormat: _enum.Constants.CONTENT_AND_ARTIFACT,
430
+ });
431
+ }
432
+ function createLocalBashProgrammaticToolCallingTool(localConfig = {}) {
433
+ return tools.tool(async (rawParams, config) => {
434
+ const params = rawParams;
435
+ return runLocalProgrammaticTool({
436
+ params,
437
+ config,
438
+ localConfig,
439
+ runtime: 'bash',
440
+ });
441
+ }, {
442
+ name: _enum.Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
443
+ description: `${BashProgrammaticToolCalling.BashProgrammaticToolCallingDescription}\n\nLocal engine: runs this bash orchestration code on the host machine and calls tools through an in-process localhost bridge.`,
444
+ schema: BashProgrammaticToolCalling.BashProgrammaticToolCallingSchema,
445
+ responseFormat: _enum.Constants.CONTENT_AND_ARTIFACT,
446
+ });
447
+ }
448
+
449
+ exports._createBashProgramForTests = _createBashProgramForTests;
450
+ exports.applyPreToolUseHooksForBridge = applyPreToolUseHooksForBridge;
451
+ exports.createLocalBashProgrammaticToolCallingTool = createLocalBashProgrammaticToolCallingTool;
452
+ exports.createLocalProgrammaticToolCallingTool = createLocalProgrammaticToolCallingTool;
453
+ //# sourceMappingURL=LocalProgrammaticToolCalling.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalProgrammaticToolCalling.cjs","sources":["../../../../src/tools/local/LocalProgrammaticToolCalling.ts"],"sourcesContent":["import { randomBytes, randomUUID, timingSafeEqual } from 'crypto';\nimport { createServer } from 'http';\nimport { tool } from '@langchain/core/tools';\nimport type { AddressInfo } from 'net';\nimport type { IncomingMessage, ServerResponse } from 'http';\nimport type { DynamicStructuredTool } from '@langchain/core/tools';\nimport type * as t from '@/types';\nimport { executeHooks } from '@/hooks';\nimport {\n executeTools,\n filterToolsByUsage,\n formatCompletedResponse,\n normalizeToPythonIdentifier,\n ProgrammaticToolCallingName,\n ProgrammaticToolCallingSchema,\n ProgrammaticToolCallingDescription,\n} from '@/tools/ProgrammaticToolCalling';\nimport {\n BashProgrammaticToolCallingSchema,\n BashProgrammaticToolCallingDescription,\n filterBashToolsByUsage,\n normalizeToBashIdentifier,\n} from '@/tools/BashProgrammaticToolCalling';\nimport {\n executeLocalBash,\n executeLocalCode,\n getLocalSessionId,\n shellQuote,\n} from './LocalExecutionEngine';\nimport { Constants } from '@/common';\n\nconst DEFAULT_TIMEOUT = 60000;\nconst LocalProgrammaticToolCallingSchema = {\n ...ProgrammaticToolCallingSchema,\n properties: {\n ...ProgrammaticToolCallingSchema.properties,\n lang: {\n type: 'string',\n enum: ['py', 'python', 'bash', 'sh'],\n default: 'bash',\n description:\n 'Local engine runtime for orchestration code. Defaults to bash; use py/python for Python orchestration.',\n },\n },\n} as const;\n\ntype ToolBridge = {\n url: string;\n token: string;\n close: () => Promise<void>;\n};\n\ntype ToolRequest = {\n id?: string;\n name?: string;\n input?: Record<string, unknown>;\n};\n\nconst BRIDGE_AUTH_HEADER = 'x-librechat-bridge-token';\n\nfunction constantTimeEquals(a: string, b: string): boolean {\n const aBuf = Buffer.from(a, 'utf8');\n const bBuf = Buffer.from(b, 'utf8');\n if (aBuf.length !== bBuf.length) {\n return false;\n }\n return timingSafeEqual(aBuf, bBuf);\n}\n\ntype LocalProgrammaticRuntime = 'python' | 'bash';\n\ntype LocalProgrammaticParams = {\n code: string;\n timeout?: number;\n lang?: string;\n runtime?: string;\n language?: string;\n};\n\ntype ToolFilter = (toolDefs: t.LCTool[], code: string) => t.LCTool[];\n\nfunction resolveRuntime(params: LocalProgrammaticParams): LocalProgrammaticRuntime {\n const rawRuntime = params.lang ?? params.runtime ?? params.language ?? 'bash';\n return rawRuntime === 'py' || rawRuntime === 'python' ? 'python' : 'bash';\n}\n\nfunction toSerializable(value: unknown): unknown {\n if (value === undefined) {\n return null;\n }\n return value;\n}\n\nasync function readRequestBody(req: IncomingMessage): Promise<ToolRequest> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString('utf8');\n if (raw === '') {\n return {};\n }\n return JSON.parse(raw) as ToolRequest;\n}\n\nfunction writeJson(res: ServerResponse, status: number, value: unknown): void {\n res.writeHead(status, { 'Content-Type': 'application/json' });\n res.end(JSON.stringify(value));\n}\n\n/**\n * Run the host's `PreToolUse` hook chain for a single bridge call.\n * Returns the (possibly rewritten) input and a `denyReason` if any\n * matcher returned `decision: 'deny'` or `'ask'`. `'ask'` collapses\n * to deny because the bridge can't raise a LangGraph interrupt from\n * inside an HTTP handler — fail-closed matches the rest of the SDK\n * when HITL is unavailable.\n *\n * @internal Exported for tests so the deny / allow / updatedInput /\n * ask branches can be exercised without standing up the full HTTP\n * bridge.\n */\nexport async function applyPreToolUseHooksForBridge(\n hookContext: t.ProgrammaticHookContext,\n toolName: string,\n toolUseId: string,\n toolInput: Record<string, unknown>\n): Promise<{ input: Record<string, unknown>; denyReason?: string }> {\n if (hookContext.registry == null) {\n return { input: toolInput };\n }\n const result = await executeHooks({\n registry: hookContext.registry,\n input: {\n hook_event_name: 'PreToolUse',\n runId: hookContext.runId,\n threadId: hookContext.threadId,\n agentId: hookContext.agentId,\n toolName,\n toolInput,\n toolUseId,\n stepId: '',\n turn: 0,\n },\n sessionId: hookContext.runId,\n matchQuery: toolName,\n }).catch(() => undefined);\n if (result == null) {\n return { input: toolInput };\n }\n const nextInput =\n result.updatedInput != null\n ? (result.updatedInput as Record<string, unknown>)\n : toolInput;\n if (result.decision === 'deny' || result.decision === 'ask') {\n return {\n input: nextInput,\n denyReason:\n result.reason ??\n (result.decision === 'ask'\n ? `Tool \"${toolName}\" requires human approval; bridge cannot raise an interrupt — denying.`\n : `Tool \"${toolName}\" denied by PreToolUse hook.`),\n };\n }\n return { input: nextInput };\n}\n\nasync function createToolBridge(\n toolMap: t.ToolMap,\n hookContext?: t.ProgrammaticHookContext\n): Promise<ToolBridge> {\n const token = randomBytes(32).toString('hex');\n const server = createServer((req, res) => {\n // `?mode=text` returns the already-serialized result as the body\n // (or the error message at non-2xx). Python/Node callers stay on\n // JSON; bash callers using curl can avoid pulling in a JSON\n // parser dependency (Codex P2 #19 — `python3` was a hard\n // requirement for the bash bridge, breaking minimal containers).\n const url = new URL(req.url ?? '/', 'http://127.0.0.1');\n const isTextMode = url.searchParams.get('mode') === 'text';\n if (req.method !== 'POST' || url.pathname !== '/tool') {\n if (isTextMode) {\n res.writeHead(404, { 'Content-Type': 'text/plain' });\n res.end('Not found');\n } else {\n writeJson(res, 404, { error: 'Not found' });\n }\n return;\n }\n\n const presented = req.headers[BRIDGE_AUTH_HEADER];\n const presentedToken = Array.isArray(presented) ? presented[0] : presented;\n if (\n typeof presentedToken !== 'string' ||\n !constantTimeEquals(presentedToken, token)\n ) {\n if (isTextMode) {\n res.writeHead(401, { 'Content-Type': 'text/plain' });\n res.end('Unauthorized');\n } else {\n writeJson(res, 401, { error: 'Unauthorized' });\n }\n return;\n }\n\n readRequestBody(req)\n .then(async (body) => {\n if (typeof body.name !== 'string' || body.name === '') {\n const message = 'Tool request is missing a tool name.';\n if (isTextMode) {\n res.writeHead(400, { 'Content-Type': 'text/plain' });\n res.end(message);\n } else {\n writeJson(res, 400, {\n call_id: body.id ?? 'invalid',\n result: null,\n is_error: true,\n error_message: message,\n });\n }\n return;\n }\n\n const callId = body.id ?? `local_call_${randomUUID()}`;\n let effectiveInput: Record<string, unknown> = body.input ?? {};\n if (hookContext != null) {\n const gate = await applyPreToolUseHooksForBridge(\n hookContext,\n body.name,\n callId,\n effectiveInput\n );\n if (gate.denyReason != null) {\n const denyMsg = gate.denyReason;\n if (isTextMode) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end(denyMsg);\n } else {\n writeJson(res, 500, {\n call_id: callId,\n result: null,\n is_error: true,\n error_message: denyMsg,\n });\n }\n return;\n }\n effectiveInput = gate.input;\n }\n\n const [result] = await executeTools(\n [\n {\n id: callId,\n name: body.name,\n input: effectiveInput,\n },\n ],\n toolMap\n );\n\n if (isTextMode) {\n if (result.is_error === true) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end(result.error_message ?? `Tool ${body.name} failed`);\n } else {\n const value = toSerializable(result.result);\n const text =\n typeof value === 'string' ? value : JSON.stringify(value);\n res.writeHead(200, { 'Content-Type': 'text/plain' });\n res.end(text);\n }\n return;\n }\n\n writeJson(res, 200, {\n ...result,\n result: toSerializable(result.result),\n });\n })\n .catch((error: Error) => {\n if (isTextMode) {\n res.writeHead(500, { 'Content-Type': 'text/plain' });\n res.end(error.message);\n } else {\n writeJson(res, 500, {\n call_id: 'error',\n result: null,\n is_error: true,\n error_message: error.message,\n });\n }\n });\n });\n\n await new Promise<void>((resolve, reject) => {\n server.once('error', reject);\n server.listen(0, '127.0.0.1', resolve);\n });\n\n const address = server.address() as AddressInfo;\n return {\n url: `http://127.0.0.1:${address.port}/tool`,\n token,\n close: () =>\n new Promise((resolve, reject) => {\n server.close((error) => (error ? reject(error) : resolve()));\n }),\n };\n}\n\nfunction indent(code: string): string {\n return code\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n}\n\nfunction createPythonProgram(\n code: string,\n toolDefs: t.LCTool[],\n bridgeUrl: string,\n bridgeToken: string\n): string {\n const functionDefs = toolDefs\n .map((def) => {\n const pythonName = normalizeToPythonIdentifier(def.name);\n return [\n `async def ${pythonName}(**kwargs):`,\n ` return await __librechat_call_tool(${JSON.stringify(def.name)}, kwargs)`,\n ].join('\\n');\n })\n .join('\\n\\n');\n\n return `\nimport asyncio\nimport json\nimport urllib.request\n\n__LIBRECHAT_TOOL_BRIDGE = ${JSON.stringify(bridgeUrl)}\n__LIBRECHAT_TOOL_TOKEN = ${JSON.stringify(bridgeToken)}\n\nasync def __librechat_call_tool(name, payload):\n body = json.dumps({\"name\": name, \"input\": payload}).encode(\"utf-8\")\n headers = {\n \"Content-Type\": \"application/json\",\n ${JSON.stringify(BRIDGE_AUTH_HEADER)}: __LIBRECHAT_TOOL_TOKEN,\n }\n\n def request():\n req = urllib.request.Request(__LIBRECHAT_TOOL_BRIDGE, data=body, headers=headers, method=\"POST\")\n with urllib.request.urlopen(req, timeout=300) as response:\n return response.read().decode(\"utf-8\")\n\n raw = await asyncio.to_thread(request)\n result = json.loads(raw)\n if result.get(\"is_error\"):\n raise RuntimeError(result.get(\"error_message\") or f\"Tool {name} failed\")\n return result.get(\"result\")\n\n${functionDefs}\n\nasync def __librechat_main():\n${indent(code)}\n\nasyncio.run(__librechat_main())\n`.trimStart();\n}\n\nexport function _createBashProgramForTests(\n code: string,\n toolDefs: t.LCTool[],\n bridgeUrl: string,\n bridgeToken: string\n): string {\n return createBashProgram(code, toolDefs, bridgeUrl, bridgeToken);\n}\n\nfunction createBashProgram(\n code: string,\n toolDefs: t.LCTool[],\n bridgeUrl: string,\n bridgeToken: string\n): string {\n const functions = toolDefs\n .map((def) => {\n const bashName = normalizeToBashIdentifier(def.name);\n return [\n `${bashName}() {`,\n ' local payload=\"${1:-}\"',\n ' if [ -z \"$payload\" ]; then payload=\\'{}\\'; fi',\n ` __librechat_call_tool ${shellQuote(def.name)} \"$payload\"`,\n '}',\n ].join('\\n');\n })\n .join('\\n\\n');\n\n return `\n__LIBRECHAT_TOOL_BRIDGE=${shellQuote(bridgeUrl)}\n__LIBRECHAT_TOOL_HEADER=${shellQuote(BRIDGE_AUTH_HEADER)}\n__LIBRECHAT_TOOL_TOKEN=${shellQuote(bridgeToken)}\n\n# Bridge call helper. Tries curl first (universally available, no\n# JSON parser needed thanks to the bridge's ?mode=text endpoint),\n# falls back to python3 for environments without curl. Codex P2 #19\n# flagged that the prior python3-only path broke minimal containers\n# (and Windows hosts without a python3 binary on PATH). Tool names\n# come from Constants.* and are always safe identifiers, so we can\n# splice them into JSON without an escape pass.\n__librechat_call_tool() {\n local tool_name=\"$1\"\n local payload=\"$2\"\n if command -v curl >/dev/null 2>&1; then\n local body=\"{\\\\\"name\\\\\":\\\\\"$tool_name\\\\\",\\\\\"input\\\\\":$payload}\"\n local response\n local http_code\n response=$(curl -sS -X POST \\\n -H \"Content-Type: application/json\" \\\n -H \"$__LIBRECHAT_TOOL_HEADER: $__LIBRECHAT_TOOL_TOKEN\" \\\n --data-binary \"$body\" \\\n -w '\\\\n__LIBRECHAT_HTTP_CODE_%{http_code}__' \\\n \"$__LIBRECHAT_TOOL_BRIDGE?mode=text\")\n http_code=$(printf '%s' \"$response\" | sed -n 's/.*__LIBRECHAT_HTTP_CODE_\\\\([0-9][0-9]*\\\\)__$/\\\\1/p')\n local body_only\n body_only=$(printf '%s' \"$response\" | sed 's/__LIBRECHAT_HTTP_CODE_[0-9][0-9]*__$//')\n if [ \"$http_code\" = \"200\" ]; then\n printf '%s' \"$body_only\"\n return 0\n fi\n printf '%s\\\\n' \"$body_only\" >&2\n return 1\n elif command -v python3 >/dev/null 2>&1; then\n python3 - \"$__LIBRECHAT_TOOL_BRIDGE\" \"$tool_name\" \"$payload\" \"$__LIBRECHAT_TOOL_HEADER\" \"$__LIBRECHAT_TOOL_TOKEN\" <<'PY'\nimport json\nimport sys\nimport urllib.request\n\nurl, name, payload, header, token = sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5]\nbody = json.dumps({\"name\": name, \"input\": json.loads(payload)}).encode(\"utf-8\")\nreq = urllib.request.Request(url, data=body, headers={\"Content-Type\": \"application/json\", header: token}, method=\"POST\")\nwith urllib.request.urlopen(req, timeout=300) as response:\n result = json.loads(response.read().decode(\"utf-8\"))\nif result.get(\"is_error\"):\n print(result.get(\"error_message\") or f\"Tool {name} failed\", file=sys.stderr)\n sys.exit(1)\nvalue = result.get(\"result\")\nif isinstance(value, str):\n print(value)\nelse:\n print(json.dumps(value))\nPY\n else\n printf 'librechat: tool bridge needs either curl or python3 on PATH\\\\n' >&2\n return 1\n fi\n}\n\n${functions}\n\n${code}\n`.trimStart();\n}\n\nfunction getProgrammaticContext(config?: {\n toolCall?: unknown;\n}): Partial<t.ProgrammaticCache> {\n return (config?.toolCall ?? {}) as Partial<t.ProgrammaticCache>;\n}\n\nfunction createEffectiveToolMap(\n toolMap: t.ToolMap,\n toolDefs: t.LCTool[],\n code: string,\n filterTools: ToolFilter\n): { effectiveTools: t.LCTool[]; effectiveMap: t.ToolMap } {\n const effectiveTools = filterTools(toolDefs, code);\n const effectiveMap = new Map<string, t.GenericTool>(\n effectiveTools\n .map((def) => {\n const executable = toolMap.get(def.name);\n return executable == null\n ? undefined\n : ([def.name, executable] as [string, t.GenericTool]);\n })\n .filter((entry): entry is [string, t.GenericTool] => entry != null)\n );\n\n return { effectiveTools, effectiveMap };\n}\n\nasync function runLocalProgrammaticTool(args: {\n params: LocalProgrammaticParams;\n config?: { toolCall?: unknown };\n localConfig: t.LocalExecutionConfig;\n runtime: LocalProgrammaticRuntime;\n}): Promise<[string, t.ProgrammaticExecutionArtifact]> {\n const { toolMap, toolDefs, hookContext } = getProgrammaticContext(args.config);\n\n if (toolMap == null || toolMap.size === 0) {\n throw new Error('No toolMap provided for local programmatic execution.');\n }\n if (toolDefs == null || toolDefs.length === 0) {\n throw new Error('No tool definitions provided for local programmatic execution.');\n }\n\n const { effectiveTools, effectiveMap } = createEffectiveToolMap(\n toolMap,\n toolDefs,\n args.params.code,\n args.runtime === 'bash' ? filterBashToolsByUsage : filterToolsByUsage\n );\n const bridge = await createToolBridge(effectiveMap, hookContext);\n\n try {\n const timeoutMs = args.params.timeout ?? args.localConfig.timeoutMs ?? DEFAULT_TIMEOUT;\n const result =\n args.runtime === 'bash'\n ? await executeLocalBash(\n createBashProgram(args.params.code, effectiveTools, bridge.url, bridge.token),\n { ...args.localConfig, timeoutMs }\n )\n : await executeLocalCode(\n {\n lang: 'py',\n code: createPythonProgram(args.params.code, effectiveTools, bridge.url, bridge.token),\n },\n { ...args.localConfig, timeoutMs }\n );\n\n if (result.exitCode !== 0 || result.timedOut) {\n throw new Error(\n result.stderr !== ''\n ? result.stderr\n : `Local ${args.runtime} programmatic execution exited with code ${\n result.exitCode ?? 'unknown'\n }`\n );\n }\n\n return formatCompletedResponse({\n status: 'completed',\n session_id: getLocalSessionId(args.localConfig),\n stdout: result.stdout,\n stderr: result.stderr,\n files: [],\n });\n } finally {\n await bridge.close();\n }\n}\n\nexport function createLocalProgrammaticToolCallingTool(\n localConfig: t.LocalExecutionConfig = {}\n): DynamicStructuredTool {\n return tool(\n async (rawParams, config) => {\n const params = rawParams as LocalProgrammaticParams;\n return runLocalProgrammaticTool({\n params,\n config,\n localConfig,\n runtime: resolveRuntime(params),\n });\n },\n {\n name: ProgrammaticToolCallingName,\n description: `${ProgrammaticToolCallingDescription}\\n\\nLocal engine: runs bash by default, or Python when \\`lang\\` is \\`py\\` or \\`python\\`, on the host machine and calls tools through an in-process localhost bridge.`,\n schema: LocalProgrammaticToolCallingSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n\nexport function createLocalBashProgrammaticToolCallingTool(\n localConfig: t.LocalExecutionConfig = {}\n): DynamicStructuredTool {\n return tool(\n async (rawParams, config) => {\n const params = rawParams as LocalProgrammaticParams;\n return runLocalProgrammaticTool({\n params,\n config,\n localConfig,\n runtime: 'bash',\n });\n },\n {\n name: Constants.BASH_PROGRAMMATIC_TOOL_CALLING,\n description: `${BashProgrammaticToolCallingDescription}\\n\\nLocal engine: runs this bash orchestration code on the host machine and calls tools through an in-process localhost bridge.`,\n schema: BashProgrammaticToolCallingSchema,\n responseFormat: Constants.CONTENT_AND_ARTIFACT,\n }\n );\n}\n"],"names":["ProgrammaticToolCallingSchema","timingSafeEqual","executeHooks","randomBytes","createServer","randomUUID","executeTools","normalizeToPythonIdentifier","normalizeToBashIdentifier","shellQuote","filterBashToolsByUsage","filterToolsByUsage","executeLocalBash","executeLocalCode","formatCompletedResponse","getLocalSessionId","tool","ProgrammaticToolCallingName","ProgrammaticToolCallingDescription","Constants","BashProgrammaticToolCallingDescription","BashProgrammaticToolCallingSchema"],"mappings":"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"}