@librechat/agents 3.1.0 → 3.1.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/agents/AgentContext.cjs +2 -5
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +1 -0
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +26 -17
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +1 -0
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +3 -0
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/tools/CodeExecutor.cjs +37 -27
- package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs +21 -17
- package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +1 -0
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/ToolSearch.cjs +37 -30
- package/dist/cjs/tools/ToolSearch.cjs.map +1 -1
- package/dist/cjs/tools/search/schema.cjs +25 -23
- package/dist/cjs/tools/search/schema.cjs.map +1 -1
- package/dist/cjs/tools/search/tool.cjs +9 -33
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/utils/schema.cjs +27 -0
- package/dist/cjs/utils/schema.cjs.map +1 -0
- package/dist/cjs/utils/title.cjs +28 -14
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +2 -5
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +1 -0
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +26 -17
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +1 -0
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +1 -0
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/tools/CodeExecutor.mjs +37 -27
- package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
- package/dist/esm/tools/ProgrammaticToolCalling.mjs +21 -17
- package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +1 -0
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/ToolSearch.mjs +37 -30
- package/dist/esm/tools/ToolSearch.mjs.map +1 -1
- package/dist/esm/tools/search/schema.mjs +25 -23
- package/dist/esm/tools/search/schema.mjs.map +1 -1
- package/dist/esm/tools/search/tool.mjs +10 -34
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/utils/schema.mjs +24 -0
- package/dist/esm/utils/schema.mjs.map +1 -0
- package/dist/esm/utils/title.mjs +28 -14
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/types/tools/CodeExecutor.d.ts +1 -15
- package/dist/types/tools/ProgrammaticToolCalling.d.ts +1 -13
- package/dist/types/tools/ToolSearch.d.ts +1 -15
- package/dist/types/tools/search/schema.d.ts +25 -7
- package/dist/types/tools/search/tool.d.ts +1 -52
- package/dist/types/tools/search/types.d.ts +5 -23
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/schema.d.ts +8 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +5 -11
- package/src/graphs/MultiAgentGraph.ts +26 -17
- package/src/specs/agent-handoffs.test.ts +1 -2
- package/src/specs/tool-error.test.ts +7 -2
- package/src/test/mockTools.ts +34 -14
- package/src/tools/CodeExecutor.ts +48 -31
- package/src/tools/ProgrammaticToolCalling.ts +24 -23
- package/src/tools/ToolSearch.ts +54 -43
- package/src/tools/search/schema.ts +30 -25
- package/src/tools/search/tool.ts +23 -16
- package/src/tools/search/types.ts +5 -29
- package/src/utils/index.ts +1 -0
- package/src/utils/schema.ts +35 -0
- package/src/utils/title.ts +31 -19
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { config } from 'dotenv';
|
|
3
2
|
import fetch, { RequestInit } from 'node-fetch';
|
|
4
3
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
@@ -21,25 +20,33 @@ const accessMessage =
|
|
|
21
20
|
const emptyOutputMessage =
|
|
22
21
|
'stdout: Empty. Ensure you\'re writing output explicitly.\n';
|
|
23
22
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
23
|
+
const SUPPORTED_LANGUAGES = [
|
|
24
|
+
'py',
|
|
25
|
+
'js',
|
|
26
|
+
'ts',
|
|
27
|
+
'c',
|
|
28
|
+
'cpp',
|
|
29
|
+
'java',
|
|
30
|
+
'php',
|
|
31
|
+
'rs',
|
|
32
|
+
'go',
|
|
33
|
+
'd',
|
|
34
|
+
'f90',
|
|
35
|
+
'r',
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
const CodeExecutionToolSchema = {
|
|
39
|
+
type: 'object',
|
|
40
|
+
properties: {
|
|
41
|
+
lang: {
|
|
42
|
+
type: 'string',
|
|
43
|
+
enum: SUPPORTED_LANGUAGES,
|
|
44
|
+
description:
|
|
45
|
+
'The programming language or runtime to execute the code in.',
|
|
46
|
+
},
|
|
47
|
+
code: {
|
|
48
|
+
type: 'string',
|
|
49
|
+
description: `The complete, self-contained code to execute, without any truncation or minimization.
|
|
43
50
|
- The environment is stateless; variables and imports don't persist between executions.
|
|
44
51
|
- Generated files from previous executions are automatically available in "/mnt/data/".
|
|
45
52
|
- Files from previous executions are automatically available and can be modified in place.
|
|
@@ -50,21 +57,26 @@ const CodeExecutionToolSchema = z.object({
|
|
|
50
57
|
- py: Matplotlib: Use \`plt.savefig()\` to save plots as files.
|
|
51
58
|
- js: use the \`console\` or \`process\` methods for all outputs.
|
|
52
59
|
- r: IMPORTANT: No X11 display available. ALL graphics MUST use Cairo library (library(Cairo)).
|
|
53
|
-
- Other languages: use appropriate output functions
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
60
|
+
- Other languages: use appropriate output functions.`,
|
|
61
|
+
},
|
|
62
|
+
args: {
|
|
63
|
+
type: 'array',
|
|
64
|
+
items: { type: 'string' },
|
|
65
|
+
description:
|
|
66
|
+
'Additional arguments to execute the code with. This should only be used if the input code requires additional arguments to run.',
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
required: ['lang', 'code'],
|
|
70
|
+
} as const;
|
|
61
71
|
|
|
62
72
|
const baseEndpoint = getCodeBaseURL();
|
|
63
73
|
const EXEC_ENDPOINT = `${baseEndpoint}/exec`;
|
|
64
74
|
|
|
75
|
+
type SupportedLanguage = (typeof SUPPORTED_LANGUAGES)[number];
|
|
76
|
+
|
|
65
77
|
function createCodeExecutionTool(
|
|
66
78
|
params: t.CodeExecutionToolParams = {}
|
|
67
|
-
): DynamicStructuredTool
|
|
79
|
+
): DynamicStructuredTool {
|
|
68
80
|
const apiKey =
|
|
69
81
|
params[EnvVar.CODE_API_KEY] ??
|
|
70
82
|
params.apiKey ??
|
|
@@ -83,8 +95,13 @@ Usage:
|
|
|
83
95
|
- NEVER use this tool to execute malicious code.
|
|
84
96
|
`.trim();
|
|
85
97
|
|
|
86
|
-
return tool
|
|
87
|
-
async (
|
|
98
|
+
return tool(
|
|
99
|
+
async (rawInput, config) => {
|
|
100
|
+
const { lang, code, ...rest } = rawInput as {
|
|
101
|
+
lang: SupportedLanguage;
|
|
102
|
+
code: string;
|
|
103
|
+
args?: string[];
|
|
104
|
+
};
|
|
88
105
|
/**
|
|
89
106
|
* Extract session context from config.toolCall (injected by ToolNode).
|
|
90
107
|
* - session_id: For API to associate with previous session
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/tools/ProgrammaticToolCalling.ts
|
|
2
|
-
import { z } from 'zod';
|
|
3
2
|
import { config } from 'dotenv';
|
|
4
3
|
import fetch, { RequestInit } from 'node-fetch';
|
|
5
4
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
@@ -33,12 +32,13 @@ const DEFAULT_TIMEOUT = 60000;
|
|
|
33
32
|
// Schema
|
|
34
33
|
// ============================================================================
|
|
35
34
|
|
|
36
|
-
const ProgrammaticToolCallingSchema =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
35
|
+
const ProgrammaticToolCallingSchema = {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
code: {
|
|
39
|
+
type: 'string',
|
|
40
|
+
minLength: 1,
|
|
41
|
+
description: `Python code that calls tools programmatically. Tools are available as async functions.
|
|
42
42
|
|
|
43
43
|
CRITICAL - STATELESS EXECUTION:
|
|
44
44
|
Each call is a fresh Python interpreter. Variables, imports, and data do NOT persist between calls.
|
|
@@ -66,19 +66,19 @@ Rules:
|
|
|
66
66
|
- Just write code with await—auto-wrapped in async context
|
|
67
67
|
- DO NOT define async def main() or call asyncio.run()
|
|
68
68
|
- Tools are pre-defined—DO NOT write function definitions
|
|
69
|
-
- Only print() output returns to the model
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
69
|
+
- Only print() output returns to the model`,
|
|
70
|
+
},
|
|
71
|
+
timeout: {
|
|
72
|
+
type: 'integer',
|
|
73
|
+
minimum: 1000,
|
|
74
|
+
maximum: 300000,
|
|
75
|
+
default: DEFAULT_TIMEOUT,
|
|
76
|
+
description:
|
|
77
|
+
'Maximum execution time in milliseconds. Default: 60 seconds. Max: 5 minutes.',
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
required: ['code'],
|
|
81
|
+
} as const;
|
|
82
82
|
|
|
83
83
|
// ============================================================================
|
|
84
84
|
// Helper Functions
|
|
@@ -576,7 +576,7 @@ export function formatCompletedResponse(
|
|
|
576
576
|
*/
|
|
577
577
|
export function createProgrammaticToolCallingTool(
|
|
578
578
|
initParams: t.ProgrammaticToolCallingParams = {}
|
|
579
|
-
): DynamicStructuredTool
|
|
579
|
+
): DynamicStructuredTool {
|
|
580
580
|
const apiKey =
|
|
581
581
|
(initParams[EnvVar.CODE_API_KEY] as string | undefined) ??
|
|
582
582
|
initParams.apiKey ??
|
|
@@ -616,8 +616,9 @@ Example (complete pipeline):
|
|
|
616
616
|
data = await query_db(sql="..."); df = process(data); await save_to_sheet(data=df); print("Done")
|
|
617
617
|
`.trim();
|
|
618
618
|
|
|
619
|
-
return tool
|
|
620
|
-
async (
|
|
619
|
+
return tool(
|
|
620
|
+
async (rawParams, config) => {
|
|
621
|
+
const params = rawParams as { code: string; timeout?: number };
|
|
621
622
|
const { code, timeout = DEFAULT_TIMEOUT } = params;
|
|
622
623
|
|
|
623
624
|
// Extra params injected by ToolNode (follows web_search pattern)
|
package/src/tools/ToolSearch.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
// src/tools/ToolSearch.ts
|
|
2
|
-
import { z } from 'zod';
|
|
3
2
|
import * as okapibm25Module from 'okapibm25';
|
|
4
3
|
import { config } from 'dotenv';
|
|
5
4
|
|
|
@@ -40,20 +39,25 @@ const MAX_REGEX_COMPLEXITY = 5;
|
|
|
40
39
|
/** Default search timeout in milliseconds */
|
|
41
40
|
const SEARCH_TIMEOUT = 5000;
|
|
42
41
|
|
|
43
|
-
/**
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
/** JSON schema type for tool search parameters */
|
|
43
|
+
interface ToolSearchSchema {
|
|
44
|
+
type: 'object';
|
|
45
|
+
properties: Record<string, unknown>;
|
|
46
|
+
required: string[];
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Input params type for tool search */
|
|
50
|
+
interface ToolSearchParams {
|
|
51
|
+
query?: string;
|
|
52
|
+
fields?: ('name' | 'description' | 'parameters')[];
|
|
53
|
+
max_results?: number;
|
|
54
|
+
mcp_server?: string | string[];
|
|
55
|
+
}
|
|
52
56
|
|
|
53
57
|
/**
|
|
54
|
-
* Creates the
|
|
58
|
+
* Creates the JSON schema with dynamic query description based on mode.
|
|
55
59
|
* @param mode - The search mode determining query interpretation
|
|
56
|
-
* @returns
|
|
60
|
+
* @returns JSON schema for tool search parameters
|
|
57
61
|
*/
|
|
58
62
|
function createToolSearchSchema(mode: t.ToolSearchMode): ToolSearchSchema {
|
|
59
63
|
const queryDescription =
|
|
@@ -61,33 +65,39 @@ function createToolSearchSchema(mode: t.ToolSearchMode): ToolSearchSchema {
|
|
|
61
65
|
? 'Search term to find in tool names and descriptions. Case-insensitive substring matching. Optional if mcp_server is provided.'
|
|
62
66
|
: 'Regex pattern to search tool names and descriptions. Optional if mcp_server is provided.';
|
|
63
67
|
|
|
64
|
-
return
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
return {
|
|
69
|
+
type: 'object',
|
|
70
|
+
properties: {
|
|
71
|
+
query: {
|
|
72
|
+
type: 'string',
|
|
73
|
+
maxLength: MAX_PATTERN_LENGTH,
|
|
74
|
+
default: '',
|
|
75
|
+
description: queryDescription,
|
|
76
|
+
},
|
|
77
|
+
fields: {
|
|
78
|
+
type: 'array',
|
|
79
|
+
items: { type: 'string', enum: ['name', 'description', 'parameters'] },
|
|
80
|
+
default: ['name', 'description'],
|
|
81
|
+
description: 'Which fields to search. Default: name and description',
|
|
82
|
+
},
|
|
83
|
+
max_results: {
|
|
84
|
+
type: 'integer',
|
|
85
|
+
minimum: 1,
|
|
86
|
+
maximum: 50,
|
|
87
|
+
default: 10,
|
|
88
|
+
description: 'Maximum number of matching tools to return',
|
|
89
|
+
},
|
|
90
|
+
mcp_server: {
|
|
91
|
+
oneOf: [
|
|
92
|
+
{ type: 'string' },
|
|
93
|
+
{ type: 'array', items: { type: 'string' } },
|
|
94
|
+
],
|
|
95
|
+
description:
|
|
96
|
+
'Filter to tools from specific MCP server(s). Can be a single server name or array of names. If provided without a query, lists all tools from those servers.',
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
required: [],
|
|
100
|
+
};
|
|
91
101
|
}
|
|
92
102
|
|
|
93
103
|
/**
|
|
@@ -748,7 +758,7 @@ function formatServerListing(
|
|
|
748
758
|
*/
|
|
749
759
|
function createToolSearch(
|
|
750
760
|
initParams: t.ToolSearchParams = {}
|
|
751
|
-
): DynamicStructuredTool
|
|
761
|
+
): DynamicStructuredTool {
|
|
752
762
|
const mode: t.ToolSearchMode = initParams.mode ?? 'code_interpreter';
|
|
753
763
|
const defaultOnlyDeferred = initParams.onlyDeferred ?? true;
|
|
754
764
|
const schema = createToolSearchSchema(mode);
|
|
@@ -802,10 +812,11 @@ Searches deferred tools by regex pattern.
|
|
|
802
812
|
${mcpNote}${toolsListSection}
|
|
803
813
|
`.trim();
|
|
804
814
|
|
|
805
|
-
return tool
|
|
806
|
-
async (
|
|
815
|
+
return tool(
|
|
816
|
+
async (rawParams, config) => {
|
|
817
|
+
const params = rawParams as ToolSearchParams;
|
|
807
818
|
const {
|
|
808
|
-
query,
|
|
819
|
+
query = '',
|
|
809
820
|
fields = ['name', 'description'],
|
|
810
821
|
max_results = 10,
|
|
811
822
|
mcp_server,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
|
-
|
|
3
1
|
export enum DATE_RANGE {
|
|
4
2
|
PAST_HOUR = 'h',
|
|
5
3
|
PAST_24_HOURS = 'd',
|
|
@@ -38,26 +36,33 @@ Examples:
|
|
|
38
36
|
- "in" for India
|
|
39
37
|
`.trim();
|
|
40
38
|
|
|
41
|
-
export const querySchema =
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export const
|
|
47
|
-
|
|
48
|
-
.
|
|
49
|
-
.
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
39
|
+
export const querySchema = {
|
|
40
|
+
type: 'string',
|
|
41
|
+
description: DEFAULT_QUERY_DESCRIPTION,
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
export const dateSchema = {
|
|
45
|
+
type: 'string',
|
|
46
|
+
enum: Object.values(DATE_RANGE),
|
|
47
|
+
description: 'Date range for search results.',
|
|
48
|
+
} as const;
|
|
49
|
+
|
|
50
|
+
export const countrySchema = {
|
|
51
|
+
type: 'string',
|
|
52
|
+
description: DEFAULT_COUNTRY_DESCRIPTION,
|
|
53
|
+
} as const;
|
|
54
|
+
|
|
55
|
+
export const imagesSchema = {
|
|
56
|
+
type: 'boolean',
|
|
57
|
+
description: 'Whether to also run an image search.',
|
|
58
|
+
} as const;
|
|
59
|
+
|
|
60
|
+
export const videosSchema = {
|
|
61
|
+
type: 'boolean',
|
|
62
|
+
description: 'Whether to also run a video search.',
|
|
63
|
+
} as const;
|
|
64
|
+
|
|
65
|
+
export const newsSchema = {
|
|
66
|
+
type: 'boolean',
|
|
67
|
+
description: 'Whether to also run a news search.',
|
|
68
|
+
} as const;
|
package/src/tools/search/tool.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { tool, DynamicStructuredTool } from '@langchain/core/tools';
|
|
3
2
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
4
3
|
import type * as t from './types';
|
|
@@ -269,12 +268,13 @@ function createTool({
|
|
|
269
268
|
search,
|
|
270
269
|
onSearchResults: _onSearchResults,
|
|
271
270
|
}: {
|
|
272
|
-
schema:
|
|
271
|
+
schema: Record<string, unknown>;
|
|
273
272
|
search: ReturnType<typeof createSearchProcessor>;
|
|
274
273
|
onSearchResults: t.SearchToolConfig['onSearchResults'];
|
|
275
|
-
}): DynamicStructuredTool
|
|
276
|
-
return tool
|
|
277
|
-
async (
|
|
274
|
+
}): DynamicStructuredTool {
|
|
275
|
+
return tool(
|
|
276
|
+
async (rawParams, runnableConfig) => {
|
|
277
|
+
const params = rawParams as SearchToolParams;
|
|
278
278
|
const { query, date, country: _c, images, videos, news } = params;
|
|
279
279
|
const country = typeof _c === 'string' && _c ? _c : undefined;
|
|
280
280
|
const searchResult = await search({
|
|
@@ -353,9 +353,19 @@ Use anchor marker(s) immediately after the statement:
|
|
|
353
353
|
* @param config - The search tool configuration
|
|
354
354
|
* @returns A DynamicStructuredTool with a schema that depends on the searchProvider
|
|
355
355
|
*/
|
|
356
|
+
/** Input params type for search tool */
|
|
357
|
+
interface SearchToolParams {
|
|
358
|
+
query: string;
|
|
359
|
+
date?: DATE_RANGE;
|
|
360
|
+
country?: string;
|
|
361
|
+
images?: boolean;
|
|
362
|
+
videos?: boolean;
|
|
363
|
+
news?: boolean;
|
|
364
|
+
}
|
|
365
|
+
|
|
356
366
|
export const createSearchTool = (
|
|
357
367
|
config: t.SearchToolConfig = {}
|
|
358
|
-
): DynamicStructuredTool
|
|
368
|
+
): DynamicStructuredTool => {
|
|
359
369
|
const {
|
|
360
370
|
searchProvider = 'serper',
|
|
361
371
|
serperApiKey,
|
|
@@ -382,14 +392,7 @@ export const createSearchTool = (
|
|
|
382
392
|
|
|
383
393
|
const logger = config.logger || createDefaultLogger();
|
|
384
394
|
|
|
385
|
-
const
|
|
386
|
-
query: z.ZodString;
|
|
387
|
-
date: z.ZodOptional<z.ZodNativeEnum<typeof DATE_RANGE>>;
|
|
388
|
-
country?: z.ZodOptional<z.ZodString>;
|
|
389
|
-
images: z.ZodOptional<z.ZodBoolean>;
|
|
390
|
-
videos: z.ZodOptional<z.ZodBoolean>;
|
|
391
|
-
news: z.ZodOptional<z.ZodBoolean>;
|
|
392
|
-
} = {
|
|
395
|
+
const schemaProperties: Record<string, unknown> = {
|
|
393
396
|
query: querySchema,
|
|
394
397
|
date: dateSchema,
|
|
395
398
|
images: imagesSchema,
|
|
@@ -398,10 +401,14 @@ export const createSearchTool = (
|
|
|
398
401
|
};
|
|
399
402
|
|
|
400
403
|
if (searchProvider === 'serper') {
|
|
401
|
-
|
|
404
|
+
schemaProperties.country = countrySchema;
|
|
402
405
|
}
|
|
403
406
|
|
|
404
|
-
const toolSchema =
|
|
407
|
+
const toolSchema = {
|
|
408
|
+
type: 'object',
|
|
409
|
+
properties: schemaProperties,
|
|
410
|
+
required: ['query'],
|
|
411
|
+
};
|
|
405
412
|
|
|
406
413
|
const searchAPI = createSearchAPI({
|
|
407
414
|
searchProvider,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import type { Logger as WinstonLogger } from 'winston';
|
|
3
2
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
4
3
|
import type { BaseReranker } from './rerankers';
|
|
@@ -657,31 +656,8 @@ export type ProcessSourcesFields = {
|
|
|
657
656
|
onGetHighlights: SearchToolConfig['onGetHighlights'];
|
|
658
657
|
};
|
|
659
658
|
|
|
660
|
-
export
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
images: z.ZodOptional<z.ZodBoolean>;
|
|
666
|
-
videos: z.ZodOptional<z.ZodBoolean>;
|
|
667
|
-
news: z.ZodOptional<z.ZodBoolean>;
|
|
668
|
-
},
|
|
669
|
-
'strip',
|
|
670
|
-
z.ZodTypeAny,
|
|
671
|
-
{
|
|
672
|
-
query: string;
|
|
673
|
-
date?: DATE_RANGE;
|
|
674
|
-
country?: unknown;
|
|
675
|
-
images?: boolean;
|
|
676
|
-
videos?: boolean;
|
|
677
|
-
news?: boolean;
|
|
678
|
-
},
|
|
679
|
-
{
|
|
680
|
-
query: string;
|
|
681
|
-
date?: DATE_RANGE;
|
|
682
|
-
country?: unknown;
|
|
683
|
-
images?: boolean;
|
|
684
|
-
videos?: boolean;
|
|
685
|
-
news?: boolean;
|
|
686
|
-
}
|
|
687
|
-
>;
|
|
659
|
+
export interface SearchToolSchema {
|
|
660
|
+
type: 'object';
|
|
661
|
+
properties: Record<string, unknown>;
|
|
662
|
+
required: string[];
|
|
663
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// src/utils/schema.ts
|
|
2
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
3
|
+
import type { ZodTypeAny } from 'zod';
|
|
4
|
+
|
|
5
|
+
/** Checks if a schema is a Zod schema by looking for the _def property */
|
|
6
|
+
export function isZodSchema(schema: unknown): schema is ZodTypeAny {
|
|
7
|
+
return (
|
|
8
|
+
schema != null && typeof schema === 'object' && '_def' in (schema as object)
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Converts a schema to JSON schema format.
|
|
14
|
+
* Handles both Zod schemas (converts) and JSON schemas (passthrough).
|
|
15
|
+
*/
|
|
16
|
+
export function toJsonSchema(
|
|
17
|
+
schema: unknown,
|
|
18
|
+
name?: string,
|
|
19
|
+
description?: string
|
|
20
|
+
): Record<string, unknown> {
|
|
21
|
+
if (isZodSchema(schema)) {
|
|
22
|
+
const zodSchema = schema as ZodTypeAny & {
|
|
23
|
+
describe: (desc: string) => ZodTypeAny;
|
|
24
|
+
};
|
|
25
|
+
const described =
|
|
26
|
+
description != null && description !== ''
|
|
27
|
+
? zodSchema.describe(description)
|
|
28
|
+
: schema;
|
|
29
|
+
return zodToJsonSchema(
|
|
30
|
+
described as Parameters<typeof zodToJsonSchema>[0],
|
|
31
|
+
name ?? ''
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
return schema as Record<string, unknown>;
|
|
35
|
+
}
|
package/src/utils/title.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { ChatPromptTemplate } from '@langchain/core/prompts';
|
|
3
2
|
import { RunnableLambda, RunnableSequence } from '@langchain/core/runnables';
|
|
4
3
|
import type { Runnable, RunnableConfig } from '@langchain/core/runnables';
|
|
@@ -12,22 +11,33 @@ const defaultTitlePrompt = `Analyze this conversation and provide:
|
|
|
12
11
|
|
|
13
12
|
{convo}`;
|
|
14
13
|
|
|
15
|
-
const titleSchema =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
'
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
const titleSchema = {
|
|
15
|
+
type: 'object',
|
|
16
|
+
properties: {
|
|
17
|
+
title: {
|
|
18
|
+
type: 'string',
|
|
19
|
+
description:
|
|
20
|
+
'A concise title for the conversation in 5 words or less, without punctuation or quotation',
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
required: ['title'],
|
|
24
|
+
} as const;
|
|
25
|
+
|
|
26
|
+
const combinedSchema = {
|
|
27
|
+
type: 'object',
|
|
28
|
+
properties: {
|
|
29
|
+
language: {
|
|
30
|
+
type: 'string',
|
|
31
|
+
description: 'The detected language of the conversation',
|
|
32
|
+
},
|
|
33
|
+
title: {
|
|
34
|
+
type: 'string',
|
|
35
|
+
description:
|
|
36
|
+
'A concise title for the conversation in 5 words or less, without punctuation or quotation',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ['language', 'title'],
|
|
40
|
+
} as const;
|
|
31
41
|
|
|
32
42
|
export const createTitleRunnable = async (
|
|
33
43
|
model: t.ChatModelInstance,
|
|
@@ -54,7 +64,8 @@ export const createTitleRunnable = async (
|
|
|
54
64
|
input: { convo: string },
|
|
55
65
|
config?: Partial<RunnableConfig>
|
|
56
66
|
): Promise<{ title: string }> => {
|
|
57
|
-
|
|
67
|
+
const result = await titleOnlyInnerChain.invoke(input, config);
|
|
68
|
+
return result as { title: string };
|
|
58
69
|
},
|
|
59
70
|
}).withConfig({ runName: 'TitleOnlyChain' });
|
|
60
71
|
|
|
@@ -64,7 +75,8 @@ export const createTitleRunnable = async (
|
|
|
64
75
|
input: { convo: string },
|
|
65
76
|
config?: Partial<RunnableConfig>
|
|
66
77
|
): Promise<{ language: string; title: string }> => {
|
|
67
|
-
|
|
78
|
+
const result = await combinedInnerChain.invoke(input, config);
|
|
79
|
+
return result as { language: string; title: string };
|
|
68
80
|
},
|
|
69
81
|
}).withConfig({ runName: 'TitleLanguageChain' });
|
|
70
82
|
|