@librechat/agents 1.5.2 → 1.5.4

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/main.cjs CHANGED
@@ -5,6 +5,7 @@ var stream = require('./stream.cjs');
5
5
  var events = require('./events.cjs');
6
6
  var messages = require('./messages.cjs');
7
7
  var Graph = require('./graphs/Graph.cjs');
8
+ var CodeExecutor = require('./tools/CodeExecutor.cjs');
8
9
  var _enum = require('./common/enum.cjs');
9
10
  var graph = require('./utils/graph.cjs');
10
11
  var run$1 = require('./utils/run.cjs');
@@ -27,6 +28,7 @@ exports.getConverseOverrideMessage = messages.getConverseOverrideMessage;
27
28
  exports.modifyDeltaProperties = messages.modifyDeltaProperties;
28
29
  exports.Graph = Graph.Graph;
29
30
  exports.StandardGraph = Graph.StandardGraph;
31
+ exports.createCodeExecutionTool = CodeExecutor.createCodeExecutionTool;
30
32
  Object.defineProperty(exports, "Callback", {
31
33
  enumerable: true,
32
34
  get: function () { return _enum.Callback; }
@@ -1 +1 @@
1
- {"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"main.cjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,81 @@
1
+ 'use strict';
2
+
3
+ var zod = require('zod');
4
+ var dotenv = require('dotenv');
5
+ var tools = require('@langchain/core/tools');
6
+
7
+ dotenv.config();
8
+ const EXEC_ENDPOINT = 'https://api.librechat.ai/exec';
9
+ const CodeExecutionToolSchema = zod.z.object({
10
+ lang: zod.z.enum([
11
+ 'py',
12
+ 'js',
13
+ 'ts',
14
+ 'c',
15
+ 'cpp',
16
+ 'java',
17
+ 'php',
18
+ 'rs',
19
+ 'go',
20
+ 'bash',
21
+ 'd',
22
+ 'f90',
23
+ ])
24
+ .describe('The programming language or runtime to execute the code in.'),
25
+ code: zod.z.string()
26
+ .describe('The complete, self-contained code to execute, without any truncation or minimization.'),
27
+ args: zod.z.array(zod.z.string()).optional()
28
+ .describe('Additional arguments to execute the code with.'),
29
+ });
30
+ function createCodeExecutionTool(params = {}) {
31
+ return tools.tool(async ({ lang, code, ...rest }) => {
32
+ const postData = {
33
+ lang,
34
+ code,
35
+ ...rest,
36
+ ...params,
37
+ };
38
+ try {
39
+ const response = await fetch(EXEC_ENDPOINT, {
40
+ method: 'POST',
41
+ headers: {
42
+ 'Content-Type': 'application/json',
43
+ 'User-Agent': 'LibreChat/1.0',
44
+ },
45
+ body: JSON.stringify(postData),
46
+ });
47
+ if (!response.ok) {
48
+ throw new Error(`HTTP error! status: ${response.status}`);
49
+ }
50
+ const result = await response.json();
51
+ let formattedOutput = '';
52
+ if (result.stdout)
53
+ formattedOutput += `stdout:\n${result.stdout}\n`;
54
+ if (result.stderr)
55
+ formattedOutput += `stderr:\n${result.stderr}\n`;
56
+ if (result.files && result.files.length > 0) {
57
+ formattedOutput += 'Generated files:\n';
58
+ result.files.forEach((file) => {
59
+ formattedOutput += `${file.name}`;
60
+ });
61
+ return [formattedOutput.trim(), result.files];
62
+ }
63
+ return [formattedOutput.trim(), undefined];
64
+ }
65
+ catch (error) {
66
+ return `Calling tool with arguments:\n\n${JSON.stringify({
67
+ lang,
68
+ code,
69
+ ...rest,
70
+ })}\n\nraised the following error:\n\n${error?.message}`;
71
+ }
72
+ }, {
73
+ name: 'execute_code',
74
+ description: 'Executes code in various programming languages, returning stdout/stderr output.',
75
+ schema: CodeExecutionToolSchema,
76
+ responseFormat: 'content_and_artifact',
77
+ });
78
+ }
79
+
80
+ exports.createCodeExecutionTool = createCodeExecutionTool;
81
+ //# sourceMappingURL=CodeExecutor.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeExecutor.cjs","sources":["../../../src/tools/CodeExecutor.ts"],"sourcesContent":["import { z } from 'zod';\nimport { config } from 'dotenv';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\n\nconfig();\n\nconst EXEC_ENDPOINT = 'https://api.librechat.ai/exec';\n\nexport type CodeExecutionToolParams = {\n session_id?: string;\n user_id?: string;\n}\n\nexport type FileRef = {\n id: string;\n name: string;\n path?: string;\n};\n\nexport type FileRefs = FileRef[];\n\nexport type ExecuteResult = {\n session_id: string;\n stdout: string;\n stderr: string;\n files?: FileRefs;\n};\n\nconst CodeExecutionToolSchema = z.object({\n lang: z.enum([\n 'py',\n 'js',\n 'ts',\n 'c',\n 'cpp',\n 'java',\n 'php',\n 'rs',\n 'go',\n 'bash',\n 'd',\n 'f90',\n ])\n .describe('The programming language or runtime to execute the code in.'),\n code: z.string()\n .describe('The complete, self-contained code to execute, without any truncation or minimization.'),\n args: z.array(z.string()).optional()\n .describe('Additional arguments to execute the code with.'),\n});\n\nfunction createCodeExecutionTool(params: CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {\n return tool<typeof CodeExecutionToolSchema>(\n async ({ lang, code, ...rest }) => {\n const postData = {\n lang,\n code,\n ...rest,\n ...params,\n };\n\n try {\n const response = await fetch(EXEC_ENDPOINT, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n },\n body: JSON.stringify(postData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result: ExecuteResult = await response.json();\n let formattedOutput = '';\n if (result.stdout) formattedOutput += `stdout:\\n${result.stdout}\\n`;\n if (result.stderr) formattedOutput += `stderr:\\n${result.stderr}\\n`;\n if (result.files && result.files.length > 0) {\n formattedOutput += 'Generated files:\\n';\n result.files.forEach((file: FileRef) => {\n formattedOutput += `${file.name}`;\n });\n return [formattedOutput.trim(), result.files];\n }\n\n return [formattedOutput.trim(), undefined];\n } catch (error) {\n return `Calling tool with arguments:\\n\\n${JSON.stringify({\n lang,\n code,\n ...rest,\n })}\\n\\nraised the following error:\\n\\n${(error as Error | undefined)?.message}`;\n }\n },\n {\n name: 'execute_code',\n description: 'Executes code in various programming languages, returning stdout/stderr output.',\n schema: CodeExecutionToolSchema,\n responseFormat: 'content_and_artifact',\n }\n );\n}\n\nexport { createCodeExecutionTool };"],"names":["config","z","tool"],"mappings":"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"}
package/dist/esm/main.mjs CHANGED
@@ -3,6 +3,7 @@ export { ChatModelStreamHandler, createContentAggregator } from './stream.mjs';
3
3
  export { HandlerRegistry, LLMStreamHandler, ModelEndHandler, TestChatStreamHandler, TestLLMStreamHandler, ToolEndHandler, createMetadataAggregator } from './events.mjs';
4
4
  export { convertMessagesToContent, formatAnthropicMessage, getConverseOverrideMessage, modifyDeltaProperties } from './messages.mjs';
5
5
  export { Graph, StandardGraph } from './graphs/Graph.mjs';
6
+ export { createCodeExecutionTool } from './tools/CodeExecutor.mjs';
6
7
  export { Callback, CommonEvents, ContentTypes, GraphEvents, GraphNodeActions, GraphNodeKeys, Providers, StepTypes, ToolCallTypes } from './common/enum.mjs';
7
8
  export { joinKeys, resetIfNotEmpty } from './utils/graph.mjs';
8
9
  export { RunnableCallable, sleep } from './utils/run.mjs';
@@ -1 +1 @@
1
- {"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;"}
1
+ {"version":3,"file":"main.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
@@ -0,0 +1,79 @@
1
+ import { z } from 'zod';
2
+ import { config } from 'dotenv';
3
+ import { tool } from '@langchain/core/tools';
4
+
5
+ config();
6
+ const EXEC_ENDPOINT = 'https://api.librechat.ai/exec';
7
+ const CodeExecutionToolSchema = z.object({
8
+ lang: z.enum([
9
+ 'py',
10
+ 'js',
11
+ 'ts',
12
+ 'c',
13
+ 'cpp',
14
+ 'java',
15
+ 'php',
16
+ 'rs',
17
+ 'go',
18
+ 'bash',
19
+ 'd',
20
+ 'f90',
21
+ ])
22
+ .describe('The programming language or runtime to execute the code in.'),
23
+ code: z.string()
24
+ .describe('The complete, self-contained code to execute, without any truncation or minimization.'),
25
+ args: z.array(z.string()).optional()
26
+ .describe('Additional arguments to execute the code with.'),
27
+ });
28
+ function createCodeExecutionTool(params = {}) {
29
+ return tool(async ({ lang, code, ...rest }) => {
30
+ const postData = {
31
+ lang,
32
+ code,
33
+ ...rest,
34
+ ...params,
35
+ };
36
+ try {
37
+ const response = await fetch(EXEC_ENDPOINT, {
38
+ method: 'POST',
39
+ headers: {
40
+ 'Content-Type': 'application/json',
41
+ 'User-Agent': 'LibreChat/1.0',
42
+ },
43
+ body: JSON.stringify(postData),
44
+ });
45
+ if (!response.ok) {
46
+ throw new Error(`HTTP error! status: ${response.status}`);
47
+ }
48
+ const result = await response.json();
49
+ let formattedOutput = '';
50
+ if (result.stdout)
51
+ formattedOutput += `stdout:\n${result.stdout}\n`;
52
+ if (result.stderr)
53
+ formattedOutput += `stderr:\n${result.stderr}\n`;
54
+ if (result.files && result.files.length > 0) {
55
+ formattedOutput += 'Generated files:\n';
56
+ result.files.forEach((file) => {
57
+ formattedOutput += `${file.name}`;
58
+ });
59
+ return [formattedOutput.trim(), result.files];
60
+ }
61
+ return [formattedOutput.trim(), undefined];
62
+ }
63
+ catch (error) {
64
+ return `Calling tool with arguments:\n\n${JSON.stringify({
65
+ lang,
66
+ code,
67
+ ...rest,
68
+ })}\n\nraised the following error:\n\n${error?.message}`;
69
+ }
70
+ }, {
71
+ name: 'execute_code',
72
+ description: 'Executes code in various programming languages, returning stdout/stderr output.',
73
+ schema: CodeExecutionToolSchema,
74
+ responseFormat: 'content_and_artifact',
75
+ });
76
+ }
77
+
78
+ export { createCodeExecutionTool };
79
+ //# sourceMappingURL=CodeExecutor.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeExecutor.mjs","sources":["../../../src/tools/CodeExecutor.ts"],"sourcesContent":["import { z } from 'zod';\nimport { config } from 'dotenv';\nimport { tool, DynamicStructuredTool } from '@langchain/core/tools';\n\nconfig();\n\nconst EXEC_ENDPOINT = 'https://api.librechat.ai/exec';\n\nexport type CodeExecutionToolParams = {\n session_id?: string;\n user_id?: string;\n}\n\nexport type FileRef = {\n id: string;\n name: string;\n path?: string;\n};\n\nexport type FileRefs = FileRef[];\n\nexport type ExecuteResult = {\n session_id: string;\n stdout: string;\n stderr: string;\n files?: FileRefs;\n};\n\nconst CodeExecutionToolSchema = z.object({\n lang: z.enum([\n 'py',\n 'js',\n 'ts',\n 'c',\n 'cpp',\n 'java',\n 'php',\n 'rs',\n 'go',\n 'bash',\n 'd',\n 'f90',\n ])\n .describe('The programming language or runtime to execute the code in.'),\n code: z.string()\n .describe('The complete, self-contained code to execute, without any truncation or minimization.'),\n args: z.array(z.string()).optional()\n .describe('Additional arguments to execute the code with.'),\n});\n\nfunction createCodeExecutionTool(params: CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {\n return tool<typeof CodeExecutionToolSchema>(\n async ({ lang, code, ...rest }) => {\n const postData = {\n lang,\n code,\n ...rest,\n ...params,\n };\n\n try {\n const response = await fetch(EXEC_ENDPOINT, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'LibreChat/1.0',\n },\n body: JSON.stringify(postData),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n\n const result: ExecuteResult = await response.json();\n let formattedOutput = '';\n if (result.stdout) formattedOutput += `stdout:\\n${result.stdout}\\n`;\n if (result.stderr) formattedOutput += `stderr:\\n${result.stderr}\\n`;\n if (result.files && result.files.length > 0) {\n formattedOutput += 'Generated files:\\n';\n result.files.forEach((file: FileRef) => {\n formattedOutput += `${file.name}`;\n });\n return [formattedOutput.trim(), result.files];\n }\n\n return [formattedOutput.trim(), undefined];\n } catch (error) {\n return `Calling tool with arguments:\\n\\n${JSON.stringify({\n lang,\n code,\n ...rest,\n })}\\n\\nraised the following error:\\n\\n${(error as Error | undefined)?.message}`;\n }\n },\n {\n name: 'execute_code',\n description: 'Executes code in various programming languages, returning stdout/stderr output.',\n schema: CodeExecutionToolSchema,\n responseFormat: 'content_and_artifact',\n }\n );\n}\n\nexport { createCodeExecutionTool };"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@ export * from './stream';
3
3
  export * from './events';
4
4
  export * from './messages';
5
5
  export * from './graphs';
6
+ export { createCodeExecutionTool } from './tools/CodeExecutor';
6
7
  export * from './common';
7
8
  export * from './utils';
8
9
  export type * from './types';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ import { DynamicStructuredTool } from '@langchain/core/tools';
3
+ export type CodeExecutionToolParams = {
4
+ session_id?: string;
5
+ user_id?: string;
6
+ };
7
+ export type FileRef = {
8
+ id: string;
9
+ name: string;
10
+ path?: string;
11
+ };
12
+ export type FileRefs = FileRef[];
13
+ export type ExecuteResult = {
14
+ session_id: string;
15
+ stdout: string;
16
+ stderr: string;
17
+ files?: FileRefs;
18
+ };
19
+ declare const CodeExecutionToolSchema: z.ZodObject<{
20
+ lang: z.ZodEnum<["py", "js", "ts", "c", "cpp", "java", "php", "rs", "go", "bash", "d", "f90"]>;
21
+ code: z.ZodString;
22
+ args: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
23
+ }, "strip", z.ZodTypeAny, {
24
+ code: string;
25
+ lang: "py" | "js" | "ts" | "c" | "cpp" | "java" | "php" | "rs" | "go" | "bash" | "d" | "f90";
26
+ args?: string[] | undefined;
27
+ }, {
28
+ code: string;
29
+ lang: "py" | "js" | "ts" | "c" | "cpp" | "java" | "php" | "rs" | "go" | "bash" | "d" | "f90";
30
+ args?: string[] | undefined;
31
+ }>;
32
+ declare function createCodeExecutionTool(params?: CodeExecutionToolParams): DynamicStructuredTool<typeof CodeExecutionToolSchema>;
33
+ export { createCodeExecutionTool };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "1.5.2",
3
+ "version": "1.5.4",
4
4
  "main": "./dist/cjs/main.cjs",
5
5
  "module": "./dist/esm/main.mjs",
6
6
  "types": "./dist/types/index.d.ts",
@@ -42,6 +42,7 @@
42
42
  "start:cli": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/cli.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
43
43
  "content": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/content.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
44
44
  "stream": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/stream.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
45
+ "code_exec": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/code_exec.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
45
46
  "simple": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/simple.ts --provider 'bedrock' --name 'Jo' --location 'New York, NY'",
46
47
  "tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
47
48
  "abort": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/abort.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
package/src/index.ts CHANGED
@@ -7,6 +7,9 @@ export * from './messages';
7
7
  /* Graphs */
8
8
  export * from './graphs';
9
9
 
10
+ /* Tools */
11
+ export { createCodeExecutionTool } from './tools/CodeExecutor';
12
+
10
13
  /* Misc. */
11
14
  export * from './common';
12
15
  export * from './utils';
@@ -0,0 +1,176 @@
1
+ // src/scripts/cli.ts
2
+ import { config } from 'dotenv';
3
+ config();
4
+ import { HumanMessage, AIMessage, BaseMessage } from '@langchain/core/messages';
5
+ import { TavilySearchResults } from '@langchain/community/tools/tavily_search';
6
+ import type * as t from '@/types';
7
+ import { ChatModelStreamHandler, createContentAggregator } from '@/stream';
8
+ import { ToolEndHandler, ModelEndHandler, createMetadataAggregator } from '@/events';
9
+ import { getLLMConfig } from '@/utils/llmConfig';
10
+ import { getArgs } from '@/scripts/args';
11
+ import { GraphEvents } from '@/common';
12
+ import { Run } from '@/run';
13
+ import { createCodeExecutionTool } from '@/tools/CodeExecutor';
14
+
15
+ const conversationHistory: BaseMessage[] = [];
16
+
17
+ async function testCodeExecution(): Promise<void> {
18
+ const { userName, location, provider, currentDate } = await getArgs();
19
+ const { contentParts, aggregateContent } = createContentAggregator();
20
+ const customHandlers = {
21
+ [GraphEvents.TOOL_END]: new ToolEndHandler(),
22
+ [GraphEvents.CHAT_MODEL_END]: new ModelEndHandler(),
23
+ [GraphEvents.CHAT_MODEL_STREAM]: new ChatModelStreamHandler(),
24
+ [GraphEvents.ON_RUN_STEP_COMPLETED]: {
25
+ handle: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData): void => {
26
+ console.log('====== ON_RUN_STEP_COMPLETED ======');
27
+ console.dir(data, { depth: null });
28
+ aggregateContent({ event, data: data as unknown as { result: t.ToolEndEvent } });
29
+ }
30
+ },
31
+ [GraphEvents.ON_RUN_STEP]: {
32
+ handle: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData): void => {
33
+ console.log('====== ON_RUN_STEP ======');
34
+ console.dir(data, { depth: null });
35
+ aggregateContent({ event, data: data as t.RunStep });
36
+ }
37
+ },
38
+ [GraphEvents.ON_RUN_STEP_DELTA]: {
39
+ handle: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.StreamEventData): void => {
40
+ console.log('====== ON_RUN_STEP_DELTA ======');
41
+ console.dir(data, { depth: null });
42
+ aggregateContent({ event, data: data as t.RunStepDeltaEvent });
43
+ }
44
+ },
45
+ [GraphEvents.ON_MESSAGE_DELTA]: {
46
+ handle: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.StreamEventData): void => {
47
+ console.log('====== ON_MESSAGE_DELTA ======');
48
+ console.dir(data, { depth: null });
49
+ aggregateContent({ event, data: data as t.MessageDeltaEvent });
50
+ }
51
+ },
52
+ [GraphEvents.TOOL_START]: {
53
+ handle: (_event: string, data: t.StreamEventData, metadata?: Record<string, unknown>): void => {
54
+ console.log('====== TOOL_START ======');
55
+ console.dir(data, { depth: null });
56
+ }
57
+ },
58
+ };
59
+
60
+ const llmConfig = getLLMConfig(provider);
61
+
62
+ const run = await Run.create<t.IState>({
63
+ graphConfig: {
64
+ type: 'standard',
65
+ llmConfig,
66
+ tools: [new TavilySearchResults(), createCodeExecutionTool()],
67
+ instructions: 'You are a friendly AI assistant with coding capabilities. Always address the user by their name.',
68
+ additional_instructions: `The user's name is ${userName} and they are located in ${location}.`,
69
+ },
70
+ returnContent: true,
71
+ customHandlers,
72
+ });
73
+
74
+ const config = {
75
+ configurable: {
76
+ provider,
77
+ thread_id: 'conversation-num-1',
78
+ },
79
+ streamMode: 'values',
80
+ version: 'v2' as const,
81
+ };
82
+
83
+ console.log('Test 1: Sorting Algorithm Comparison');
84
+
85
+ const userMessage1 = `
86
+ Hi ${userName} here. I need a Python script that compares different sorting algorithms. Can you write a script that:
87
+ 1. Implements three sorting algorithms: Bubble Sort, Insertion Sort, and Merge Sort
88
+ 2. Generates three random lists of integers:
89
+ - A small list (20 elements)
90
+ - A medium list (100 elements)
91
+ - A large list (1000 elements)
92
+ 3. Applies each sorting algorithm to each list and measures the execution time
93
+ 4. Prints a comparison table showing the time taken by each algorithm for each list size
94
+ 5. Determines and announces the fastest algorithm for each list size
95
+ Please write the script and then execute it to show the results.
96
+ `;
97
+
98
+ conversationHistory.push(new HumanMessage(userMessage1));
99
+
100
+ let inputs = {
101
+ messages: conversationHistory,
102
+ };
103
+ const finalContentParts1 = await run.processStream(inputs, config);
104
+ const finalMessages1 = run.getRunMessages();
105
+ if (finalMessages1) {
106
+ conversationHistory.push(...finalMessages1);
107
+ }
108
+ console.log('\n\n====================\n\n');
109
+ console.dir(contentParts, { depth: null });
110
+
111
+ console.log('Test 2: Text File Analysis and Processing');
112
+
113
+ const userMessage2 = `
114
+ Great job on the sorting algorithms! Now, let's solve a popular LeetCode problem using the Merge Sort algorithm we implemented. The problem is "Merge Intervals". Here's what I need:
115
+
116
+ 1. Implement a solution to the Merge Intervals problem:
117
+ - Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals.
118
+ - Return an array of the non-overlapping intervals that cover all the intervals in the input.
119
+
120
+ 2. Use the Merge Sort algorithm as part of the solution to sort the intervals based on their start times.
121
+
122
+ 3. Implement a function to generate a random list of intervals for testing.
123
+
124
+ 4. Create test cases:
125
+ - A small case with 5 intervals
126
+ - A medium case with 20 intervals
127
+ - A large case with 100 intervals
128
+
129
+ 5. Apply your solution to each test case and print:
130
+ - The original intervals
131
+ - The merged intervals
132
+ - The time taken to solve each case
133
+
134
+ Please write the script and execute it to demonstrate the results for all three test cases.
135
+ `;
136
+
137
+ conversationHistory.push(new HumanMessage(userMessage2));
138
+
139
+ inputs = {
140
+ messages: conversationHistory,
141
+ };
142
+ const finalContentParts2 = await run.processStream(inputs, config);
143
+ const finalMessages2 = run.getRunMessages();
144
+ if (finalMessages2) {
145
+ conversationHistory.push(...finalMessages2);
146
+ }
147
+ console.log('\n\n====================\n\n');
148
+ console.dir(contentParts, { depth: null });
149
+
150
+ const { handleLLMEnd, collected } = createMetadataAggregator();
151
+ const titleResult = await run.generateTitle({
152
+ inputText: userMessage2,
153
+ contentParts,
154
+ chainOptions: {
155
+ callbacks: [{
156
+ handleLLMEnd,
157
+ }],
158
+ },
159
+ });
160
+ console.log('Generated Title:', titleResult);
161
+ console.log('Collected metadata:', collected);
162
+ }
163
+
164
+ process.on('unhandledRejection', (reason, promise) => {
165
+ console.error('Unhandled Rejection at:', promise, 'reason:', reason);
166
+ console.log('Conversation history:');
167
+ console.dir(conversationHistory, { depth: null });
168
+ process.exit(1);
169
+ });
170
+
171
+ testCodeExecution().catch((err) => {
172
+ console.error(err);
173
+ console.log('Conversation history:');
174
+ console.dir(conversationHistory, { depth: null });
175
+ process.exit(1);
176
+ });
@@ -0,0 +1,105 @@
1
+ import { z } from 'zod';
2
+ import { config } from 'dotenv';
3
+ import { tool, DynamicStructuredTool } from '@langchain/core/tools';
4
+
5
+ config();
6
+
7
+ const EXEC_ENDPOINT = 'https://api.librechat.ai/exec';
8
+
9
+ export type CodeExecutionToolParams = {
10
+ session_id?: string;
11
+ user_id?: string;
12
+ }
13
+
14
+ export type FileRef = {
15
+ id: string;
16
+ name: string;
17
+ path?: string;
18
+ };
19
+
20
+ export type FileRefs = FileRef[];
21
+
22
+ export type ExecuteResult = {
23
+ session_id: string;
24
+ stdout: string;
25
+ stderr: string;
26
+ files?: FileRefs;
27
+ };
28
+
29
+ const CodeExecutionToolSchema = z.object({
30
+ lang: z.enum([
31
+ 'py',
32
+ 'js',
33
+ 'ts',
34
+ 'c',
35
+ 'cpp',
36
+ 'java',
37
+ 'php',
38
+ 'rs',
39
+ 'go',
40
+ 'bash',
41
+ 'd',
42
+ 'f90',
43
+ ])
44
+ .describe('The programming language or runtime to execute the code in.'),
45
+ code: z.string()
46
+ .describe('The complete, self-contained code to execute, without any truncation or minimization.'),
47
+ args: z.array(z.string()).optional()
48
+ .describe('Additional arguments to execute the code with.'),
49
+ });
50
+
51
+ function createCodeExecutionTool(params: CodeExecutionToolParams = {}): DynamicStructuredTool<typeof CodeExecutionToolSchema> {
52
+ return tool<typeof CodeExecutionToolSchema>(
53
+ async ({ lang, code, ...rest }) => {
54
+ const postData = {
55
+ lang,
56
+ code,
57
+ ...rest,
58
+ ...params,
59
+ };
60
+
61
+ try {
62
+ const response = await fetch(EXEC_ENDPOINT, {
63
+ method: 'POST',
64
+ headers: {
65
+ 'Content-Type': 'application/json',
66
+ 'User-Agent': 'LibreChat/1.0',
67
+ },
68
+ body: JSON.stringify(postData),
69
+ });
70
+
71
+ if (!response.ok) {
72
+ throw new Error(`HTTP error! status: ${response.status}`);
73
+ }
74
+
75
+ const result: ExecuteResult = await response.json();
76
+ let formattedOutput = '';
77
+ if (result.stdout) formattedOutput += `stdout:\n${result.stdout}\n`;
78
+ if (result.stderr) formattedOutput += `stderr:\n${result.stderr}\n`;
79
+ if (result.files && result.files.length > 0) {
80
+ formattedOutput += 'Generated files:\n';
81
+ result.files.forEach((file: FileRef) => {
82
+ formattedOutput += `${file.name}`;
83
+ });
84
+ return [formattedOutput.trim(), result.files];
85
+ }
86
+
87
+ return [formattedOutput.trim(), undefined];
88
+ } catch (error) {
89
+ return `Calling tool with arguments:\n\n${JSON.stringify({
90
+ lang,
91
+ code,
92
+ ...rest,
93
+ })}\n\nraised the following error:\n\n${(error as Error | undefined)?.message}`;
94
+ }
95
+ },
96
+ {
97
+ name: 'execute_code',
98
+ description: 'Executes code in various programming languages, returning stdout/stderr output.',
99
+ schema: CodeExecutionToolSchema,
100
+ responseFormat: 'content_and_artifact',
101
+ }
102
+ );
103
+ }
104
+
105
+ export { createCodeExecutionTool };