@librechat/agents 3.0.0-rc9 → 3.0.0
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 +6 -2
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +23 -2
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/graphs/MultiAgentGraph.cjs +5 -5
- package/dist/cjs/graphs/MultiAgentGraph.cjs.map +1 -1
- package/dist/cjs/instrumentation.cjs +21 -0
- package/dist/cjs/instrumentation.cjs.map +1 -0
- package/dist/cjs/llm/anthropic/index.cjs +21 -2
- package/dist/cjs/llm/anthropic/index.cjs.map +1 -1
- package/dist/cjs/llm/google/index.cjs +3 -0
- package/dist/cjs/llm/google/index.cjs.map +1 -1
- package/dist/cjs/llm/google/utils/common.cjs +13 -0
- package/dist/cjs/llm/google/utils/common.cjs.map +1 -1
- package/dist/cjs/llm/ollama/index.cjs +3 -0
- package/dist/cjs/llm/ollama/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/index.cjs +18 -3
- package/dist/cjs/llm/openai/index.cjs.map +1 -1
- package/dist/cjs/llm/openai/utils/index.cjs +6 -1
- package/dist/cjs/llm/openai/utils/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +5 -1
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/vertexai/index.cjs +1 -1
- package/dist/cjs/llm/vertexai/index.cjs.map +1 -1
- package/dist/cjs/main.cjs +8 -2
- package/dist/cjs/main.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +49 -0
- package/dist/cjs/messages/cache.cjs.map +1 -0
- package/dist/cjs/messages/content.cjs +53 -0
- package/dist/cjs/messages/content.cjs.map +1 -0
- package/dist/cjs/messages/core.cjs +5 -1
- package/dist/cjs/messages/core.cjs.map +1 -1
- package/dist/cjs/messages/format.cjs +50 -59
- package/dist/cjs/messages/format.cjs.map +1 -1
- package/dist/cjs/messages/prune.cjs +28 -0
- package/dist/cjs/messages/prune.cjs.map +1 -1
- package/dist/cjs/run.cjs +57 -5
- package/dist/cjs/run.cjs.map +1 -1
- package/dist/cjs/stream.cjs +7 -0
- package/dist/cjs/stream.cjs.map +1 -1
- package/dist/cjs/tools/ToolNode.cjs +2 -0
- package/dist/cjs/tools/ToolNode.cjs.map +1 -1
- package/dist/cjs/tools/search/firecrawl.cjs +3 -1
- package/dist/cjs/tools/search/firecrawl.cjs.map +1 -1
- package/dist/cjs/tools/search/rerankers.cjs +8 -6
- package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
- package/dist/cjs/tools/search/search.cjs +5 -5
- package/dist/cjs/tools/search/search.cjs.map +1 -1
- package/dist/cjs/tools/search/serper-scraper.cjs +132 -0
- package/dist/cjs/tools/search/serper-scraper.cjs.map +1 -0
- package/dist/cjs/tools/search/tool.cjs +46 -9
- package/dist/cjs/tools/search/tool.cjs.map +1 -1
- package/dist/cjs/utils/handlers.cjs +70 -0
- package/dist/cjs/utils/handlers.cjs.map +1 -0
- package/dist/cjs/utils/misc.cjs +8 -1
- package/dist/cjs/utils/misc.cjs.map +1 -1
- package/dist/cjs/utils/title.cjs +54 -25
- package/dist/cjs/utils/title.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +6 -2
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +23 -2
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/graphs/MultiAgentGraph.mjs +5 -5
- package/dist/esm/graphs/MultiAgentGraph.mjs.map +1 -1
- package/dist/esm/instrumentation.mjs +19 -0
- package/dist/esm/instrumentation.mjs.map +1 -0
- package/dist/esm/llm/anthropic/index.mjs +21 -2
- package/dist/esm/llm/anthropic/index.mjs.map +1 -1
- package/dist/esm/llm/google/index.mjs +3 -0
- package/dist/esm/llm/google/index.mjs.map +1 -1
- package/dist/esm/llm/google/utils/common.mjs +13 -0
- package/dist/esm/llm/google/utils/common.mjs.map +1 -1
- package/dist/esm/llm/ollama/index.mjs +3 -0
- package/dist/esm/llm/ollama/index.mjs.map +1 -1
- package/dist/esm/llm/openai/index.mjs +18 -3
- package/dist/esm/llm/openai/index.mjs.map +1 -1
- package/dist/esm/llm/openai/utils/index.mjs +6 -1
- package/dist/esm/llm/openai/utils/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +5 -1
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/vertexai/index.mjs +1 -1
- package/dist/esm/llm/vertexai/index.mjs.map +1 -1
- package/dist/esm/main.mjs +5 -2
- package/dist/esm/main.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +47 -0
- package/dist/esm/messages/cache.mjs.map +1 -0
- package/dist/esm/messages/content.mjs +51 -0
- package/dist/esm/messages/content.mjs.map +1 -0
- package/dist/esm/messages/core.mjs +5 -1
- package/dist/esm/messages/core.mjs.map +1 -1
- package/dist/esm/messages/format.mjs +50 -58
- package/dist/esm/messages/format.mjs.map +1 -1
- package/dist/esm/messages/prune.mjs +28 -0
- package/dist/esm/messages/prune.mjs.map +1 -1
- package/dist/esm/run.mjs +57 -5
- package/dist/esm/run.mjs.map +1 -1
- package/dist/esm/stream.mjs +7 -0
- package/dist/esm/stream.mjs.map +1 -1
- package/dist/esm/tools/ToolNode.mjs +2 -0
- package/dist/esm/tools/ToolNode.mjs.map +1 -1
- package/dist/esm/tools/search/firecrawl.mjs +3 -1
- package/dist/esm/tools/search/firecrawl.mjs.map +1 -1
- package/dist/esm/tools/search/rerankers.mjs +8 -6
- package/dist/esm/tools/search/rerankers.mjs.map +1 -1
- package/dist/esm/tools/search/search.mjs +5 -5
- package/dist/esm/tools/search/search.mjs.map +1 -1
- package/dist/esm/tools/search/serper-scraper.mjs +129 -0
- package/dist/esm/tools/search/serper-scraper.mjs.map +1 -0
- package/dist/esm/tools/search/tool.mjs +46 -9
- package/dist/esm/tools/search/tool.mjs.map +1 -1
- package/dist/esm/utils/handlers.mjs +68 -0
- package/dist/esm/utils/handlers.mjs.map +1 -0
- package/dist/esm/utils/misc.mjs +8 -2
- package/dist/esm/utils/misc.mjs.map +1 -1
- package/dist/esm/utils/title.mjs +54 -25
- package/dist/esm/utils/title.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +4 -1
- package/dist/types/instrumentation.d.ts +1 -0
- package/dist/types/llm/anthropic/index.d.ts +3 -0
- package/dist/types/llm/google/index.d.ts +1 -0
- package/dist/types/llm/ollama/index.d.ts +1 -0
- package/dist/types/llm/openai/index.d.ts +4 -0
- package/dist/types/llm/openrouter/index.d.ts +4 -2
- package/dist/types/llm/vertexai/index.d.ts +1 -1
- package/dist/types/messages/cache.d.ts +8 -0
- package/dist/types/messages/content.d.ts +7 -0
- package/dist/types/messages/format.d.ts +22 -25
- package/dist/types/messages/index.d.ts +2 -0
- package/dist/types/run.d.ts +2 -1
- package/dist/types/tools/search/firecrawl.d.ts +2 -1
- package/dist/types/tools/search/rerankers.d.ts +4 -1
- package/dist/types/tools/search/search.d.ts +1 -2
- package/dist/types/tools/search/serper-scraper.d.ts +59 -0
- package/dist/types/tools/search/tool.d.ts +25 -4
- package/dist/types/tools/search/types.d.ts +31 -1
- package/dist/types/types/graph.d.ts +3 -1
- package/dist/types/types/messages.d.ts +4 -0
- package/dist/types/utils/handlers.d.ts +34 -0
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/misc.d.ts +1 -0
- package/package.json +6 -2
- package/src/agents/AgentContext.ts +8 -0
- package/src/graphs/Graph.ts +31 -2
- package/src/graphs/MultiAgentGraph.ts +5 -5
- package/src/instrumentation.ts +22 -0
- package/src/llm/anthropic/index.ts +23 -2
- package/src/llm/anthropic/llm.spec.ts +1 -1
- package/src/llm/google/index.ts +4 -0
- package/src/llm/google/utils/common.ts +14 -0
- package/src/llm/ollama/index.ts +3 -0
- package/src/llm/openai/index.ts +17 -4
- package/src/llm/openai/utils/index.ts +7 -1
- package/src/llm/openrouter/index.ts +15 -6
- package/src/llm/vertexai/index.ts +2 -2
- package/src/messages/cache.test.ts +262 -0
- package/src/messages/cache.ts +56 -0
- package/src/messages/content.test.ts +362 -0
- package/src/messages/content.ts +63 -0
- package/src/messages/core.ts +5 -2
- package/src/messages/format.ts +65 -71
- package/src/messages/formatMessage.test.ts +418 -2
- package/src/messages/index.ts +2 -0
- package/src/messages/prune.ts +51 -0
- package/src/run.ts +82 -10
- package/src/scripts/ant_web_search.ts +1 -1
- package/src/scripts/handoff-test.ts +1 -1
- package/src/scripts/multi-agent-chain.ts +4 -4
- package/src/scripts/multi-agent-conditional.ts +4 -4
- package/src/scripts/multi-agent-document-review-chain.ts +4 -4
- package/src/scripts/multi-agent-parallel.ts +10 -8
- package/src/scripts/multi-agent-sequence.ts +3 -3
- package/src/scripts/multi-agent-supervisor.ts +5 -3
- package/src/scripts/multi-agent-test.ts +2 -2
- package/src/scripts/search.ts +5 -1
- package/src/scripts/simple.ts +8 -0
- package/src/scripts/test-custom-prompt-key.ts +4 -4
- package/src/scripts/test-handoff-input.ts +3 -3
- package/src/scripts/test-multi-agent-list-handoff.ts +2 -2
- package/src/scripts/tools.ts +4 -1
- package/src/specs/agent-handoffs.test.ts +889 -0
- package/src/stream.ts +9 -2
- package/src/tools/search/firecrawl.ts +5 -2
- package/src/tools/search/jina-reranker.test.ts +126 -0
- package/src/tools/search/rerankers.ts +11 -5
- package/src/tools/search/search.ts +6 -8
- package/src/tools/search/serper-scraper.ts +155 -0
- package/src/tools/search/tool.ts +49 -8
- package/src/tools/search/types.ts +46 -0
- package/src/types/graph.ts +6 -1
- package/src/types/messages.ts +4 -0
- package/src/utils/handlers.ts +107 -0
- package/src/utils/index.ts +2 -1
- package/src/utils/llmConfig.ts +35 -1
- package/src/utils/misc.ts +33 -21
- package/src/utils/title.ts +80 -40
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import { AIMessage, ToolMessage,
|
|
1
|
+
import { AIMessage, ToolMessage, HumanMessage, SystemMessage } from '@langchain/core/messages';
|
|
2
2
|
import type { MessageContentImageUrl } from '@langchain/core/messages';
|
|
3
3
|
import type { MessageContentComplex, TPayload } from '@/types';
|
|
4
4
|
import { Providers } from '@/common';
|
|
5
|
-
interface
|
|
5
|
+
interface MediaMessageParams {
|
|
6
6
|
message: {
|
|
7
7
|
role: string;
|
|
8
8
|
content: string;
|
|
9
9
|
name?: string;
|
|
10
10
|
[key: string]: any;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
mediaParts: MessageContentComplex[];
|
|
13
13
|
endpoint?: Providers;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
* Formats a message
|
|
16
|
+
* Formats a message with media content (images, documents, videos, audios) to API payload format.
|
|
17
17
|
*
|
|
18
|
-
* @param
|
|
19
|
-
* @returns
|
|
18
|
+
* @param params - The parameters for formatting.
|
|
19
|
+
* @returns - The formatted message.
|
|
20
20
|
*/
|
|
21
|
-
export declare const
|
|
21
|
+
export declare const formatMediaMessage: ({ message, endpoint, mediaParts, }: MediaMessageParams) => {
|
|
22
22
|
role: string;
|
|
23
23
|
content: MessageContentComplex[];
|
|
24
24
|
name?: string;
|
|
@@ -31,6 +31,9 @@ interface MessageInput {
|
|
|
31
31
|
text?: string;
|
|
32
32
|
content?: string | MessageContentComplex[];
|
|
33
33
|
image_urls?: MessageContentImageUrl[];
|
|
34
|
+
documents?: MessageContentComplex[];
|
|
35
|
+
videos?: MessageContentComplex[];
|
|
36
|
+
audios?: MessageContentComplex[];
|
|
34
37
|
lc_id?: string[];
|
|
35
38
|
[key: string]: any;
|
|
36
39
|
}
|
|
@@ -50,16 +53,16 @@ interface FormattedMessage {
|
|
|
50
53
|
/**
|
|
51
54
|
* Formats a message to OpenAI payload format based on the provided options.
|
|
52
55
|
*
|
|
53
|
-
* @param
|
|
54
|
-
* @returns
|
|
56
|
+
* @param params - The parameters for formatting.
|
|
57
|
+
* @returns - The formatted message.
|
|
55
58
|
*/
|
|
56
|
-
export declare const formatMessage: ({ message, userName,
|
|
59
|
+
export declare const formatMessage: ({ message, userName, endpoint, assistantName, langChain, }: FormatMessageParams) => FormattedMessage | HumanMessage | AIMessage | SystemMessage;
|
|
57
60
|
/**
|
|
58
61
|
* Formats an array of messages for LangChain.
|
|
59
62
|
*
|
|
60
|
-
* @param
|
|
61
|
-
* @param
|
|
62
|
-
* @returns
|
|
63
|
+
* @param messages - The array of messages to format.
|
|
64
|
+
* @param formatOptions - The options for formatting each message.
|
|
65
|
+
* @returns - The array of formatted LangChain messages.
|
|
63
66
|
*/
|
|
64
67
|
export declare const formatLangChainMessages: (messages: Array<MessageInput>, formatOptions: Omit<FormatMessageParams, "message" | "langChain">) => Array<HumanMessage | AIMessage | SystemMessage>;
|
|
65
68
|
interface LangChainMessage {
|
|
@@ -76,28 +79,22 @@ interface LangChainMessage {
|
|
|
76
79
|
/**
|
|
77
80
|
* Formats a LangChain message object by merging properties from `lc_kwargs` or `kwargs` and `additional_kwargs`.
|
|
78
81
|
*
|
|
79
|
-
* @param
|
|
80
|
-
* @returns
|
|
82
|
+
* @param message - The message object to format.
|
|
83
|
+
* @returns - The formatted LangChain message.
|
|
81
84
|
*/
|
|
82
85
|
export declare const formatFromLangChain: (message: LangChainMessage) => Record<string, any>;
|
|
83
86
|
/**
|
|
84
87
|
* Formats an array of messages for LangChain, handling tool calls and creating ToolMessage instances.
|
|
85
88
|
*
|
|
86
|
-
* @param
|
|
87
|
-
* @param
|
|
88
|
-
* @param
|
|
89
|
-
* @returns
|
|
89
|
+
* @param payload - The array of messages to format.
|
|
90
|
+
* @param indexTokenCountMap - Optional map of message indices to token counts.
|
|
91
|
+
* @param tools - Optional set of tool names that are allowed in the request.
|
|
92
|
+
* @returns - Object containing formatted messages and updated indexTokenCountMap if provided.
|
|
90
93
|
*/
|
|
91
94
|
export declare const formatAgentMessages: (payload: TPayload, indexTokenCountMap?: Record<number, number>, tools?: Set<string>) => {
|
|
92
95
|
messages: Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>;
|
|
93
96
|
indexTokenCountMap?: Record<number, number>;
|
|
94
97
|
};
|
|
95
|
-
/**
|
|
96
|
-
* Formats an array of messages for LangChain, making sure all content fields are strings
|
|
97
|
-
* @param {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} payload - The array of messages to format.
|
|
98
|
-
* @returns {Array<HumanMessage | AIMessage | SystemMessage | ToolMessage>} - The array of formatted LangChain messages, including ToolMessages for tool calls.
|
|
99
|
-
*/
|
|
100
|
-
export declare const formatContentStrings: (payload: Array<BaseMessage>) => Array<BaseMessage>;
|
|
101
98
|
/**
|
|
102
99
|
* Adds a value at key 0 for system messages and shifts all key indices by one in an indexTokenCountMap.
|
|
103
100
|
* This is useful when adding a system message at the beginning of a conversation.
|
package/dist/types/run.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import './instrumentation';
|
|
2
|
+
import type { MessageContentComplex, BaseMessage } from '@langchain/core/messages';
|
|
2
3
|
import type { RunnableConfig } from '@langchain/core/runnables';
|
|
3
4
|
import type * as t from '@/types';
|
|
4
5
|
import { MultiAgentGraph } from '@/graphs/MultiAgentGraph';
|
|
@@ -3,9 +3,10 @@ import type * as t from './types';
|
|
|
3
3
|
* Firecrawl scraper implementation
|
|
4
4
|
* Uses the Firecrawl API to scrape web pages
|
|
5
5
|
*/
|
|
6
|
-
export declare class FirecrawlScraper {
|
|
6
|
+
export declare class FirecrawlScraper implements t.BaseScraper {
|
|
7
7
|
private apiKey;
|
|
8
8
|
private apiUrl;
|
|
9
|
+
private version;
|
|
9
10
|
private defaultFormats;
|
|
10
11
|
private timeout;
|
|
11
12
|
private logger;
|
|
@@ -7,8 +7,10 @@ export declare abstract class BaseReranker {
|
|
|
7
7
|
protected getDefaultRanking(documents: string[], topK: number): t.Highlight[];
|
|
8
8
|
}
|
|
9
9
|
export declare class JinaReranker extends BaseReranker {
|
|
10
|
-
|
|
10
|
+
private apiUrl;
|
|
11
|
+
constructor({ apiKey, apiUrl, logger, }: {
|
|
11
12
|
apiKey?: string;
|
|
13
|
+
apiUrl?: string;
|
|
12
14
|
logger?: t.Logger;
|
|
13
15
|
});
|
|
14
16
|
rerank(query: string, documents: string[], topK?: number): Promise<t.Highlight[]>;
|
|
@@ -30,6 +32,7 @@ export declare class InfinityReranker extends BaseReranker {
|
|
|
30
32
|
export declare const createReranker: (config: {
|
|
31
33
|
rerankerType: t.RerankerType;
|
|
32
34
|
jinaApiKey?: string;
|
|
35
|
+
jinaApiUrl?: string;
|
|
33
36
|
cohereApiKey?: string;
|
|
34
37
|
logger?: t.Logger;
|
|
35
38
|
}) => BaseReranker | undefined;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import type * as t from './types';
|
|
2
|
-
import { FirecrawlScraper } from './firecrawl';
|
|
3
2
|
export declare const createSearchAPI: (config: t.SearchConfig) => {
|
|
4
3
|
getSources: (params: t.GetSourcesParams) => Promise<t.SearchResult>;
|
|
5
4
|
};
|
|
6
|
-
export declare const createSourceProcessor: (config?: t.ProcessSourcesConfig, scraperInstance?:
|
|
5
|
+
export declare const createSourceProcessor: (config?: t.ProcessSourcesConfig, scraperInstance?: t.BaseScraper) => {
|
|
7
6
|
processSources: (fields: t.ProcessSourcesFields) => Promise<t.SearchResultData>;
|
|
8
7
|
topResults: number;
|
|
9
8
|
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type * as t from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Serper scraper implementation
|
|
4
|
+
* Uses the Serper Scrape API (https://scrape.serper.dev) to scrape web pages
|
|
5
|
+
*
|
|
6
|
+
* Features:
|
|
7
|
+
* - Simple API with single endpoint
|
|
8
|
+
* - Returns both text and markdown content
|
|
9
|
+
* - Includes metadata from scraped pages
|
|
10
|
+
* - Credits-based pricing model
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const scraper = createSerperScraper({
|
|
15
|
+
* apiKey: 'your-serper-api-key',
|
|
16
|
+
* includeMarkdown: true,
|
|
17
|
+
* timeout: 10000
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* const [url, response] = await scraper.scrapeUrl('https://example.com');
|
|
21
|
+
* if (response.success) {
|
|
22
|
+
* const [content] = scraper.extractContent(response);
|
|
23
|
+
* console.log(content);
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare class SerperScraper implements t.BaseScraper {
|
|
28
|
+
private apiKey;
|
|
29
|
+
private apiUrl;
|
|
30
|
+
private timeout;
|
|
31
|
+
private logger;
|
|
32
|
+
private includeMarkdown;
|
|
33
|
+
constructor(config?: t.SerperScraperConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Scrape a single URL
|
|
36
|
+
* @param url URL to scrape
|
|
37
|
+
* @param options Scrape options
|
|
38
|
+
* @returns Scrape response
|
|
39
|
+
*/
|
|
40
|
+
scrapeUrl(url: string, options?: t.SerperScrapeOptions): Promise<[string, t.SerperScrapeResponse]>;
|
|
41
|
+
/**
|
|
42
|
+
* Extract content from scrape response
|
|
43
|
+
* @param response Scrape response
|
|
44
|
+
* @returns Extracted content or empty string if not available
|
|
45
|
+
*/
|
|
46
|
+
extractContent(response: t.SerperScrapeResponse): [string, undefined | t.References];
|
|
47
|
+
/**
|
|
48
|
+
* Extract metadata from scrape response
|
|
49
|
+
* @param response Scrape response
|
|
50
|
+
* @returns Metadata object
|
|
51
|
+
*/
|
|
52
|
+
extractMetadata(response: t.SerperScrapeResponse): Record<string, string | number | boolean | null | undefined>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Create a Serper scraper instance
|
|
56
|
+
* @param config Scraper configuration
|
|
57
|
+
* @returns Serper scraper instance
|
|
58
|
+
*/
|
|
59
|
+
export declare const createSerperScraper: (config?: t.SerperScraperConfig) => SerperScraper;
|
|
@@ -6,6 +6,27 @@ import { DATE_RANGE } from './schema';
|
|
|
6
6
|
* Creates a search tool with a schema that dynamically includes the country field
|
|
7
7
|
* only when the searchProvider is 'serper'.
|
|
8
8
|
*
|
|
9
|
+
* Supports multiple scraper providers:
|
|
10
|
+
* - Firecrawl (default): Full-featured web scraping with multiple formats
|
|
11
|
+
* - Serper: Lightweight scraping using Serper's scrape API
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Using Firecrawl scraper (default)
|
|
16
|
+
* const searchTool = createSearchTool({
|
|
17
|
+
* searchProvider: 'serper',
|
|
18
|
+
* scraperProvider: 'firecrawl',
|
|
19
|
+
* firecrawlApiKey: 'your-firecrawl-key'
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* // Using Serper scraper
|
|
23
|
+
* const searchTool = createSearchTool({
|
|
24
|
+
* searchProvider: 'serper',
|
|
25
|
+
* scraperProvider: 'serper',
|
|
26
|
+
* serperApiKey: 'your-serper-key'
|
|
27
|
+
* });
|
|
28
|
+
* ```
|
|
29
|
+
*
|
|
9
30
|
* @param config - The search tool configuration
|
|
10
31
|
* @returns A DynamicStructuredTool with a schema that depends on the searchProvider
|
|
11
32
|
*/
|
|
@@ -18,16 +39,16 @@ export declare const createSearchTool: (config?: t.SearchToolConfig) => DynamicS
|
|
|
18
39
|
news: z.ZodOptional<z.ZodBoolean>;
|
|
19
40
|
}, "strip", z.ZodTypeAny, {
|
|
20
41
|
query: string;
|
|
21
|
-
date?: DATE_RANGE | undefined;
|
|
22
|
-
images?: boolean | undefined;
|
|
23
42
|
videos?: boolean | undefined;
|
|
43
|
+
images?: boolean | undefined;
|
|
24
44
|
news?: boolean | undefined;
|
|
45
|
+
date?: DATE_RANGE | undefined;
|
|
25
46
|
country?: unknown;
|
|
26
47
|
}, {
|
|
27
48
|
query: string;
|
|
28
|
-
date?: DATE_RANGE | undefined;
|
|
29
|
-
images?: boolean | undefined;
|
|
30
49
|
videos?: boolean | undefined;
|
|
50
|
+
images?: boolean | undefined;
|
|
31
51
|
news?: boolean | undefined;
|
|
52
|
+
date?: DATE_RANGE | undefined;
|
|
32
53
|
country?: unknown;
|
|
33
54
|
}>>;
|
|
@@ -4,6 +4,7 @@ import type { RunnableConfig } from '@langchain/core/runnables';
|
|
|
4
4
|
import type { BaseReranker } from './rerankers';
|
|
5
5
|
import { DATE_RANGE } from './schema';
|
|
6
6
|
export type SearchProvider = 'serper' | 'searxng';
|
|
7
|
+
export type ScraperProvider = 'firecrawl' | 'serper';
|
|
7
8
|
export type RerankerType = 'infinity' | 'jina' | 'cohere' | 'none';
|
|
8
9
|
export interface Highlight {
|
|
9
10
|
score: number;
|
|
@@ -85,8 +86,16 @@ export interface ProcessSourcesConfig {
|
|
|
85
86
|
export interface FirecrawlConfig {
|
|
86
87
|
firecrawlApiKey?: string;
|
|
87
88
|
firecrawlApiUrl?: string;
|
|
89
|
+
firecrawlVersion?: string;
|
|
88
90
|
firecrawlOptions?: FirecrawlScraperConfig;
|
|
89
91
|
}
|
|
92
|
+
export interface SerperScraperConfig {
|
|
93
|
+
apiKey?: string;
|
|
94
|
+
apiUrl?: string;
|
|
95
|
+
timeout?: number;
|
|
96
|
+
logger?: Logger;
|
|
97
|
+
includeMarkdown?: boolean;
|
|
98
|
+
}
|
|
90
99
|
export interface ScraperContentResult {
|
|
91
100
|
content: string;
|
|
92
101
|
}
|
|
@@ -130,9 +139,12 @@ export interface SearchToolConfig extends SearchConfig, ProcessSourcesConfig, Fi
|
|
|
130
139
|
logger?: Logger;
|
|
131
140
|
safeSearch?: SafeSearchLevel;
|
|
132
141
|
jinaApiKey?: string;
|
|
142
|
+
jinaApiUrl?: string;
|
|
133
143
|
cohereApiKey?: string;
|
|
134
144
|
rerankerType?: RerankerType;
|
|
145
|
+
scraperProvider?: ScraperProvider;
|
|
135
146
|
scraperTimeout?: number;
|
|
147
|
+
serperScraperOptions?: SerperScraperConfig;
|
|
136
148
|
onSearchResults?: (results: SearchResult, runnableConfig?: RunnableConfig) => void;
|
|
137
149
|
onGetHighlights?: (link: string) => void;
|
|
138
150
|
}
|
|
@@ -146,8 +158,15 @@ export type UsedReferences = {
|
|
|
146
158
|
originalIndex: number;
|
|
147
159
|
reference: MediaReference;
|
|
148
160
|
}[];
|
|
161
|
+
/** Base Scraper Interface */
|
|
162
|
+
export interface BaseScraper {
|
|
163
|
+
scrapeUrl(url: string, options?: unknown): Promise<[string, FirecrawlScrapeResponse | SerperScrapeResponse]>;
|
|
164
|
+
extractContent(response: FirecrawlScrapeResponse | SerperScrapeResponse): [string, undefined | References];
|
|
165
|
+
extractMetadata(response: FirecrawlScrapeResponse | SerperScrapeResponse): ScrapeMetadata | Record<string, string | number | boolean | null | undefined>;
|
|
166
|
+
}
|
|
149
167
|
/** Firecrawl */
|
|
150
|
-
export type FirecrawlScrapeOptions = Omit<FirecrawlScraperConfig, 'apiKey' | 'apiUrl' | 'logger'>;
|
|
168
|
+
export type FirecrawlScrapeOptions = Omit<FirecrawlScraperConfig, 'apiKey' | 'apiUrl' | 'version' | 'logger'>;
|
|
169
|
+
export type SerperScrapeOptions = Omit<SerperScraperConfig, 'apiKey' | 'apiUrl' | 'logger'>;
|
|
151
170
|
export interface ScrapeMetadata {
|
|
152
171
|
sourceURL?: string;
|
|
153
172
|
url?: string;
|
|
@@ -213,9 +232,20 @@ export interface FirecrawlScrapeResponse {
|
|
|
213
232
|
};
|
|
214
233
|
error?: string;
|
|
215
234
|
}
|
|
235
|
+
export interface SerperScrapeResponse {
|
|
236
|
+
success: boolean;
|
|
237
|
+
data?: {
|
|
238
|
+
text?: string;
|
|
239
|
+
markdown?: string;
|
|
240
|
+
metadata?: Record<string, string | number | boolean | null | undefined>;
|
|
241
|
+
credits?: number;
|
|
242
|
+
};
|
|
243
|
+
error?: string;
|
|
244
|
+
}
|
|
216
245
|
export interface FirecrawlScraperConfig {
|
|
217
246
|
apiKey?: string;
|
|
218
247
|
apiUrl?: string;
|
|
248
|
+
version?: string;
|
|
219
249
|
formats?: string[];
|
|
220
250
|
timeout?: number;
|
|
221
251
|
logger?: Logger;
|
|
@@ -218,7 +218,7 @@ export type GraphEdge = {
|
|
|
218
218
|
* For handoff edges: Description for the input parameter that the handoff tool accepts,
|
|
219
219
|
* allowing the supervisor to pass specific instructions/context to the transferred agent.
|
|
220
220
|
*/
|
|
221
|
-
prompt?: string | ((messages: BaseMessage[], runStartIndex: number) => string | undefined);
|
|
221
|
+
prompt?: string | ((messages: BaseMessage[], runStartIndex: number) => string | Promise<string> | undefined);
|
|
222
222
|
/**
|
|
223
223
|
* When true, excludes messages from startIndex when adding prompt.
|
|
224
224
|
* Automatically set to true when {results} variable is used in prompt.
|
|
@@ -246,4 +246,6 @@ export interface AgentInputs {
|
|
|
246
246
|
clientOptions?: ClientOptions;
|
|
247
247
|
additional_instructions?: string;
|
|
248
248
|
reasoningKey?: 'reasoning_content' | 'reasoning';
|
|
249
|
+
/** Format content blocks as strings (for legacy compatibility i.e. Ollama/Azure Serverless) */
|
|
250
|
+
useLegacyContent?: boolean;
|
|
249
251
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Agent Handler Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides a simple helper to create handlers with content aggregation for multi-agent scripts.
|
|
5
|
+
*
|
|
6
|
+
* Usage:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* const { contentParts, aggregateContent, handlers } = createHandlers();
|
|
9
|
+
*
|
|
10
|
+
* // With callbacks
|
|
11
|
+
* const { contentParts, aggregateContent, handlers } = createHandlers({
|
|
12
|
+
* onRunStep: (event, data) => console.log('Step:', data),
|
|
13
|
+
* onRunStepCompleted: (event, data) => console.log('Completed:', data)
|
|
14
|
+
* });
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
import { GraphEvents } from '@/common';
|
|
18
|
+
import { createContentAggregator } from '@/stream';
|
|
19
|
+
import type * as t from '@/types';
|
|
20
|
+
interface HandlerCallbacks {
|
|
21
|
+
onRunStep?: (event: GraphEvents.ON_RUN_STEP, data: t.StreamEventData) => void;
|
|
22
|
+
onRunStepCompleted?: (event: GraphEvents.ON_RUN_STEP_COMPLETED, data: t.StreamEventData) => void;
|
|
23
|
+
onRunStepDelta?: (event: GraphEvents.ON_RUN_STEP_DELTA, data: t.StreamEventData) => void;
|
|
24
|
+
onMessageDelta?: (event: GraphEvents.ON_MESSAGE_DELTA, data: t.StreamEventData) => void;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Creates handlers with content aggregation for multi-agent scripts
|
|
28
|
+
*/
|
|
29
|
+
export declare function createHandlers(callbacks?: HandlerCallbacks): {
|
|
30
|
+
contentParts: Array<t.MessageContentComplex | undefined>;
|
|
31
|
+
aggregateContent: ReturnType<typeof createContentAggregator>['aggregateContent'];
|
|
32
|
+
handlers: Record<string, t.EventHandler>;
|
|
33
|
+
};
|
|
34
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@librechat/agents",
|
|
3
|
-
"version": "3.0.00
|
|
3
|
+
"version": "3.0.00",
|
|
4
4
|
"main": "./dist/cjs/main.cjs",
|
|
5
5
|
"module": "./dist/esm/main.mjs",
|
|
6
6
|
"types": "./dist/types/index.d.ts",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"caching": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/caching.ts --name 'Jo' --location 'New York, NY'",
|
|
52
52
|
"thinking": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/thinking.ts --name 'Jo' --location 'New York, NY'",
|
|
53
53
|
"memory": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/memory.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
|
|
54
|
-
"tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider '
|
|
54
|
+
"tool-test": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/tools.ts --provider 'openrouter' --name 'Jo' --location 'New York, NY'",
|
|
55
55
|
"search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/search.ts --provider 'anthropic' --name 'Jo' --location 'New York, NY'",
|
|
56
56
|
"ant_web_search": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/ant_web_search.ts --name 'Jo' --location 'New York, NY'",
|
|
57
57
|
"abort": "node -r dotenv/config --loader ./tsconfig-paths-bootstrap.mjs --experimental-specifier-resolution=node ./src/scripts/abort.ts --provider 'openAI' --name 'Jo' --location 'New York, NY'",
|
|
@@ -105,6 +105,10 @@
|
|
|
105
105
|
"@langchain/ollama": "^0.2.3",
|
|
106
106
|
"@langchain/openai": "0.5.18",
|
|
107
107
|
"@langchain/xai": "^0.0.3",
|
|
108
|
+
"@langfuse/langchain": "^4.3.0",
|
|
109
|
+
"@langfuse/otel": "^4.3.0",
|
|
110
|
+
"@langfuse/tracing": "^4.3.0",
|
|
111
|
+
"@opentelemetry/sdk-node": "^0.207.0",
|
|
108
112
|
"cheerio": "^1.0.0",
|
|
109
113
|
"dotenv": "^16.4.7",
|
|
110
114
|
"https-proxy-agent": "^7.0.6",
|
|
@@ -37,6 +37,7 @@ export class AgentContext {
|
|
|
37
37
|
streamBuffer,
|
|
38
38
|
maxContextTokens,
|
|
39
39
|
reasoningKey,
|
|
40
|
+
useLegacyContent,
|
|
40
41
|
} = agentConfig;
|
|
41
42
|
|
|
42
43
|
const agentContext = new AgentContext({
|
|
@@ -53,6 +54,7 @@ export class AgentContext {
|
|
|
53
54
|
toolEnd,
|
|
54
55
|
instructionTokens: 0,
|
|
55
56
|
tokenCounter,
|
|
57
|
+
useLegacyContent,
|
|
56
58
|
});
|
|
57
59
|
|
|
58
60
|
if (tokenCounter) {
|
|
@@ -123,6 +125,8 @@ export class AgentContext {
|
|
|
123
125
|
>;
|
|
124
126
|
/** Promise for token calculation initialization */
|
|
125
127
|
tokenCalculationPromise?: Promise<void>;
|
|
128
|
+
/** Format content blocks as strings (for legacy compatibility) */
|
|
129
|
+
useLegacyContent: boolean = false;
|
|
126
130
|
|
|
127
131
|
constructor({
|
|
128
132
|
agentId,
|
|
@@ -138,6 +142,7 @@ export class AgentContext {
|
|
|
138
142
|
reasoningKey,
|
|
139
143
|
toolEnd,
|
|
140
144
|
instructionTokens,
|
|
145
|
+
useLegacyContent,
|
|
141
146
|
}: {
|
|
142
147
|
agentId: string;
|
|
143
148
|
provider: Providers;
|
|
@@ -152,6 +157,7 @@ export class AgentContext {
|
|
|
152
157
|
reasoningKey?: 'reasoning_content' | 'reasoning';
|
|
153
158
|
toolEnd?: boolean;
|
|
154
159
|
instructionTokens?: number;
|
|
160
|
+
useLegacyContent?: boolean;
|
|
155
161
|
}) {
|
|
156
162
|
this.agentId = agentId;
|
|
157
163
|
this.provider = provider;
|
|
@@ -173,6 +179,8 @@ export class AgentContext {
|
|
|
173
179
|
this.instructionTokens = instructionTokens;
|
|
174
180
|
}
|
|
175
181
|
|
|
182
|
+
this.useLegacyContent = useLegacyContent ?? false;
|
|
183
|
+
|
|
176
184
|
this.systemRunnable = this.createSystemRunnable();
|
|
177
185
|
}
|
|
178
186
|
|
package/src/graphs/Graph.ts
CHANGED
|
@@ -41,7 +41,9 @@ import {
|
|
|
41
41
|
convertMessagesToContent,
|
|
42
42
|
modifyDeltaProperties,
|
|
43
43
|
formatArtifactPayload,
|
|
44
|
+
formatContentStrings,
|
|
44
45
|
createPruneMessages,
|
|
46
|
+
addCacheControl,
|
|
45
47
|
} from '@/messages';
|
|
46
48
|
import {
|
|
47
49
|
resetIfNotEmpty,
|
|
@@ -299,6 +301,8 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
299
301
|
agentContext.currentTokenType === 'think_and_text'
|
|
300
302
|
) {
|
|
301
303
|
keyList.push('reasoning');
|
|
304
|
+
} else if (agentContext.tokenTypeSwitch === 'content') {
|
|
305
|
+
keyList.push('post-reasoning');
|
|
302
306
|
}
|
|
303
307
|
|
|
304
308
|
if (this.invokedToolIds != null && this.invokedToolIds.size > 0) {
|
|
@@ -580,7 +584,12 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
580
584
|
null) ||
|
|
581
585
|
(agentContext.provider === Providers.BEDROCK &&
|
|
582
586
|
(agentContext.clientOptions as t.BedrockAnthropicInput)
|
|
583
|
-
.additionalModelRequestFields?.['thinking'] != null)
|
|
587
|
+
.additionalModelRequestFields?.['thinking'] != null) ||
|
|
588
|
+
(agentContext.provider === Providers.OPENAI &&
|
|
589
|
+
(
|
|
590
|
+
(agentContext.clientOptions as t.OpenAIClientOptions).modelKwargs
|
|
591
|
+
?.thinking as t.AnthropicClientOptions['thinking']
|
|
592
|
+
)?.type === 'enabled');
|
|
584
593
|
|
|
585
594
|
agentContext.pruneMessages = createPruneMessages({
|
|
586
595
|
startIndex: this.startIndex,
|
|
@@ -601,7 +610,11 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
601
610
|
messagesToUse = context;
|
|
602
611
|
}
|
|
603
612
|
|
|
604
|
-
|
|
613
|
+
let finalMessages = messagesToUse;
|
|
614
|
+
if (agentContext.useLegacyContent) {
|
|
615
|
+
finalMessages = formatContentStrings(finalMessages);
|
|
616
|
+
}
|
|
617
|
+
|
|
605
618
|
const lastMessageX =
|
|
606
619
|
finalMessages.length >= 2
|
|
607
620
|
? finalMessages[finalMessages.length - 2]
|
|
@@ -635,6 +648,22 @@ export class StandardGraph extends Graph<t.BaseGraphState, t.GraphNode> {
|
|
|
635
648
|
formatArtifactPayload(finalMessages);
|
|
636
649
|
}
|
|
637
650
|
|
|
651
|
+
if (agentContext.provider === Providers.ANTHROPIC) {
|
|
652
|
+
const anthropicOptions = agentContext.clientOptions as
|
|
653
|
+
| t.AnthropicClientOptions
|
|
654
|
+
| undefined;
|
|
655
|
+
const defaultHeaders = anthropicOptions?.clientOptions
|
|
656
|
+
?.defaultHeaders as Record<string, string> | undefined;
|
|
657
|
+
const anthropicBeta = defaultHeaders?.['anthropic-beta'];
|
|
658
|
+
|
|
659
|
+
if (
|
|
660
|
+
typeof anthropicBeta === 'string' &&
|
|
661
|
+
anthropicBeta.includes('prompt-caching')
|
|
662
|
+
) {
|
|
663
|
+
finalMessages = addCacheControl<BaseMessage>(finalMessages);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
638
667
|
if (
|
|
639
668
|
agentContext.lastStreamCall != null &&
|
|
640
669
|
agentContext.streamBuffer != null
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { tool } from '@langchain/core/tools';
|
|
3
|
+
import { PromptTemplate } from '@langchain/core/prompts';
|
|
3
4
|
import {
|
|
4
5
|
ToolMessage,
|
|
5
6
|
HumanMessage,
|
|
6
7
|
getBufferString,
|
|
7
8
|
} from '@langchain/core/messages';
|
|
8
|
-
import { ChatPromptTemplate } from '@langchain/core/prompts';
|
|
9
9
|
import {
|
|
10
10
|
END,
|
|
11
11
|
START,
|
|
@@ -508,16 +508,16 @@ export class MultiAgentGraph extends StandardGraph {
|
|
|
508
508
|
let effectiveExcludeResults = excludeResults;
|
|
509
509
|
|
|
510
510
|
if (typeof prompt === 'function') {
|
|
511
|
-
promptText = prompt(state.messages, this.startIndex);
|
|
511
|
+
promptText = await prompt(state.messages, this.startIndex);
|
|
512
512
|
} else if (prompt != null) {
|
|
513
513
|
if (prompt.includes('{results}')) {
|
|
514
514
|
const resultsMessages = state.messages.slice(this.startIndex);
|
|
515
515
|
const resultsString = getBufferString(resultsMessages);
|
|
516
|
-
const promptTemplate =
|
|
517
|
-
const
|
|
516
|
+
const promptTemplate = PromptTemplate.fromTemplate(prompt);
|
|
517
|
+
const result = await promptTemplate.invoke({
|
|
518
518
|
results: resultsString,
|
|
519
519
|
});
|
|
520
|
-
promptText =
|
|
520
|
+
promptText = result.value;
|
|
521
521
|
effectiveExcludeResults =
|
|
522
522
|
excludeResults !== false && promptText !== '';
|
|
523
523
|
} else {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
2
|
+
import { LangfuseSpanProcessor } from '@langfuse/otel';
|
|
3
|
+
import { isPresent } from '@/utils/misc';
|
|
4
|
+
|
|
5
|
+
if (
|
|
6
|
+
isPresent(process.env.LANGFUSE_SECRET_KEY) &&
|
|
7
|
+
isPresent(process.env.LANGFUSE_PUBLIC_KEY) &&
|
|
8
|
+
isPresent(process.env.LANGFUSE_BASE_URL)
|
|
9
|
+
) {
|
|
10
|
+
const langfuseSpanProcessor = new LangfuseSpanProcessor({
|
|
11
|
+
publicKey: process.env.LANGFUSE_PUBLIC_KEY,
|
|
12
|
+
secretKey: process.env.LANGFUSE_SECRET_KEY,
|
|
13
|
+
baseUrl: process.env.LANGFUSE_BASE_URL,
|
|
14
|
+
environment: process.env.NODE_ENV ?? 'development',
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const sdk = new NodeSDK({
|
|
18
|
+
spanProcessors: [langfuseSpanProcessor],
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
sdk.start();
|
|
22
|
+
}
|