@librechat/agents 2.3.99 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/splitStream.cjs +44 -13
- package/dist/cjs/splitStream.cjs.map +1 -1
- package/dist/cjs/stream.cjs +6 -6
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +80 -15
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/esm/splitStream.mjs +44 -13
- package/dist/esm/splitStream.mjs.map +1 -1
- package/dist/esm/stream.mjs +6 -6
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +80 -15
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/types/splitStream.d.ts +2 -2
- package/dist/types/tools/CodeExecutor.d.ts +3 -0
- package/dist/types/types/stream.d.ts +12 -10
- package/package.json +1 -1
- package/src/splitStream.ts +68 -28
- package/src/stream.ts +11 -9
- package/src/tools/CodeExecutor.ts +117 -34
- package/src/types/stream.ts +111 -50
- package/src/utils/llmConfig.ts +1 -1
|
@@ -243,29 +243,31 @@ export interface TMessage {
|
|
|
243
243
|
[key: string]: unknown;
|
|
244
244
|
}
|
|
245
245
|
export type TPayload = Array<Partial<TMessage>>;
|
|
246
|
+
export type CustomChunkDelta = null | undefined | (Partial<OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice.Delta> & {
|
|
247
|
+
reasoning?: string | null;
|
|
248
|
+
reasoning_content?: string | null;
|
|
249
|
+
});
|
|
250
|
+
export type CustomChunkChoice = Partial<Omit<OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice, 'delta'> & {
|
|
251
|
+
delta?: CustomChunkDelta;
|
|
252
|
+
}>;
|
|
246
253
|
export type CustomChunk = Partial<OpenAITypes.ChatCompletionChunk> & {
|
|
247
|
-
choices?: Partial<Array<
|
|
248
|
-
delta?: Partial<OpenAITypes.Chat.Completions.ChatCompletionChunk.Choice.Delta> & {
|
|
249
|
-
reasoning?: string | null;
|
|
250
|
-
reasoning_content?: string | null;
|
|
251
|
-
};
|
|
252
|
-
}>>;
|
|
254
|
+
choices?: Partial<Array<CustomChunkChoice>>;
|
|
253
255
|
};
|
|
254
256
|
export type SplitStreamHandlers = Partial<{
|
|
255
|
-
[GraphEvents.ON_RUN_STEP]: ({ event, data }: {
|
|
257
|
+
[GraphEvents.ON_RUN_STEP]: ({ event, data, }: {
|
|
256
258
|
event: GraphEvents;
|
|
257
259
|
data: RunStep;
|
|
258
260
|
}) => void;
|
|
259
|
-
[GraphEvents.ON_MESSAGE_DELTA]: ({ event, data }: {
|
|
261
|
+
[GraphEvents.ON_MESSAGE_DELTA]: ({ event, data, }: {
|
|
260
262
|
event: GraphEvents;
|
|
261
263
|
data: MessageDeltaEvent;
|
|
262
264
|
}) => void;
|
|
263
|
-
[GraphEvents.ON_REASONING_DELTA]: ({ event, data }: {
|
|
265
|
+
[GraphEvents.ON_REASONING_DELTA]: ({ event, data, }: {
|
|
264
266
|
event: GraphEvents;
|
|
265
267
|
data: ReasoningDeltaEvent;
|
|
266
268
|
}) => void;
|
|
267
269
|
}>;
|
|
268
|
-
export type ContentAggregator = ({ event, data }: {
|
|
270
|
+
export type ContentAggregator = ({ event, data, }: {
|
|
269
271
|
event: GraphEvents;
|
|
270
272
|
data: RunStep | MessageDeltaEvent | RunStepDeltaEvent | {
|
|
271
273
|
result: ToolEndEvent;
|
package/package.json
CHANGED
package/src/splitStream.ts
CHANGED
|
@@ -2,7 +2,19 @@ import { nanoid } from 'nanoid';
|
|
|
2
2
|
import type * as t from '@/types';
|
|
3
3
|
import { ContentTypes, GraphEvents, StepTypes } from '@/common';
|
|
4
4
|
|
|
5
|
-
export const SEPARATORS = [
|
|
5
|
+
export const SEPARATORS = [
|
|
6
|
+
'.',
|
|
7
|
+
'?',
|
|
8
|
+
'!',
|
|
9
|
+
'۔',
|
|
10
|
+
'。',
|
|
11
|
+
'‥',
|
|
12
|
+
';',
|
|
13
|
+
'¡',
|
|
14
|
+
'¿',
|
|
15
|
+
'\n',
|
|
16
|
+
'```',
|
|
17
|
+
];
|
|
6
18
|
|
|
7
19
|
export class SplitStreamHandler {
|
|
8
20
|
private inCodeBlock = false;
|
|
@@ -28,12 +40,12 @@ export class SplitStreamHandler {
|
|
|
28
40
|
reasoningKey,
|
|
29
41
|
blockThreshold,
|
|
30
42
|
}: {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
43
|
+
runId: string;
|
|
44
|
+
accumulate?: boolean;
|
|
45
|
+
handlers: t.SplitStreamHandlers;
|
|
46
|
+
blockThreshold?: number;
|
|
47
|
+
reasoningKey?: 'reasoning_content' | 'reasoning';
|
|
48
|
+
}) {
|
|
37
49
|
this.runId = runId;
|
|
38
50
|
this.handlers = handlers;
|
|
39
51
|
if (reasoningKey) {
|
|
@@ -51,7 +63,9 @@ export class SplitStreamHandler {
|
|
|
51
63
|
}
|
|
52
64
|
return undefined;
|
|
53
65
|
};
|
|
54
|
-
createMessageStep = (
|
|
66
|
+
createMessageStep = (
|
|
67
|
+
type?: ContentTypes.TEXT | ContentTypes.THINK
|
|
68
|
+
): [string, string] => {
|
|
55
69
|
if (type != null && this.currentType !== type) {
|
|
56
70
|
this.currentType = type;
|
|
57
71
|
}
|
|
@@ -70,23 +84,35 @@ export class SplitStreamHandler {
|
|
|
70
84
|
stepDetails,
|
|
71
85
|
// usage: null,
|
|
72
86
|
};
|
|
73
|
-
this.handlers?.[GraphEvents.ON_RUN_STEP]?.({
|
|
87
|
+
this.handlers?.[GraphEvents.ON_RUN_STEP]?.({
|
|
88
|
+
event: GraphEvents.ON_RUN_STEP,
|
|
89
|
+
data: runStep,
|
|
90
|
+
});
|
|
74
91
|
};
|
|
75
92
|
dispatchMessageDelta = (stepId: string, delta: t.MessageDelta): void => {
|
|
76
93
|
const messageDelta: t.MessageDeltaEvent = {
|
|
77
94
|
id: stepId,
|
|
78
95
|
delta,
|
|
79
96
|
};
|
|
80
|
-
this.handlers?.[GraphEvents.ON_MESSAGE_DELTA]?.({
|
|
97
|
+
this.handlers?.[GraphEvents.ON_MESSAGE_DELTA]?.({
|
|
98
|
+
event: GraphEvents.ON_MESSAGE_DELTA,
|
|
99
|
+
data: messageDelta,
|
|
100
|
+
});
|
|
81
101
|
};
|
|
82
102
|
dispatchReasoningDelta = (stepId: string, delta: t.ReasoningDelta): void => {
|
|
83
103
|
const reasoningDelta: t.ReasoningDeltaEvent = {
|
|
84
104
|
id: stepId,
|
|
85
105
|
delta,
|
|
86
106
|
};
|
|
87
|
-
this.handlers?.[GraphEvents.ON_REASONING_DELTA]?.({
|
|
107
|
+
this.handlers?.[GraphEvents.ON_REASONING_DELTA]?.({
|
|
108
|
+
event: GraphEvents.ON_REASONING_DELTA,
|
|
109
|
+
data: reasoningDelta,
|
|
110
|
+
});
|
|
88
111
|
};
|
|
89
|
-
handleContent = (
|
|
112
|
+
handleContent = (
|
|
113
|
+
content: string,
|
|
114
|
+
_type: ContentTypes.TEXT | ContentTypes.THINK
|
|
115
|
+
): void => {
|
|
90
116
|
let type = _type;
|
|
91
117
|
if (this.inThinkBlock && type === ContentTypes.TEXT) {
|
|
92
118
|
type = ContentTypes.THINK;
|
|
@@ -112,17 +138,21 @@ export class SplitStreamHandler {
|
|
|
112
138
|
const stepId = this.currentStepId ?? '';
|
|
113
139
|
if (type === ContentTypes.THINK) {
|
|
114
140
|
this.dispatchReasoningDelta(stepId, {
|
|
115
|
-
content: [
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
141
|
+
content: [
|
|
142
|
+
{
|
|
143
|
+
type: ContentTypes.THINK,
|
|
144
|
+
think: content,
|
|
145
|
+
},
|
|
146
|
+
],
|
|
119
147
|
});
|
|
120
148
|
} else {
|
|
121
149
|
this.dispatchMessageDelta(stepId, {
|
|
122
|
-
content: [
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
150
|
+
content: [
|
|
151
|
+
{
|
|
152
|
+
type: ContentTypes.TEXT,
|
|
153
|
+
text: content,
|
|
154
|
+
},
|
|
155
|
+
],
|
|
126
156
|
});
|
|
127
157
|
}
|
|
128
158
|
|
|
@@ -131,7 +161,10 @@ export class SplitStreamHandler {
|
|
|
131
161
|
return;
|
|
132
162
|
}
|
|
133
163
|
|
|
134
|
-
if (
|
|
164
|
+
if (
|
|
165
|
+
this.currentLength > this.blockThreshold &&
|
|
166
|
+
SEPARATORS.some((sep) => content.includes(sep))
|
|
167
|
+
) {
|
|
135
168
|
const [newStepId, newMessageId] = this.createMessageStep(type);
|
|
136
169
|
this.dispatchRunStep(newStepId, {
|
|
137
170
|
type: StepTypes.MESSAGE_CREATION,
|
|
@@ -141,11 +174,14 @@ export class SplitStreamHandler {
|
|
|
141
174
|
});
|
|
142
175
|
}
|
|
143
176
|
};
|
|
144
|
-
getDeltaContent(chunk
|
|
145
|
-
return chunk
|
|
177
|
+
getDeltaContent(chunk?: t.CustomChunk): string {
|
|
178
|
+
return (chunk?.choices?.[0]?.delta as t.CustomChunkDelta)?.content ?? '';
|
|
146
179
|
}
|
|
147
|
-
getReasoningDelta(chunk
|
|
148
|
-
return
|
|
180
|
+
getReasoningDelta(chunk?: t.CustomChunk): string {
|
|
181
|
+
return (
|
|
182
|
+
(chunk?.choices?.[0]?.delta as t.CustomChunkDelta)?.[this.reasoningKey] ??
|
|
183
|
+
''
|
|
184
|
+
);
|
|
149
185
|
}
|
|
150
186
|
handle(chunk?: t.CustomChunk): void {
|
|
151
187
|
if (!chunk) {
|
|
@@ -173,8 +209,12 @@ export class SplitStreamHandler {
|
|
|
173
209
|
const message_id = this.getMessageId() ?? '';
|
|
174
210
|
|
|
175
211
|
if (!message_id) {
|
|
176
|
-
const initialContentType = this.inThinkBlock
|
|
177
|
-
|
|
212
|
+
const initialContentType = this.inThinkBlock
|
|
213
|
+
? ContentTypes.THINK
|
|
214
|
+
: ContentTypes.TEXT;
|
|
215
|
+
const initialType = reasoning_content
|
|
216
|
+
? ContentTypes.THINK
|
|
217
|
+
: initialContentType;
|
|
178
218
|
const [stepId, message_id] = this.createMessageStep(initialType);
|
|
179
219
|
this.dispatchRunStep(stepId, {
|
|
180
220
|
type: StepTypes.MESSAGE_CREATION,
|
|
@@ -190,4 +230,4 @@ export class SplitStreamHandler {
|
|
|
190
230
|
this.handleContent(content, ContentTypes.TEXT);
|
|
191
231
|
}
|
|
192
232
|
}
|
|
193
|
-
}
|
|
233
|
+
}
|
package/src/stream.ts
CHANGED
|
@@ -484,17 +484,19 @@ export function createContentAggregator(): t.ContentAggregatorResult {
|
|
|
484
484
|
'tool_call' in contentPart
|
|
485
485
|
) {
|
|
486
486
|
const existingContent = contentParts[index] as
|
|
487
|
-
| (Omit<t.ToolCallContent, 'tool_call'> & {
|
|
487
|
+
| (Omit<t.ToolCallContent, 'tool_call'> & {
|
|
488
|
+
tool_call?: t.ToolCallPart;
|
|
489
|
+
})
|
|
488
490
|
| undefined;
|
|
489
491
|
|
|
490
|
-
const toolCallArgs =
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
492
|
+
const toolCallArgs = (contentPart.tool_call as t.ToolCallPart).args;
|
|
493
|
+
/** When args are a valid object, they are likely already invoked */
|
|
494
|
+
const args =
|
|
495
|
+
finalUpdate ||
|
|
496
|
+
typeof existingContent?.tool_call?.args === 'object' ||
|
|
497
|
+
typeof toolCallArgs === 'object'
|
|
498
|
+
? contentPart.tool_call.args
|
|
499
|
+
: (existingContent?.tool_call?.args ?? '') + (toolCallArgs ?? '');
|
|
498
500
|
|
|
499
501
|
const id =
|
|
500
502
|
getNonEmptyValue([
|
|
@@ -10,26 +10,33 @@ import { EnvVar, Constants } from '@/common';
|
|
|
10
10
|
config();
|
|
11
11
|
|
|
12
12
|
export const imageExtRegex = /\.(jpg|jpeg|png|gif|webp)$/i;
|
|
13
|
-
export const getCodeBaseURL = (): string =>
|
|
13
|
+
export const getCodeBaseURL = (): string =>
|
|
14
|
+
getEnvironmentVariable(EnvVar.CODE_BASEURL) ??
|
|
15
|
+
Constants.OFFICIAL_CODE_BASEURL;
|
|
14
16
|
|
|
15
|
-
const imageMessage = '
|
|
16
|
-
const otherMessage = '
|
|
17
|
+
const imageMessage = 'Image is already displayed to the user';
|
|
18
|
+
const otherMessage = 'File is already downloaded by the user';
|
|
19
|
+
const accessMessage =
|
|
20
|
+
'IMPORTANT: Files accessed via session ID are READ-ONLY snapshots. Any modifications MUST be saved as NEW files with different names. The original files cannot be modified in-place. To access these files in future executions, you MUST provide this session_id as a parameter. Without the session_id, previously generated files will not be accessible in subsequent executions.';
|
|
21
|
+
const emptyOutputMessage =
|
|
22
|
+
'stdout: Empty. Ensure you\'re writing output explicitly.\n';
|
|
17
23
|
|
|
18
24
|
const CodeExecutionToolSchema = z.object({
|
|
19
|
-
lang: z
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
25
|
+
lang: z
|
|
26
|
+
.enum([
|
|
27
|
+
'py',
|
|
28
|
+
'js',
|
|
29
|
+
'ts',
|
|
30
|
+
'c',
|
|
31
|
+
'cpp',
|
|
32
|
+
'java',
|
|
33
|
+
'php',
|
|
34
|
+
'rs',
|
|
35
|
+
'go',
|
|
36
|
+
'd',
|
|
37
|
+
'f90',
|
|
38
|
+
'r',
|
|
39
|
+
])
|
|
33
40
|
.describe('The programming language or runtime to execute the code in.'),
|
|
34
41
|
code: z.string()
|
|
35
42
|
.describe(`The complete, self-contained code to execute, without any truncation or minimization.
|
|
@@ -42,14 +49,36 @@ const CodeExecutionToolSchema = z.object({
|
|
|
42
49
|
- js: use the \`console\` or \`process\` methods for all outputs.
|
|
43
50
|
- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).
|
|
44
51
|
- Other languages: use appropriate output functions.`),
|
|
45
|
-
|
|
46
|
-
.
|
|
52
|
+
session_id: z
|
|
53
|
+
.string()
|
|
54
|
+
.optional()
|
|
55
|
+
.describe(
|
|
56
|
+
`Optional: Session ID from a previous execution to access generated files.
|
|
57
|
+
- Files load into /mnt/data/ (current working directory)
|
|
58
|
+
- Use relative paths ONLY
|
|
59
|
+
- Files are READ-ONLY - cannot be modified in-place
|
|
60
|
+
- To modify: read original file, write to NEW filename
|
|
61
|
+
`.trim()
|
|
62
|
+
),
|
|
63
|
+
args: z
|
|
64
|
+
.array(z.string())
|
|
65
|
+
.optional()
|
|
66
|
+
.describe(
|
|
67
|
+
'Additional arguments to execute the code with. This should only be used if the input code requires additional arguments to run.'
|
|
68
|
+
),
|
|
47
69
|
});
|
|
48
70
|
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
71
|
+
const baseEndpoint = getCodeBaseURL();
|
|
72
|
+
const EXEC_ENDPOINT = `${baseEndpoint}/exec`;
|
|
73
|
+
|
|
74
|
+
function createCodeExecutionTool(
|
|
75
|
+
params: t.CodeExecutionToolParams = {}
|
|
76
|
+
): DynamicStructuredTool<typeof CodeExecutionToolSchema> {
|
|
77
|
+
const apiKey =
|
|
78
|
+
params[EnvVar.CODE_API_KEY] ??
|
|
79
|
+
params.apiKey ??
|
|
80
|
+
getEnvironmentVariable(EnvVar.CODE_API_KEY) ??
|
|
81
|
+
'';
|
|
53
82
|
if (!apiKey) {
|
|
54
83
|
throw new Error('No API key provided for code execution tool.');
|
|
55
84
|
}
|
|
@@ -64,7 +93,7 @@ Usage:
|
|
|
64
93
|
`.trim();
|
|
65
94
|
|
|
66
95
|
return tool<typeof CodeExecutionToolSchema>(
|
|
67
|
-
async ({ lang, code, ...rest }) => {
|
|
96
|
+
async ({ lang, code, session_id, ...rest }) => {
|
|
68
97
|
const postData = {
|
|
69
98
|
lang,
|
|
70
99
|
code,
|
|
@@ -72,6 +101,54 @@ Usage:
|
|
|
72
101
|
...params,
|
|
73
102
|
};
|
|
74
103
|
|
|
104
|
+
if (session_id != null && session_id.length > 0) {
|
|
105
|
+
try {
|
|
106
|
+
const filesEndpoint = `${baseEndpoint}/files/${session_id}?detail=full`;
|
|
107
|
+
const fetchOptions: RequestInit = {
|
|
108
|
+
method: 'GET',
|
|
109
|
+
headers: {
|
|
110
|
+
'User-Agent': 'LibreChat/1.0',
|
|
111
|
+
'X-API-Key': apiKey,
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
if (process.env.PROXY != null && process.env.PROXY !== '') {
|
|
116
|
+
fetchOptions.agent = new HttpsProxyAgent(process.env.PROXY);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const response = await fetch(filesEndpoint, fetchOptions);
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Failed to fetch files for session: ${response.status}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const files = await response.json();
|
|
127
|
+
if (Array.isArray(files) && files.length > 0) {
|
|
128
|
+
const fileReferences: t.CodeEnvFile[] = files.map((file) => {
|
|
129
|
+
// Extract the ID from the file name (part after session ID prefix and before extension)
|
|
130
|
+
const nameParts = file.name.split('/');
|
|
131
|
+
const id = nameParts.length > 1 ? nameParts[1].split('.')[0] : '';
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
session_id,
|
|
135
|
+
id,
|
|
136
|
+
name: file.metadata['original-filename'],
|
|
137
|
+
};
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
if (!postData.files) {
|
|
141
|
+
postData.files = fileReferences;
|
|
142
|
+
} else if (Array.isArray(postData.files)) {
|
|
143
|
+
postData.files = [...postData.files, ...fileReferences];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} catch {
|
|
147
|
+
// eslint-disable-next-line no-console
|
|
148
|
+
console.warn(`Failed to fetch files for session: ${session_id}`);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
75
152
|
try {
|
|
76
153
|
const fetchOptions: RequestInit = {
|
|
77
154
|
method: 'POST',
|
|
@@ -96,7 +173,7 @@ Usage:
|
|
|
96
173
|
if (result.stdout) {
|
|
97
174
|
formattedOutput += `stdout:\n${result.stdout}\n`;
|
|
98
175
|
} else {
|
|
99
|
-
formattedOutput +=
|
|
176
|
+
formattedOutput += emptyOutputMessage;
|
|
100
177
|
}
|
|
101
178
|
if (result.stderr) formattedOutput += `stderr:\n${result.stderr}\n`;
|
|
102
179
|
if (result.files && result.files.length > 0) {
|
|
@@ -104,24 +181,30 @@ Usage:
|
|
|
104
181
|
|
|
105
182
|
const fileCount = result.files.length;
|
|
106
183
|
for (let i = 0; i < fileCount; i++) {
|
|
107
|
-
const
|
|
108
|
-
const isImage = imageExtRegex.test(
|
|
109
|
-
formattedOutput +=
|
|
184
|
+
const file = result.files[i];
|
|
185
|
+
const isImage = imageExtRegex.test(file.name);
|
|
186
|
+
formattedOutput += `- /mnt/data/${file.name} | ${isImage ? imageMessage : otherMessage}`;
|
|
110
187
|
|
|
111
188
|
if (i < fileCount - 1) {
|
|
112
189
|
formattedOutput += fileCount <= 3 ? ', ' : ',\n';
|
|
113
190
|
}
|
|
114
191
|
}
|
|
115
192
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
193
|
+
formattedOutput += `\nsession_id: ${result.session_id}\n\n${accessMessage}`;
|
|
194
|
+
return [
|
|
195
|
+
formattedOutput.trim(),
|
|
196
|
+
{
|
|
197
|
+
session_id: result.session_id,
|
|
198
|
+
files: result.files,
|
|
199
|
+
},
|
|
200
|
+
];
|
|
120
201
|
}
|
|
121
202
|
|
|
122
203
|
return [formattedOutput.trim(), { session_id: result.session_id }];
|
|
123
204
|
} catch (error) {
|
|
124
|
-
|
|
205
|
+
throw new Error(
|
|
206
|
+
`Execution error:\n\n${(error as Error | undefined)?.message}`
|
|
207
|
+
);
|
|
125
208
|
}
|
|
126
209
|
},
|
|
127
210
|
{
|
|
@@ -133,4 +216,4 @@ Usage:
|
|
|
133
216
|
);
|
|
134
217
|
}
|
|
135
218
|
|
|
136
|
-
export { createCodeExecutionTool };
|
|
219
|
+
export { createCodeExecutionTool };
|