@librechat/agents 3.7.19 → 3.7.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/dist/cjs/llm/openai/index.cjs +110 -24
  2. package/dist/cjs/llm/openai/index.cjs.map +1 -1
  3. package/dist/cjs/main.cjs +1 -0
  4. package/dist/cjs/tools/BashExecutor.cjs +3 -2
  5. package/dist/cjs/tools/BashExecutor.cjs.map +1 -1
  6. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs +2 -1
  7. package/dist/cjs/tools/BashProgrammaticToolCalling.cjs.map +1 -1
  8. package/dist/cjs/tools/CodeExecutor.cjs +27 -10
  9. package/dist/cjs/tools/CodeExecutor.cjs.map +1 -1
  10. package/dist/cjs/tools/ProgrammaticToolCalling.cjs +6 -5
  11. package/dist/cjs/tools/ProgrammaticToolCalling.cjs.map +1 -1
  12. package/dist/cjs/tools/diagnostics.cjs +26 -0
  13. package/dist/cjs/tools/diagnostics.cjs.map +1 -0
  14. package/dist/cjs/tools/search/format.cjs +7 -0
  15. package/dist/cjs/tools/search/format.cjs.map +1 -1
  16. package/dist/cjs/tools/search/rerankers.cjs +6 -4
  17. package/dist/cjs/tools/search/rerankers.cjs.map +1 -1
  18. package/dist/cjs/tools/search/search.cjs +14 -2
  19. package/dist/cjs/tools/search/search.cjs.map +1 -1
  20. package/dist/cjs/tools/search/tool.cjs +8 -3
  21. package/dist/cjs/tools/search/tool.cjs.map +1 -1
  22. package/dist/esm/llm/openai/index.mjs +110 -25
  23. package/dist/esm/llm/openai/index.mjs.map +1 -1
  24. package/dist/esm/main.mjs +2 -2
  25. package/dist/esm/tools/BashExecutor.mjs +3 -2
  26. package/dist/esm/tools/BashExecutor.mjs.map +1 -1
  27. package/dist/esm/tools/BashProgrammaticToolCalling.mjs +2 -1
  28. package/dist/esm/tools/BashProgrammaticToolCalling.mjs.map +1 -1
  29. package/dist/esm/tools/CodeExecutor.mjs +27 -10
  30. package/dist/esm/tools/CodeExecutor.mjs.map +1 -1
  31. package/dist/esm/tools/ProgrammaticToolCalling.mjs +6 -5
  32. package/dist/esm/tools/ProgrammaticToolCalling.mjs.map +1 -1
  33. package/dist/esm/tools/diagnostics.mjs +25 -0
  34. package/dist/esm/tools/diagnostics.mjs.map +1 -0
  35. package/dist/esm/tools/search/format.mjs +7 -1
  36. package/dist/esm/tools/search/format.mjs.map +1 -1
  37. package/dist/esm/tools/search/rerankers.mjs +6 -5
  38. package/dist/esm/tools/search/rerankers.mjs.map +1 -1
  39. package/dist/esm/tools/search/search.mjs +14 -2
  40. package/dist/esm/tools/search/search.mjs.map +1 -1
  41. package/dist/esm/tools/search/tool.mjs +8 -4
  42. package/dist/esm/tools/search/tool.mjs.map +1 -1
  43. package/dist/types/llm/openai/index.d.ts +11 -1
  44. package/dist/types/tools/CodeExecutor.d.ts +13 -2
  45. package/dist/types/tools/diagnostics.d.ts +52 -0
  46. package/dist/types/tools/search/format.d.ts +2 -1
  47. package/dist/types/tools/search/rerankers.d.ts +10 -0
  48. package/dist/types/tools/search/tool.d.ts +1 -0
  49. package/dist/types/types/llm.d.ts +23 -0
  50. package/package.json +4 -2
  51. package/src/llm/openai/index.ts +281 -27
  52. package/src/tools/BashExecutor.ts +9 -4
  53. package/src/tools/BashProgrammaticToolCalling.ts +6 -3
  54. package/src/tools/CodeExecutor.ts +88 -15
  55. package/src/tools/ProgrammaticToolCalling.ts +24 -12
  56. package/src/tools/diagnostics.ts +107 -0
  57. package/src/tools/search/format.ts +15 -1
  58. package/src/tools/search/rerankers.ts +18 -3
  59. package/src/tools/search/search.ts +30 -5
  60. package/src/tools/search/tool.ts +13 -3
  61. package/src/types/llm.ts +23 -0
@@ -19,6 +19,7 @@ type OpenAICoreRequestOptions = OpenAIClient.RequestOptions;
19
19
  type OpenAICompletionParam = OpenAIClient.Chat.Completions.ChatCompletionMessageParam;
20
20
  type LibreChatOpenAIFields = t.ChatOpenAIFields & {
21
21
  _lc_stream_delay?: number;
22
+ firstPartyEndpoint?: boolean;
22
23
  includeReasoningContent?: boolean;
23
24
  includeReasoningDetails?: boolean;
24
25
  convertReasoningDetailsToContent?: boolean;
@@ -30,6 +31,7 @@ type LibreChatOpenAIFields = t.ChatOpenAIFields & {
30
31
  };
31
32
  type LibreChatAzureOpenAIFields = t.AzureOpenAIInput & {
32
33
  _lc_stream_delay?: number;
34
+ firstPartyEndpoint?: boolean;
33
35
  promptCacheExplicit?: boolean;
34
36
  safety_identifier?: string;
35
37
  };
@@ -38,10 +40,12 @@ export declare function addChatCacheBreakpoints(messages: OpenAIClient.Chat.Comp
38
40
  /** @internal */
39
41
  export declare function addResponseCacheBreakpoints(input: OpenAIClient.Responses.ResponseCreateParams['input']): OpenAIClient.Responses.ResponseCreateParams['input'];
40
42
  /** @internal */
43
+ export declare function isGpt6AstraModel(model?: string): boolean;
44
+ /** @internal */
41
45
  export declare function shouldIncludeEncryptedReasoning(model: string, params: {
42
46
  store?: boolean | null;
43
47
  reasoning?: unknown;
44
- }): boolean;
48
+ }, astraRulesApply?: boolean): boolean;
45
49
  export declare function getCacheWriteTokens(message: BaseMessage): number | undefined;
46
50
  export declare function attachCacheWriteUsage(message: BaseMessage): void;
47
51
  export declare function attachCacheWriteMetadata(response: OpenAIClient.Responses.Response): OpenAIClient.Responses.Response;
@@ -97,6 +101,9 @@ export declare class CustomAzureOpenAIClient extends AzureOpenAIClient {
97
101
  fetchWithTimeout(url: RequestInfo, init: RequestInit | undefined, ms: number, controller: AbortController): Promise<Response>;
98
102
  }
99
103
  export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptions> {
104
+ protected firstPartyEndpoint?: boolean;
105
+ /** @see {@link astraRulesApply} */
106
+ protected get astraRulesApply(): boolean;
100
107
  _lc_stream_delay: number;
101
108
  constructor(fields?: LibreChatOpenAIFields & t.OpenAIChatInput['modelKwargs']);
102
109
  get exposedClient(): CustomOpenAIClient;
@@ -117,6 +124,9 @@ export declare class ChatOpenAI extends OriginalChatOpenAI<t.ChatOpenAICallOptio
117
124
  protected _streamRawResponseChunks(messages: BaseMessage[], options: this['ParsedCallOptions'], runManager?: CallbackManagerForLLMRun): AsyncGenerator<ChatGenerationChunk>;
118
125
  }
119
126
  export declare class AzureChatOpenAI extends OriginalAzureChatOpenAI {
127
+ protected firstPartyEndpoint?: boolean;
128
+ /** @see {@link astraRulesApply} */
129
+ protected get astraRulesApply(): boolean;
120
130
  _lc_stream_delay: number;
121
131
  constructor(fields?: LibreChatAzureOpenAIFields);
122
132
  get exposedClient(): CustomOpenAIClient;
@@ -1,4 +1,5 @@
1
1
  import { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import type { CodeApiMethod } from '@/tools/diagnostics';
2
3
  import type * as t from '@/types';
3
4
  import { Constants } from '@/common';
4
5
  export { appendCodeSessionFileSummary, stripCodeSessionFileSummary, } from '@/tools/CodeSessionFileSummary';
@@ -57,11 +58,21 @@ export declare function buildCodeApiExecutionErrorMessage(response: {
57
58
  error?: unknown;
58
59
  stderr?: unknown;
59
60
  }): string;
60
- export declare function resolveCodeApiAuthHeaders(authHeaders?: t.CodeApiAuthHeaders): Promise<t.CodeApiAuthHeaderMap>;
61
+ export declare function resolveCodeApiAuthHeaders(authHeaders?: t.CodeApiAuthHeaders, options?: {
62
+ recoverable?: boolean;
63
+ }): Promise<t.CodeApiAuthHeaderMap>;
61
64
  export declare function addCodeApiExecutionProfileHeader(headers: t.CodeApiAuthHeaderMap, executionProfile?: t.CodeApiExecutionProfile): t.CodeApiAuthHeaderMap;
62
- export declare function buildCodeApiHttpErrorMessage(_method: string, _endpoint: string, response: {
65
+ type CodeApiErrorResponse = {
63
66
  status: number;
64
67
  text: () => Promise<string>;
68
+ /** node-fetch types this as `NodeJS.ReadableStream`, which does not declare
69
+ * `destroy`; every runtime instance is a `Readable`, and a test double may
70
+ * supply nothing at all. */
71
+ body?: NodeJS.ReadableStream | null;
72
+ };
73
+ export declare function buildCodeApiHttpErrorMessage(method: CodeApiMethod, _endpoint: string, response: CodeApiErrorResponse, options?: {
74
+ recoverable?: boolean;
75
+ profile?: t.CodeApiExecutionProfile;
65
76
  }): Promise<string>;
66
77
  export declare const CodeExecutionToolDescription: string;
67
78
  /**
@@ -0,0 +1,52 @@
1
+ import type * as t from '@/types';
2
+ /**
3
+ * Operator diagnostics for the Code API tools.
4
+ *
5
+ * Every failure these tools surface to the model is reduced to a fixed
6
+ * sentence, so this log is the only surviving account of what went wrong —
7
+ * which also makes it the one place a credential can escape by accident. It
8
+ * escaped repeatedly while any field was quoted from something the tools did
9
+ * not produce: a response body echoing the header that was sent, an error
10
+ * message quoting an excerpt of a malformed signing key, a `stack` whose first
11
+ * line is that message, a writable `name`, a configured base URL carrying a
12
+ * capability in its path or its authority.
13
+ *
14
+ * Filtering those carriers case by case never converged, because the shape of
15
+ * a credential inside free text is not decidable. The rule here is structural
16
+ * instead: a diagnostic NAMES what happened using values this module owns, and
17
+ * QUOTES nothing it received. `CodeApiDiagnosticDetail` is a closed union of
18
+ * such values, so host-authored text cannot reach a log without failing to
19
+ * compile — and adding a field means widening that union in this file, which
20
+ * is the point at which the question gets asked.
21
+ */
22
+ export type CodeApiMethod = 'GET' | 'POST';
23
+ type CodeApiProfileLabel = t.CodeApiExecutionProfile | 'unset';
24
+ /** Built-in error types, the `typeof` results for a non-Error rejection, and
25
+ * the two labels this module supplies when neither applies. */
26
+ type CodeApiErrorLabel = 'SyntaxError' | 'TypeError' | 'RangeError' | 'ReferenceError' | 'URIError' | 'EvalError' | 'Error' | 'UndescribableError' | 'string' | 'number' | 'bigint' | 'boolean' | 'symbol' | 'undefined' | 'object' | 'function';
27
+ export type CodeApiDiagnosticDetail = {
28
+ type: CodeApiErrorLabel;
29
+ } | {
30
+ method: CodeApiMethod;
31
+ profile: CodeApiProfileLabel;
32
+ status: number;
33
+ } | {
34
+ files: 'none';
35
+ };
36
+ /**
37
+ * Classifies a rejection without reading anything off it. `instanceof` walks
38
+ * the prototype chain, so an accessor trap is never reached; the guard covers
39
+ * a `getPrototypeOf` trap, which would otherwise cost both the log and the
40
+ * rejection.
41
+ */
42
+ export declare function describeCodeApiError(error: unknown): {
43
+ type: CodeApiErrorLabel;
44
+ };
45
+ type CodeApiDiagnosticSource = 'CodeExecutor' | 'BashExecutor' | 'ProgrammaticToolCalling' | 'BashProgrammaticToolCalling';
46
+ /**
47
+ * Console is the SDK's diagnostic channel; a winston logger is the host's
48
+ * concern. Hosts correlate these lines with their own request-scoped logs,
49
+ * which is where received identifiers such as a session id belong.
50
+ */
51
+ export declare function logCodeApiDiagnostic(source: CodeApiDiagnosticSource, level: 'debug' | 'warn' | 'error', message: string, detail: CodeApiDiagnosticDetail): void;
52
+ export {};
@@ -1,8 +1,9 @@
1
1
  import type * as t from './types';
2
+ export declare const MISSING_SEARCH_RESULT_DATA_ERROR = "Search provider returned no result data";
2
3
  /** Resolves the per-search highlight budget from config, the
3
4
  * `SEARCH_MAX_LLM_OUTPUT_CHARS` env var, or the default (50,000 chars). */
4
5
  export declare function resolveMaxLLMOutputChars(maxOutputChars?: number): number;
5
- export declare function formatResultsForLLM(turn: number, results: t.SearchResultData, maxOutputChars?: number): {
6
+ export declare function formatResultsForLLM(turn: number, results?: t.SearchResultData | null, maxOutputChars?: number): {
6
7
  output: string;
7
8
  references: t.ResultReference[];
8
9
  };
@@ -1,4 +1,14 @@
1
1
  import type * as t from './types';
2
+ /**
3
+ * Ranking used whenever no reranker scores the chunks: the candidates' own
4
+ * order, capped at `topK`, with a neutral score.
5
+ *
6
+ * Exported because it is not only a *fallback*. With `rerankerType: 'none'`
7
+ * there is no reranker to fall back from, and the search pipeline needs the
8
+ * same ranking to hand the scraped text downstream — see `getHighlights` in
9
+ * `./search`.
10
+ */
11
+ export declare const getDefaultRanking: (documents: string[], topK: number) => t.Highlight[];
2
12
  export declare abstract class BaseReranker {
3
13
  protected apiKey: string | undefined;
4
14
  protected logger: t.Logger;
@@ -20,6 +20,7 @@ import { createSearchAPI } from './search';
20
20
  * model-authored intent to stand unchanged as the label.
21
21
  */
22
22
  export declare function resolveSearchOutcome(data: t.SearchResultData, query: string): string | undefined;
23
+ export declare function normalizeSearchResultData(result: t.SearchResultData | null | undefined): t.SearchResultData;
23
24
  /**
24
25
  * Executes parallel searches and merges the results,
25
26
  * deduplicating top stories by link
@@ -58,6 +58,29 @@ export type GoogleThinkingConfig = {
58
58
  export type ManagedRequestOptions = {
59
59
  promptCacheExplicit?: boolean;
60
60
  safety_identifier?: string;
61
+ /**
62
+ * Declares that this client talks to the first-party OpenAI or Azure surface.
63
+ * Gates the model-specific request *shaping* documented only for it —
64
+ * currently GPT-6 Astra's rejected sampling and logprob parameters, its
65
+ * unsupported reasoning efforts, and the encrypted reasoning it supports —
66
+ * and defaults to off.
67
+ *
68
+ * Shaping only. Which API serves the turn is not decided here: GPT-6 Astra
69
+ * serves tool calls only from the Responses API, and a caller wanting them
70
+ * must select it with `useResponsesApi`, alongside the rest of the request
71
+ * shaping that depends on which API is in use.
72
+ *
73
+ * The shaping runs inside this SDK's own request delegates. A caller that
74
+ * supplies its own `completions` or `responses` delegate replaces that
75
+ * construction and owns the request shaping for it — this flag cannot reach
76
+ * inside a delegate it did not build.
77
+ *
78
+ * Declared rather than inferred from a base URL: only the caller knows
79
+ * whether a URL is a faithful first-party route, a gateway, or a proxy with
80
+ * its own semantics, and every gate it controls removes capability, so
81
+ * guessing wrong silently degrades an endpoint the SDK cannot see.
82
+ */
83
+ firstPartyEndpoint?: boolean;
61
84
  };
62
85
  /**
63
86
  * Adaptive stream-smoothing configuration shared by every provider client.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@librechat/agents",
3
- "version": "3.7.19",
3
+ "version": "3.7.21",
4
4
  "reova": {
5
5
  "enabled": true,
6
6
  "endpoint": "https://telemetry.reo.dev/data"
@@ -266,6 +266,7 @@
266
266
  "script5": "tsx -r dotenv/config ./src/scripts/cli5.ts --name 'Jo' --location 'New York, NY'",
267
267
  "test": "NODE_OPTIONS='--experimental-vm-modules' jest",
268
268
  "test:live:handoffs": "RUN_HANDOFF_LIVE_TESTS=1 NODE_OPTIONS='--experimental-vm-modules' jest src/specs/agent-handoffs.live.test.ts --runInBand",
269
+ "test:live:cross-provider-attachments": "RUN_CROSS_PROVIDER_ATTACHMENT_LIVE_TESTS=1 NODE_OPTIONS='--experimental-vm-modules' jest src/specs/cross-provider-attachments.live.test.ts --runInBand",
269
270
  "test:live:ask-user-questions": "RUN_ASK_USER_QUESTIONS_LIVE_TESTS=1 NODE_OPTIONS='--experimental-vm-modules' jest src/specs/ask-user-questions.live.test.ts --runInBand",
270
271
  "test:memory": "NODE_OPTIONS='--expose-gc' npx jest src/specs/title.memory-leak.test.ts",
271
272
  "test:all": "npm test -- --testPathIgnorePatterns=title.memory-leak.test.ts && npm run test:memory",
@@ -279,6 +280,7 @@
279
280
  },
280
281
  "overrides": {
281
282
  "@langchain/openai": "$@langchain/openai",
283
+ "@langchain/langgraph-checkpoint": "^1.1.5",
282
284
  "@browserbasehq/stagehand": {
283
285
  "openai": "$openai"
284
286
  },
@@ -338,7 +340,7 @@
338
340
  "@anthropic-ai/sandbox-runtime": "^0.0.67",
339
341
  "@anthropic-ai/vertex-sdk": "^0.12.0",
340
342
  "@eslint/js": "^10.0.1",
341
- "@langchain/langgraph-checkpoint-mongodb": "^1.4.0",
343
+ "@langchain/langgraph-checkpoint-mongodb": "^1.4.1",
342
344
  "@swc/core": "^1.6.13",
343
345
  "@types/jest": "^30.0.0",
344
346
  "@types/node": "^24.13.1",