@librechat/agents 3.1.90 → 3.1.92

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 (94) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +9 -5
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +48 -14
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/instrumentation.cjs +2 -7
  6. package/dist/cjs/instrumentation.cjs.map +1 -1
  7. package/dist/cjs/langfuse.cjs +285 -0
  8. package/dist/cjs/langfuse.cjs.map +1 -0
  9. package/dist/cjs/main.cjs +25 -0
  10. package/dist/cjs/main.cjs.map +1 -1
  11. package/dist/cjs/run.cjs +75 -44
  12. package/dist/cjs/run.cjs.map +1 -1
  13. package/dist/cjs/stream.cjs +10 -3
  14. package/dist/cjs/stream.cjs.map +1 -1
  15. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs +380 -0
  16. package/dist/cjs/tools/cloudflare/CloudflareBridgeRuntime.cjs.map +1 -0
  17. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +997 -0
  18. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -0
  19. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs +575 -0
  20. package/dist/cjs/tools/cloudflare/CloudflareSandboxExecutionEngine.cjs.map +1 -0
  21. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs +165 -0
  22. package/dist/cjs/tools/cloudflare/CloudflareSandboxTools.cjs.map +1 -0
  23. package/dist/cjs/tools/local/LocalExecutionEngine.cjs +17 -5
  24. package/dist/cjs/tools/local/LocalExecutionEngine.cjs.map +1 -1
  25. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs +110 -6
  26. package/dist/cjs/tools/local/resolveLocalExecutionTools.cjs.map +1 -1
  27. package/dist/cjs/utils/callbacks.cjs +27 -0
  28. package/dist/cjs/utils/callbacks.cjs.map +1 -0
  29. package/dist/esm/agents/AgentContext.mjs +9 -5
  30. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  31. package/dist/esm/graphs/Graph.mjs +48 -14
  32. package/dist/esm/graphs/Graph.mjs.map +1 -1
  33. package/dist/esm/instrumentation.mjs +2 -7
  34. package/dist/esm/instrumentation.mjs.map +1 -1
  35. package/dist/esm/langfuse.mjs +275 -0
  36. package/dist/esm/langfuse.mjs.map +1 -0
  37. package/dist/esm/main.mjs +5 -1
  38. package/dist/esm/main.mjs.map +1 -1
  39. package/dist/esm/run.mjs +75 -44
  40. package/dist/esm/run.mjs.map +1 -1
  41. package/dist/esm/stream.mjs +10 -3
  42. package/dist/esm/stream.mjs.map +1 -1
  43. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs +378 -0
  44. package/dist/esm/tools/cloudflare/CloudflareBridgeRuntime.mjs.map +1 -0
  45. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +994 -0
  46. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -0
  47. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs +566 -0
  48. package/dist/esm/tools/cloudflare/CloudflareSandboxExecutionEngine.mjs.map +1 -0
  49. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs +155 -0
  50. package/dist/esm/tools/cloudflare/CloudflareSandboxTools.mjs.map +1 -0
  51. package/dist/esm/tools/local/LocalExecutionEngine.mjs +17 -6
  52. package/dist/esm/tools/local/LocalExecutionEngine.mjs.map +1 -1
  53. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs +111 -7
  54. package/dist/esm/tools/local/resolveLocalExecutionTools.mjs.map +1 -1
  55. package/dist/esm/utils/callbacks.mjs +24 -0
  56. package/dist/esm/utils/callbacks.mjs.map +1 -0
  57. package/dist/types/agents/AgentContext.d.ts +4 -1
  58. package/dist/types/graphs/Graph.d.ts +6 -5
  59. package/dist/types/index.d.ts +1 -0
  60. package/dist/types/langfuse.d.ts +57 -0
  61. package/dist/types/tools/cloudflare/CloudflareBridgeRuntime.d.ts +23 -0
  62. package/dist/types/tools/cloudflare/CloudflareProgrammaticToolCalling.d.ts +4 -0
  63. package/dist/types/tools/cloudflare/CloudflareSandboxExecutionEngine.d.ts +21 -0
  64. package/dist/types/tools/cloudflare/CloudflareSandboxTools.d.ts +22 -0
  65. package/dist/types/tools/cloudflare/index.d.ts +4 -0
  66. package/dist/types/tools/local/LocalExecutionEngine.d.ts +1 -0
  67. package/dist/types/types/graph.d.ts +8 -0
  68. package/dist/types/types/run.d.ts +2 -2
  69. package/dist/types/types/tools.d.ts +118 -2
  70. package/dist/types/utils/callbacks.d.ts +5 -0
  71. package/package.json +4 -4
  72. package/src/__tests__/stream.eagerEventExecution.test.ts +66 -0
  73. package/src/agents/AgentContext.ts +13 -3
  74. package/src/graphs/Graph.ts +57 -16
  75. package/src/index.ts +1 -0
  76. package/src/instrumentation.ts +2 -7
  77. package/src/langfuse.ts +441 -0
  78. package/src/run.ts +105 -59
  79. package/src/specs/langfuse-callbacks.test.ts +75 -0
  80. package/src/specs/langfuse-config.test.ts +114 -0
  81. package/src/specs/langfuse-metadata.test.ts +19 -1
  82. package/src/stream.ts +13 -3
  83. package/src/tools/__tests__/CloudflareSandboxExecution.test.ts +537 -0
  84. package/src/tools/cloudflare/CloudflareBridgeRuntime.ts +480 -0
  85. package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +1162 -0
  86. package/src/tools/cloudflare/CloudflareSandboxExecutionEngine.ts +744 -0
  87. package/src/tools/cloudflare/CloudflareSandboxTools.ts +225 -0
  88. package/src/tools/cloudflare/index.ts +4 -0
  89. package/src/tools/local/LocalExecutionEngine.ts +20 -4
  90. package/src/tools/local/resolveLocalExecutionTools.ts +169 -7
  91. package/src/types/graph.ts +9 -0
  92. package/src/types/run.ts +2 -7
  93. package/src/types/tools.ts +141 -2
  94. package/src/utils/callbacks.ts +39 -0
@@ -0,0 +1,225 @@
1
+ import { tool } from '@langchain/core/tools';
2
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
3
+ import type * as t from '@/types';
4
+ import {
5
+ CodeExecutionToolName,
6
+ CodeExecutionToolSchema,
7
+ } from '@/tools/CodeExecutor';
8
+ import {
9
+ BashExecutionToolName,
10
+ BashExecutionToolSchema,
11
+ BashToolOutputReferencesGuide,
12
+ } from '@/tools/BashExecutor';
13
+ import {
14
+ createLocalReadFileTool,
15
+ createLocalWriteFileTool,
16
+ createLocalEditFileTool,
17
+ createLocalGrepSearchTool,
18
+ createLocalGlobSearchTool,
19
+ createLocalListDirectoryTool,
20
+ } from '@/tools/local/LocalCodingTools';
21
+ import { createLocalFileCheckpointer } from '@/tools/local/FileCheckpointer';
22
+ import { createCompileCheckTool } from '@/tools/local/CompileCheckTool';
23
+ import { Constants } from '@/common';
24
+ import {
25
+ createCloudflareLocalExecutionConfig,
26
+ createCloudflareWorkspaceFS,
27
+ executeCloudflareBash,
28
+ executeCloudflareCode,
29
+ formatCloudflareOutput,
30
+ getCloudflareWorkspaceRoot,
31
+ } from './CloudflareSandboxExecutionEngine';
32
+ import {
33
+ createCloudflareBashProgrammaticToolCallingTool,
34
+ createCloudflareProgrammaticToolCallingTool,
35
+ } from './CloudflareProgrammaticToolCalling';
36
+
37
+ export const CLOUDFLARE_CODING_TOOL_NAMES: readonly string[] = [
38
+ Constants.READ_FILE,
39
+ Constants.WRITE_FILE,
40
+ Constants.EDIT_FILE,
41
+ Constants.GREP_SEARCH,
42
+ Constants.GLOB_SEARCH,
43
+ Constants.LIST_DIRECTORY,
44
+ Constants.COMPILE_CHECK,
45
+ Constants.BASH_TOOL,
46
+ Constants.EXECUTE_CODE,
47
+ Constants.PROGRAMMATIC_TOOL_CALLING,
48
+ Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
49
+ ];
50
+
51
+ export const CLOUDFLARE_BASH_CODING_TOOL_NAMES: readonly string[] = [
52
+ Constants.READ_FILE,
53
+ Constants.WRITE_FILE,
54
+ Constants.EDIT_FILE,
55
+ Constants.GREP_SEARCH,
56
+ Constants.GLOB_SEARCH,
57
+ Constants.LIST_DIRECTORY,
58
+ Constants.COMPILE_CHECK,
59
+ Constants.BASH_TOOL,
60
+ Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
61
+ ];
62
+
63
+ export const CloudflareCodeExecutionToolDescription = `
64
+ Runs code inside the configured Cloudflare Sandbox workspace. The sandbox can see files and installed runtimes available inside the Cloudflare Sandbox container.
65
+
66
+ Usage:
67
+ - Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.
68
+ - Input code is already displayed to the user, so do not repeat it unless asked.
69
+ - Output is not displayed unless you print it explicitly.
70
+ `.trim();
71
+
72
+ export const CloudflareBashExecutionToolDescription = `
73
+ Runs bash commands inside the configured Cloudflare Sandbox workspace.
74
+
75
+ Usage:
76
+ - Commands execute in the Cloudflare Sandbox workspace and may modify sandbox files.
77
+ - Output is not displayed unless you print it explicitly.
78
+ - Prefer project-native commands and inspect files before changing them.
79
+ `.trim();
80
+
81
+ export function createCloudflareCodeExecutionTool(
82
+ config: t.CloudflareSandboxExecutionConfig
83
+ ): DynamicStructuredTool {
84
+ return tool(
85
+ async (rawInput) => {
86
+ const input = rawInput as {
87
+ lang: string;
88
+ code: string;
89
+ args?: string[];
90
+ };
91
+ const cwd = getCloudflareWorkspaceRoot(config);
92
+ const result = await executeCloudflareCode(input, config);
93
+ return [
94
+ formatCloudflareOutput(result, cwd),
95
+ {
96
+ session_id: 'cloudflare-sandbox',
97
+ files: [],
98
+ } satisfies t.CodeExecutionArtifact,
99
+ ];
100
+ },
101
+ {
102
+ name: CodeExecutionToolName,
103
+ description: CloudflareCodeExecutionToolDescription,
104
+ schema: CodeExecutionToolSchema,
105
+ responseFormat: Constants.CONTENT_AND_ARTIFACT,
106
+ }
107
+ );
108
+ }
109
+
110
+ export function createCloudflareBashExecutionTool(options: {
111
+ config: t.CloudflareSandboxExecutionConfig;
112
+ enableToolOutputReferences?: boolean;
113
+ }): DynamicStructuredTool {
114
+ const { config } = options;
115
+ return tool(
116
+ async (rawInput) => {
117
+ const input = rawInput as { command: string; args?: string[] };
118
+ const cwd = getCloudflareWorkspaceRoot(config);
119
+ const result = await executeCloudflareBash(
120
+ input.command,
121
+ config,
122
+ input.args ?? []
123
+ );
124
+ return [
125
+ formatCloudflareOutput(result, cwd),
126
+ {
127
+ session_id: 'cloudflare-sandbox',
128
+ files: [],
129
+ } satisfies t.CodeExecutionArtifact,
130
+ ];
131
+ },
132
+ {
133
+ name: BashExecutionToolName,
134
+ description:
135
+ options.enableToolOutputReferences === true
136
+ ? `${CloudflareBashExecutionToolDescription}\n\n${BashToolOutputReferencesGuide}`
137
+ : CloudflareBashExecutionToolDescription,
138
+ schema: BashExecutionToolSchema,
139
+ responseFormat: Constants.CONTENT_AND_ARTIFACT,
140
+ }
141
+ );
142
+ }
143
+
144
+ export type CloudflareCodingToolBundle = {
145
+ tools: DynamicStructuredTool[];
146
+ checkpointer?: t.LocalFileCheckpointer;
147
+ };
148
+
149
+ function getSelectedCodingToolNames(
150
+ config: t.CloudflareSandboxExecutionConfig
151
+ ): Set<string> {
152
+ return new Set(config.codingToolNames ?? CLOUDFLARE_CODING_TOOL_NAMES);
153
+ }
154
+
155
+ export function createCloudflareCodingTools(
156
+ config: t.CloudflareSandboxExecutionConfig,
157
+ options: { checkpointer?: t.LocalFileCheckpointer } = {}
158
+ ): DynamicStructuredTool[] {
159
+ const localConfig = createCloudflareLocalExecutionConfig(config);
160
+ const checkpointer =
161
+ options.checkpointer ??
162
+ (config.fileCheckpointing === true
163
+ ? createLocalFileCheckpointer({
164
+ fs: createCloudflareWorkspaceFS(config),
165
+ })
166
+ : undefined);
167
+ const tools = [
168
+ [Constants.READ_FILE, createLocalReadFileTool(localConfig)],
169
+ [Constants.WRITE_FILE, createLocalWriteFileTool(localConfig, checkpointer)],
170
+ [Constants.EDIT_FILE, createLocalEditFileTool(localConfig, checkpointer)],
171
+ [Constants.GREP_SEARCH, createLocalGrepSearchTool(localConfig)],
172
+ [Constants.GLOB_SEARCH, createLocalGlobSearchTool(localConfig)],
173
+ [Constants.LIST_DIRECTORY, createLocalListDirectoryTool(localConfig)],
174
+ [Constants.COMPILE_CHECK, createCompileCheckTool(localConfig)],
175
+ [Constants.BASH_TOOL, createCloudflareBashExecutionTool({ config })],
176
+ [Constants.EXECUTE_CODE, createCloudflareCodeExecutionTool(config)],
177
+ [
178
+ Constants.PROGRAMMATIC_TOOL_CALLING,
179
+ createCloudflareProgrammaticToolCallingTool(config),
180
+ ],
181
+ [
182
+ Constants.BASH_PROGRAMMATIC_TOOL_CALLING,
183
+ createCloudflareBashProgrammaticToolCallingTool(config),
184
+ ],
185
+ ] satisfies Array<[string, DynamicStructuredTool]>;
186
+ const selectedNames = getSelectedCodingToolNames(config);
187
+ return tools
188
+ .filter(([name]) => selectedNames.has(name))
189
+ .map(([, selectedTool]) => selectedTool);
190
+ }
191
+
192
+ export function createCloudflareCodingToolBundle(
193
+ config: t.CloudflareSandboxExecutionConfig,
194
+ options: { checkpointer?: t.LocalFileCheckpointer } = {}
195
+ ): CloudflareCodingToolBundle {
196
+ const checkpointer =
197
+ options.checkpointer ??
198
+ (config.fileCheckpointing === true
199
+ ? createLocalFileCheckpointer({
200
+ fs: createCloudflareWorkspaceFS(config),
201
+ })
202
+ : undefined);
203
+ return {
204
+ tools: createCloudflareCodingTools(config, { checkpointer }),
205
+ checkpointer,
206
+ };
207
+ }
208
+
209
+ export function createCloudflareExecutionTool(
210
+ name: string,
211
+ config: t.CloudflareSandboxExecutionConfig
212
+ ): t.GenericTool | undefined {
213
+ switch (name) {
214
+ case Constants.EXECUTE_CODE:
215
+ return createCloudflareCodeExecutionTool(config);
216
+ case Constants.BASH_TOOL:
217
+ return createCloudflareBashExecutionTool({ config });
218
+ case Constants.PROGRAMMATIC_TOOL_CALLING:
219
+ return createCloudflareProgrammaticToolCallingTool(config);
220
+ case Constants.BASH_PROGRAMMATIC_TOOL_CALLING:
221
+ return createCloudflareBashProgrammaticToolCallingTool(config);
222
+ default:
223
+ return undefined;
224
+ }
225
+ }
@@ -0,0 +1,4 @@
1
+ export * from './CloudflareBridgeRuntime';
2
+ export * from './CloudflareProgrammaticToolCalling';
3
+ export * from './CloudflareSandboxExecutionEngine';
4
+ export * from './CloudflareSandboxTools';
@@ -342,7 +342,11 @@ function shouldUseLocalSandbox(config: t.LocalExecutionConfig): boolean {
342
342
  let sandboxOffWarned = false;
343
343
 
344
344
  function maybeWarnSandboxOff(config: t.LocalExecutionConfig): void {
345
- if (sandboxOffWarned || shouldUseLocalSandbox(config)) {
345
+ if (
346
+ sandboxOffWarned ||
347
+ shouldUseLocalSandbox(config) ||
348
+ config.exec?.sandboxed === true
349
+ ) {
346
350
  return;
347
351
  }
348
352
  sandboxOffWarned = true;
@@ -700,6 +704,8 @@ export interface SpawnLocalProcessOptions {
700
704
  internal?: boolean;
701
705
  }
702
706
 
707
+ export const LOCAL_SPAWN_TIMEOUT_MS = Symbol('librechat.localSpawn.timeoutMs');
708
+
703
709
  export async function spawnLocalProcess(
704
710
  command: string,
705
711
  args: string[],
@@ -742,12 +748,16 @@ export async function spawnLocalProcess(
742
748
 
743
749
  const launcher = getSpawn(config);
744
750
  return new Promise<SpawnResult>((resolveResult, reject) => {
745
- const child = launcher(spawnCommand, spawnArgs, {
751
+ const spawnOptions: import('child_process').SpawnOptions = {
746
752
  cwd,
747
753
  detached: process.platform !== 'win32',
748
754
  env: { ...process.env, ...(config.env ?? {}) },
749
755
  stdio: ['ignore', 'pipe', 'pipe'],
756
+ };
757
+ Object.defineProperty(spawnOptions, LOCAL_SPAWN_TIMEOUT_MS, {
758
+ value: timeoutMs,
750
759
  });
760
+ const child = launcher(spawnCommand, spawnArgs, spawnOptions);
751
761
 
752
762
  let stdout = '';
753
763
  let stderr = '';
@@ -1166,7 +1176,10 @@ function configShell(): string {
1166
1176
  const SIGKILL_ESCALATION_MS = 2000;
1167
1177
 
1168
1178
  function sigterm(child: ChildProcess): void {
1169
- if (child.pid == null) return;
1179
+ if (child.pid == null) {
1180
+ child.kill('SIGTERM');
1181
+ return;
1182
+ }
1170
1183
  try {
1171
1184
  if (process.platform === 'win32') {
1172
1185
  child.kill('SIGTERM');
@@ -1179,8 +1192,11 @@ function sigterm(child: ChildProcess): void {
1179
1192
  }
1180
1193
 
1181
1194
  function sigkill(child: ChildProcess): void {
1182
- if (child.pid == null) return;
1183
1195
  if (child.exitCode != null || child.signalCode != null) return;
1196
+ if (child.pid == null) {
1197
+ child.kill('SIGKILL');
1198
+ return;
1199
+ }
1184
1200
  try {
1185
1201
  if (process.platform === 'win32') {
1186
1202
  child.kill('SIGKILL');
@@ -1,4 +1,8 @@
1
- import { Constants, CODE_EXECUTION_TOOLS } from '@/common';
1
+ import {
2
+ Constants,
3
+ CODE_EXECUTION_TOOLS,
4
+ LOCAL_CODING_BUNDLE_NAMES,
5
+ } from '@/common';
2
6
  import {
3
7
  createLocalBashExecutionTool,
4
8
  createLocalCodeExecutionTool,
@@ -12,6 +16,11 @@ import {
12
16
  createLocalBashProgrammaticToolCallingTool,
13
17
  createLocalProgrammaticToolCallingTool,
14
18
  } from './LocalProgrammaticToolCalling';
19
+ import {
20
+ createCloudflareCodingToolBundle,
21
+ createCloudflareCodingTools,
22
+ createCloudflareExecutionTool,
23
+ } from '@/tools/cloudflare';
15
24
  import type * as t from '@/types';
16
25
 
17
26
  type ResolveLocalToolsResult = {
@@ -34,13 +43,68 @@ function shouldUseLocalExecution(config?: t.ToolExecutionConfig): boolean {
34
43
  return config?.engine === 'local';
35
44
  }
36
45
 
46
+ function shouldUseCloudflareSandboxExecution(
47
+ config?: t.ToolExecutionConfig
48
+ ): boolean {
49
+ return config?.engine === 'cloudflare-sandbox';
50
+ }
51
+
37
52
  function shouldIncludeCodingTools(config?: t.ToolExecutionConfig): boolean {
38
53
  return (
39
- shouldUseLocalExecution(config) &&
40
- config?.local?.includeCodingTools !== false
54
+ (shouldUseLocalExecution(config) &&
55
+ config?.local?.includeCodingTools !== false) ||
56
+ (shouldUseCloudflareSandboxExecution(config) &&
57
+ config?.cloudflare?.includeCodingTools !== false)
41
58
  );
42
59
  }
43
60
 
61
+ function getCloudflareConfig(
62
+ config?: t.ToolExecutionConfig
63
+ ): t.CloudflareSandboxExecutionConfig {
64
+ if (config?.cloudflare == null) {
65
+ throw new Error(
66
+ 'toolExecution.cloudflare is required when engine is "cloudflare-sandbox".'
67
+ );
68
+ }
69
+ return config.cloudflare;
70
+ }
71
+
72
+ function getSelectedCloudflareCodingToolNames(
73
+ config: t.CloudflareSandboxExecutionConfig
74
+ ): Set<string> {
75
+ return new Set(config.codingToolNames ?? LOCAL_CODING_BUNDLE_NAMES);
76
+ }
77
+
78
+ function filterCloudflareCodingToolAllowlist(
79
+ tools: t.GraphTools | undefined,
80
+ selectedNames: Set<string>
81
+ ): t.GraphTools | undefined {
82
+ const existingTools = (tools as t.GenericTool[] | undefined) ?? [];
83
+ if (existingTools.length === 0) {
84
+ return tools;
85
+ }
86
+ return existingTools.filter((existingTool) => {
87
+ if (!('name' in existingTool) || typeof existingTool.name !== 'string') {
88
+ return true;
89
+ }
90
+ return (
91
+ !LOCAL_CODING_BUNDLE_NAMES.includes(existingTool.name) ||
92
+ selectedNames.has(existingTool.name)
93
+ );
94
+ });
95
+ }
96
+
97
+ function pruneCloudflareCodingToolAllowlist(
98
+ toolMap: t.ToolMap,
99
+ selectedNames: Set<string>
100
+ ): void {
101
+ for (const name of LOCAL_CODING_BUNDLE_NAMES) {
102
+ if (!selectedNames.has(name)) {
103
+ toolMap.delete(name);
104
+ }
105
+ }
106
+ }
107
+
44
108
  function createLocalExecutionTool(
45
109
  name: string,
46
110
  config: t.LocalExecutionConfig
@@ -90,10 +154,44 @@ export function resolveLocalToolsForBinding(args: {
90
154
  tools?: t.GraphTools;
91
155
  toolExecution?: t.ToolExecutionConfig;
92
156
  }): t.GraphTools | undefined {
93
- if (!shouldUseLocalExecution(args.toolExecution)) {
157
+ if (
158
+ !shouldUseLocalExecution(args.toolExecution) &&
159
+ !shouldUseCloudflareSandboxExecution(args.toolExecution)
160
+ ) {
94
161
  return args.tools;
95
162
  }
96
163
 
164
+ if (shouldUseCloudflareSandboxExecution(args.toolExecution)) {
165
+ const cloudflareConfig = getCloudflareConfig(args.toolExecution);
166
+ if (shouldIncludeCodingTools(args.toolExecution)) {
167
+ const selectedNames =
168
+ getSelectedCloudflareCodingToolNames(cloudflareConfig);
169
+ return mergeToolsByName(
170
+ filterCloudflareCodingToolAllowlist(args.tools, selectedNames),
171
+ createCloudflareCodingTools(cloudflareConfig)
172
+ );
173
+ }
174
+
175
+ const replacements = ((args.tools as t.GenericTool[] | undefined) ?? [])
176
+ .filter(
177
+ (existingTool): existingTool is t.GenericTool & { name: string } =>
178
+ 'name' in existingTool &&
179
+ typeof existingTool.name === 'string' &&
180
+ CODE_EXECUTION_TOOLS.has(existingTool.name)
181
+ )
182
+ .map((existingTool) =>
183
+ createCloudflareExecutionTool(existingTool.name, cloudflareConfig)
184
+ )
185
+ .filter(
186
+ (cloudflareTool): cloudflareTool is t.GenericTool =>
187
+ cloudflareTool != null
188
+ );
189
+
190
+ return replacements.length === 0
191
+ ? args.tools
192
+ : mergeToolsByName(args.tools, replacements);
193
+ }
194
+
97
195
  const localConfig = args.toolExecution?.local ?? {};
98
196
  if (shouldIncludeCodingTools(args.toolExecution)) {
99
197
  return mergeToolsByName(args.tools, createLocalCodingTools(localConfig));
@@ -125,7 +223,16 @@ export function resolveLocalToolRegistry(args: {
125
223
  }
126
224
 
127
225
  const registry = new Map(args.toolRegistry ?? []);
226
+ const selectedNames = shouldUseCloudflareSandboxExecution(args.toolExecution)
227
+ ? getSelectedCloudflareCodingToolNames(
228
+ getCloudflareConfig(args.toolExecution)
229
+ )
230
+ : undefined;
128
231
  for (const definition of createLocalCodingToolDefinitions()) {
232
+ if (selectedNames != null && !selectedNames.has(definition.name)) {
233
+ registry.delete(definition.name);
234
+ continue;
235
+ }
129
236
  registry.set(definition.name, definition);
130
237
  }
131
238
  return registry;
@@ -145,17 +252,69 @@ export function resolveLocalExecutionTools(args: {
145
252
  fileCheckpointer?: t.LocalFileCheckpointer;
146
253
  }): ResolveLocalToolsResult {
147
254
  const directToolNames = new Set<string>();
148
- if (!shouldUseLocalExecution(args.toolExecution)) {
255
+ if (
256
+ !shouldUseLocalExecution(args.toolExecution) &&
257
+ !shouldUseCloudflareSandboxExecution(args.toolExecution)
258
+ ) {
149
259
  return {
150
260
  toolMap: args.toolMap,
151
261
  directToolNames,
152
262
  };
153
263
  }
154
264
 
155
- const localConfig = args.toolExecution?.local ?? {};
156
265
  const toolMap = new Map(args.toolMap);
157
266
  let fileCheckpointer: t.LocalFileCheckpointer | undefined;
158
267
 
268
+ if (shouldUseCloudflareSandboxExecution(args.toolExecution)) {
269
+ const cloudflareConfig = getCloudflareConfig(args.toolExecution);
270
+ if (shouldIncludeCodingTools(args.toolExecution)) {
271
+ const selectedNames =
272
+ getSelectedCloudflareCodingToolNames(cloudflareConfig);
273
+ pruneCloudflareCodingToolAllowlist(toolMap, selectedNames);
274
+ if (
275
+ cloudflareConfig.fileCheckpointing === true ||
276
+ args.fileCheckpointer != null
277
+ ) {
278
+ const bundle = createCloudflareCodingToolBundle(cloudflareConfig, {
279
+ checkpointer: args.fileCheckpointer,
280
+ });
281
+ fileCheckpointer = bundle.checkpointer;
282
+ for (const cloudflareTool of bundle.tools) {
283
+ toolMap.set(cloudflareTool.name, cloudflareTool);
284
+ directToolNames.add(cloudflareTool.name);
285
+ }
286
+ } else {
287
+ for (const cloudflareTool of createCloudflareCodingTools(
288
+ cloudflareConfig
289
+ )) {
290
+ toolMap.set(cloudflareTool.name, cloudflareTool);
291
+ directToolNames.add(cloudflareTool.name);
292
+ }
293
+ }
294
+ }
295
+
296
+ const includeCodingTools = shouldIncludeCodingTools(args.toolExecution);
297
+ for (const name of CODE_EXECUTION_TOOLS) {
298
+ if (includeCodingTools) continue;
299
+ if (!toolMap.has(name)) continue;
300
+
301
+ const cloudflareTool = createCloudflareExecutionTool(
302
+ name,
303
+ cloudflareConfig
304
+ );
305
+ if (cloudflareTool == null) {
306
+ continue;
307
+ }
308
+
309
+ toolMap.set(name, cloudflareTool);
310
+ directToolNames.add(name);
311
+ }
312
+
313
+ return { toolMap, directToolNames, fileCheckpointer };
314
+ }
315
+
316
+ const localConfig = args.toolExecution?.local ?? {};
317
+
159
318
  if (shouldIncludeCodingTools(args.toolExecution)) {
160
319
  // Use the bundle factory when fileCheckpointing is on so we can
161
320
  // surface the checkpointer back to the caller — without this, the
@@ -163,7 +322,10 @@ export function resolveLocalExecutionTools(args: {
163
322
  // immediately discarded, making the public `fileCheckpointing`
164
323
  // config flag a silent no-op outside of direct
165
324
  // `createLocalCodingToolBundle()` use.
166
- if (localConfig.fileCheckpointing === true || args.fileCheckpointer != null) {
325
+ if (
326
+ localConfig.fileCheckpointing === true ||
327
+ args.fileCheckpointer != null
328
+ ) {
167
329
  const bundle = createLocalCodingToolBundle(localConfig, {
168
330
  checkpointer: args.fileCheckpointer,
169
331
  });
@@ -408,6 +408,13 @@ export interface SubagentUpdateEvent {
408
408
  timestamp: string;
409
409
  }
410
410
 
411
+ export interface LangfuseConfig {
412
+ enabled?: boolean;
413
+ publicKey?: string;
414
+ secretKey?: string;
415
+ baseUrl?: string;
416
+ }
417
+
411
418
  export interface AgentInputs {
412
419
  agentId: string;
413
420
  /** Human-readable name for the agent (used in handoff context). Defaults to agentId if not provided. */
@@ -421,6 +428,8 @@ export interface AgentInputs {
421
428
  streamBuffer?: number;
422
429
  maxContextTokens?: number;
423
430
  clientOptions?: ClientOptions;
431
+ /** Per-agent Langfuse tracing configuration. */
432
+ langfuse?: LangfuseConfig;
424
433
  /** Dynamic system tail appended after stable instructions without provider cache markers. */
425
434
  additional_instructions?: string;
426
435
  reasoningKey?: 'reasoning_content' | 'reasoning';
package/src/types/run.ts CHANGED
@@ -3,10 +3,7 @@ import type * as z from 'zod';
3
3
  import type { BaseMessage } from '@langchain/core/messages';
4
4
  import type { StructuredTool } from '@langchain/core/tools';
5
5
  import type { RunnableConfig } from '@langchain/core/runnables';
6
- import type {
7
- BaseCallbackHandler,
8
- CallbackHandlerMethods,
9
- } from '@langchain/core/callbacks/base';
6
+ import type { Callbacks } from '@langchain/core/callbacks/manager';
10
7
  import type * as s from '@/types/stream';
11
8
  import type * as e from '@/common/enum';
12
9
  import type * as g from '@/types/graph';
@@ -213,9 +210,7 @@ export type RunConfig = {
213
210
  humanInTheLoop?: HumanInTheLoopConfig;
214
211
  };
215
212
 
216
- export type ProvidedCallbacks =
217
- | (BaseCallbackHandler | CallbackHandlerMethods)[]
218
- | undefined;
213
+ export type ProvidedCallbacks = Callbacks | undefined;
219
214
 
220
215
  export type TokenCounter = (message: BaseMessage) => number;
221
216