@librechat/agents 3.2.38 → 3.2.41
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 +25 -8
- package/dist/cjs/agents/AgentContext.cjs.map +1 -1
- package/dist/cjs/graphs/Graph.cjs +7 -4
- package/dist/cjs/graphs/Graph.cjs.map +1 -1
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +4 -3
- package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +20 -4
- package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/index.cjs +7 -1
- package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/toolCache.cjs +5 -4
- package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +34 -17
- package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/index.cjs +1 -0
- package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
- package/dist/cjs/llm/openrouter/toolCache.cjs +18 -5
- package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
- package/dist/cjs/main.cjs +4 -0
- package/dist/cjs/messages/anthropicToolCache.cjs +75 -13
- package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
- package/dist/cjs/messages/cache.cjs +91 -35
- package/dist/cjs/messages/cache.cjs.map +1 -1
- package/dist/cjs/summarization/node.cjs +3 -2
- package/dist/cjs/summarization/node.cjs.map +1 -1
- package/dist/cjs/tools/ReadFile.cjs +2 -2
- package/dist/cjs/tools/ReadFile.cjs.map +1 -1
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +11 -11
- package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
- package/dist/cjs/tools/local/LocalCodingTools.cjs +11 -11
- package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
- package/dist/esm/agents/AgentContext.mjs +26 -9
- package/dist/esm/agents/AgentContext.mjs.map +1 -1
- package/dist/esm/graphs/Graph.mjs +8 -5
- package/dist/esm/graphs/Graph.mjs.map +1 -1
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs +4 -3
- package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs +20 -4
- package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/bedrock/index.mjs +7 -1
- package/dist/esm/llm/bedrock/index.mjs.map +1 -1
- package/dist/esm/llm/bedrock/toolCache.mjs +5 -4
- package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs +34 -17
- package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
- package/dist/esm/llm/openrouter/index.mjs +1 -0
- package/dist/esm/llm/openrouter/index.mjs.map +1 -1
- package/dist/esm/llm/openrouter/toolCache.mjs +18 -5
- package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
- package/dist/esm/main.mjs +2 -2
- package/dist/esm/messages/anthropicToolCache.mjs +75 -13
- package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
- package/dist/esm/messages/cache.mjs +88 -36
- package/dist/esm/messages/cache.mjs.map +1 -1
- package/dist/esm/summarization/node.mjs +4 -3
- package/dist/esm/summarization/node.mjs.map +1 -1
- package/dist/esm/tools/ReadFile.mjs +2 -2
- package/dist/esm/tools/ReadFile.mjs.map +1 -1
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +11 -11
- package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
- package/dist/esm/tools/local/LocalCodingTools.mjs +11 -11
- package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
- package/dist/types/agents/AgentContext.d.ts +11 -0
- package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +2 -0
- package/dist/types/llm/bedrock/index.d.ts +13 -0
- package/dist/types/llm/bedrock/toolCache.d.ts +2 -1
- package/dist/types/llm/openrouter/index.d.ts +8 -0
- package/dist/types/llm/openrouter/toolCache.d.ts +2 -1
- package/dist/types/messages/anthropicToolCache.d.ts +2 -1
- package/dist/types/messages/cache.d.ts +49 -5
- package/dist/types/tools/ReadFile.d.ts +4 -4
- package/dist/types/types/llm.d.ts +14 -0
- package/package.json +1 -1
- package/src/agents/AgentContext.ts +64 -17
- package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +6 -2
- package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +7 -5
- package/src/agents/__tests__/AgentContext.openrouter.live.test.ts +1 -1
- package/src/agents/__tests__/AgentContext.test.ts +31 -19
- package/src/agents/__tests__/promptCacheLiveHelpers.ts +6 -2
- package/src/graphs/Graph.ts +40 -4
- package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +12 -12
- package/src/hooks/createWorkspacePolicyHook.ts +7 -6
- package/src/llm/anthropic/utils/message_inputs.ts +33 -6
- package/src/llm/bedrock/index.ts +21 -1
- package/src/llm/bedrock/llm.spec.ts +61 -0
- package/src/llm/bedrock/toolCache.test.ts +24 -0
- package/src/llm/bedrock/toolCache.ts +12 -7
- package/src/llm/bedrock/utils/message_inputs.ts +57 -40
- package/src/llm/openrouter/index.ts +9 -0
- package/src/llm/openrouter/toolCache.test.ts +52 -1
- package/src/llm/openrouter/toolCache.ts +40 -6
- package/src/messages/__tests__/anthropicToolCache.test.ts +168 -0
- package/src/messages/anthropicToolCache.ts +118 -15
- package/src/messages/cache.test.ts +175 -0
- package/src/messages/cache.ts +133 -48
- package/src/summarization/node.ts +21 -2
- package/src/tools/ReadFile.ts +2 -2
- package/src/tools/__tests__/LocalExecutionTools.test.ts +25 -25
- package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +5 -5
- package/src/tools/__tests__/ReadFile.test.ts +3 -3
- package/src/tools/__tests__/ToolNode.session.test.ts +2 -2
- package/src/tools/__tests__/workspaceSeam.test.ts +2 -2
- package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +11 -11
- package/src/tools/local/LocalCodingTools.ts +14 -14
- package/src/types/llm.ts +14 -0
|
@@ -125,7 +125,7 @@ describe('workspace seam', () => {
|
|
|
125
125
|
await writeTool.invoke({
|
|
126
126
|
id: 'c1',
|
|
127
127
|
name: 'write_file',
|
|
128
|
-
args: {
|
|
128
|
+
args: { path: 'note.md', content: 'hi\n' },
|
|
129
129
|
type: 'tool_call',
|
|
130
130
|
});
|
|
131
131
|
expect(tracked.writeFile).toHaveBeenCalled();
|
|
@@ -137,7 +137,7 @@ describe('workspace seam', () => {
|
|
|
137
137
|
await readTool.invoke({
|
|
138
138
|
id: 'c2',
|
|
139
139
|
name: Constants.READ_FILE,
|
|
140
|
-
args: {
|
|
140
|
+
args: { path: 'note.md' },
|
|
141
141
|
type: 'tool_call',
|
|
142
142
|
});
|
|
143
143
|
expect(tracked.stat).toHaveBeenCalled();
|
|
@@ -478,30 +478,30 @@ async def execute_code(lang, code, args=None):
|
|
|
478
478
|
finally:
|
|
479
479
|
shutil.rmtree(temp_dir, ignore_errors=True)
|
|
480
480
|
|
|
481
|
-
async def read_file(
|
|
482
|
-
resolved = _resolve(
|
|
481
|
+
async def read_file(path, offset=None, limit=None):
|
|
482
|
+
resolved = _resolve(path)
|
|
483
483
|
with open(resolved, encoding="utf-8") as handle:
|
|
484
484
|
return _line_window(handle.read(), offset, limit)
|
|
485
485
|
|
|
486
|
-
async def write_file(
|
|
486
|
+
async def write_file(path, content):
|
|
487
487
|
_assert_writable("write_file")
|
|
488
|
-
resolved = _resolve(
|
|
488
|
+
resolved = _resolve(path)
|
|
489
489
|
os.makedirs(os.path.dirname(resolved), exist_ok=True)
|
|
490
490
|
existed = os.path.exists(resolved)
|
|
491
491
|
with open(resolved, "w", encoding="utf-8") as handle:
|
|
492
492
|
handle.write(content)
|
|
493
493
|
return f"{'Overwrote' if existed else 'Created'} {resolved} ({len(content)} chars)."
|
|
494
494
|
|
|
495
|
-
async def edit_file(
|
|
495
|
+
async def edit_file(path, old_text=None, new_text=None, edits=None):
|
|
496
496
|
_assert_writable("edit_file")
|
|
497
|
-
resolved = _resolve(
|
|
497
|
+
resolved = _resolve(path)
|
|
498
498
|
edits = edits or [{"old_text": old_text, "new_text": new_text}]
|
|
499
499
|
content = open(resolved, encoding="utf-8").read()
|
|
500
500
|
for edit in edits:
|
|
501
501
|
old = edit.get("old_text") or ""
|
|
502
502
|
new = edit.get("new_text") or ""
|
|
503
503
|
if content.count(old) != 1:
|
|
504
|
-
raise ValueError(f"Could not locate old_text exactly once in {
|
|
504
|
+
raise ValueError(f"Could not locate old_text exactly once in {path}")
|
|
505
505
|
content = content.replace(old, new, 1)
|
|
506
506
|
open(resolved, "w", encoding="utf-8").write(content)
|
|
507
507
|
return f"Applied {len(edits)} edit(s) to {resolved}."
|
|
@@ -881,13 +881,13 @@ async function execute_code(payload) {
|
|
|
881
881
|
}
|
|
882
882
|
|
|
883
883
|
async function read_file(payload) {
|
|
884
|
-
const resolved = resolvePath(payload.
|
|
884
|
+
const resolved = resolvePath(payload.path);
|
|
885
885
|
return lineWindow(await fsp.readFile(resolved, "utf8"), payload.offset, payload.limit);
|
|
886
886
|
}
|
|
887
887
|
|
|
888
888
|
async function write_file(payload) {
|
|
889
889
|
assertWritable("write_file");
|
|
890
|
-
const resolved = resolvePath(payload.
|
|
890
|
+
const resolved = resolvePath(payload.path);
|
|
891
891
|
await fsp.mkdir(path.dirname(resolved), { recursive: true });
|
|
892
892
|
const existed = fs.existsSync(resolved);
|
|
893
893
|
await fsp.writeFile(resolved, payload.content, "utf8");
|
|
@@ -896,14 +896,14 @@ async function write_file(payload) {
|
|
|
896
896
|
|
|
897
897
|
async function edit_file(payload) {
|
|
898
898
|
assertWritable("edit_file");
|
|
899
|
-
const resolved = resolvePath(payload.
|
|
899
|
+
const resolved = resolvePath(payload.path);
|
|
900
900
|
const edits = payload.edits || [{ old_text: payload.old_text, new_text: payload.new_text }];
|
|
901
901
|
let content = await fsp.readFile(resolved, "utf8");
|
|
902
902
|
for (const edit of edits) {
|
|
903
903
|
const oldText = edit.old_text || "";
|
|
904
904
|
const newText = edit.new_text || "";
|
|
905
905
|
if (oldText === "" || content.split(oldText).length - 1 !== 1) {
|
|
906
|
-
throw new Error("Could not locate old_text exactly once in " + payload.
|
|
906
|
+
throw new Error("Could not locate old_text exactly once in " + payload.path);
|
|
907
907
|
}
|
|
908
908
|
content = content.replace(oldText, newText);
|
|
909
909
|
}
|
|
@@ -49,7 +49,7 @@ export const LocalListDirectoryToolName = Constants.LIST_DIRECTORY;
|
|
|
49
49
|
export const LocalReadFileToolSchema: t.JsonSchemaType = {
|
|
50
50
|
type: 'object',
|
|
51
51
|
properties: {
|
|
52
|
-
|
|
52
|
+
path: {
|
|
53
53
|
type: 'string',
|
|
54
54
|
description:
|
|
55
55
|
'Path to a local file, relative to the configured cwd unless absolute paths are allowed.',
|
|
@@ -63,13 +63,13 @@ export const LocalReadFileToolSchema: t.JsonSchemaType = {
|
|
|
63
63
|
description: 'Optional maximum number of lines to return.',
|
|
64
64
|
},
|
|
65
65
|
},
|
|
66
|
-
required: ['
|
|
66
|
+
required: ['path'],
|
|
67
67
|
};
|
|
68
68
|
|
|
69
69
|
export const LocalWriteFileToolSchema: t.JsonSchemaType = {
|
|
70
70
|
type: 'object',
|
|
71
71
|
properties: {
|
|
72
|
-
|
|
72
|
+
path: {
|
|
73
73
|
type: 'string',
|
|
74
74
|
description:
|
|
75
75
|
'Path to write, relative to the configured cwd unless absolute paths are allowed.',
|
|
@@ -79,13 +79,13 @@ export const LocalWriteFileToolSchema: t.JsonSchemaType = {
|
|
|
79
79
|
description: 'Complete file contents to write.',
|
|
80
80
|
},
|
|
81
81
|
},
|
|
82
|
-
required: ['
|
|
82
|
+
required: ['path', 'content'],
|
|
83
83
|
};
|
|
84
84
|
|
|
85
85
|
export const LocalEditFileToolSchema: t.JsonSchemaType = {
|
|
86
86
|
type: 'object',
|
|
87
87
|
properties: {
|
|
88
|
-
|
|
88
|
+
path: {
|
|
89
89
|
type: 'string',
|
|
90
90
|
description:
|
|
91
91
|
'Path to edit, relative to the configured cwd unless absolute paths are allowed.',
|
|
@@ -112,7 +112,7 @@ export const LocalEditFileToolSchema: t.JsonSchemaType = {
|
|
|
112
112
|
},
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
|
-
required: ['
|
|
115
|
+
required: ['path'],
|
|
116
116
|
};
|
|
117
117
|
|
|
118
118
|
export const LocalGrepSearchToolSchema: t.JsonSchemaType = {
|
|
@@ -391,18 +391,18 @@ export function createLocalReadFileTool(
|
|
|
391
391
|
return tool(
|
|
392
392
|
async (rawInput) => {
|
|
393
393
|
const input = rawInput as {
|
|
394
|
-
|
|
394
|
+
path: string;
|
|
395
395
|
offset?: number;
|
|
396
396
|
limit?: number;
|
|
397
397
|
};
|
|
398
398
|
const path = await resolveWorkspacePathSafe(
|
|
399
|
-
input.
|
|
399
|
+
input.path,
|
|
400
400
|
config,
|
|
401
401
|
'read'
|
|
402
402
|
);
|
|
403
403
|
const fileStat = await fs.stat(path);
|
|
404
404
|
if (!fileStat.isFile()) {
|
|
405
|
-
throw new Error(`Path is not a file: ${input.
|
|
405
|
+
throw new Error(`Path is not a file: ${input.path}`);
|
|
406
406
|
}
|
|
407
407
|
const maxBytes = Math.max(
|
|
408
408
|
config.maxReadBytes ?? DEFAULT_MAX_READ_BYTES,
|
|
@@ -514,12 +514,12 @@ export function createLocalWriteFileTool(
|
|
|
514
514
|
const fs = getWorkspaceFS(config);
|
|
515
515
|
return tool(
|
|
516
516
|
async (rawInput) => {
|
|
517
|
-
const input = rawInput as {
|
|
517
|
+
const input = rawInput as { path: string; content: string };
|
|
518
518
|
if (config.readOnly === true) {
|
|
519
519
|
throw new Error('write_file is blocked in read-only local mode.');
|
|
520
520
|
}
|
|
521
521
|
const path = await resolveWorkspacePathSafe(
|
|
522
|
-
input.
|
|
522
|
+
input.path,
|
|
523
523
|
config,
|
|
524
524
|
'write'
|
|
525
525
|
);
|
|
@@ -598,7 +598,7 @@ export function createLocalEditFileTool(
|
|
|
598
598
|
return tool(
|
|
599
599
|
async (rawInput) => {
|
|
600
600
|
const input = rawInput as {
|
|
601
|
-
|
|
601
|
+
path: string;
|
|
602
602
|
old_text?: string;
|
|
603
603
|
new_text?: string;
|
|
604
604
|
edits?: Array<{ old_text?: string; new_text?: string }>;
|
|
@@ -612,7 +612,7 @@ export function createLocalEditFileTool(
|
|
|
612
612
|
}
|
|
613
613
|
|
|
614
614
|
const path = await resolveWorkspacePathSafe(
|
|
615
|
-
input.
|
|
615
|
+
input.path,
|
|
616
616
|
config,
|
|
617
617
|
'write'
|
|
618
618
|
);
|
|
@@ -627,7 +627,7 @@ export function createLocalEditFileTool(
|
|
|
627
627
|
const match = locateEdit(next, edit.oldText);
|
|
628
628
|
if (match == null) {
|
|
629
629
|
throw new Error(
|
|
630
|
-
`Edit ${i + 1}/${edits.length}: could not locate old_text in ${input.
|
|
630
|
+
`Edit ${i + 1}/${edits.length}: could not locate old_text in ${input.path}. ` +
|
|
631
631
|
'Tried exact, line-trimmed, whitespace-normalized, and indentation-flexible matching. ' +
|
|
632
632
|
'Re-read the file and copy the literal lines.'
|
|
633
633
|
);
|
package/src/types/llm.ts
CHANGED
|
@@ -22,6 +22,7 @@ import type { Runnable } from '@langchain/core/runnables';
|
|
|
22
22
|
import type { OpenAI as OpenAIClient } from 'openai';
|
|
23
23
|
import type { ChatXAIInput } from '@langchain/xai';
|
|
24
24
|
import type { ChatOpenRouterCallOptions } from '@/llm/openrouter';
|
|
25
|
+
import type { PromptCacheTtl } from '@/messages/cache';
|
|
25
26
|
import {
|
|
26
27
|
AzureChatOpenAI,
|
|
27
28
|
ChatDeepSeek,
|
|
@@ -76,6 +77,12 @@ export type OpenAIClientOptions = ChatOpenAIFields;
|
|
|
76
77
|
export type AnthropicClientOptions = Omit<AnthropicInput, 'thinking'> & {
|
|
77
78
|
thinking?: ThinkingConfig;
|
|
78
79
|
promptCache?: boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Prompt-cache breakpoint TTL. Defaults to `'1h'` (extended cache) when
|
|
82
|
+
* `promptCache` is enabled; set `'5m'` to opt back into the legacy
|
|
83
|
+
* 5-minute behavior.
|
|
84
|
+
*/
|
|
85
|
+
promptCacheTtl?: PromptCacheTtl;
|
|
79
86
|
};
|
|
80
87
|
export type MistralAIClientOptions = ChatMistralAIInput;
|
|
81
88
|
export type VertexAIClientOptions = ChatVertexAIInput & {
|
|
@@ -86,6 +93,13 @@ export type BedrockAnthropicInput = ChatBedrockConverseInput & {
|
|
|
86
93
|
additionalModelRequestFields?: ChatBedrockConverseInput['additionalModelRequestFields'] &
|
|
87
94
|
AnthropicReasoning;
|
|
88
95
|
promptCache?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Prompt-cache checkpoint TTL. Defaults to `'1h'` (extended cache) when
|
|
98
|
+
* `promptCache` is enabled; set `'5m'` to opt into the legacy 5-minute
|
|
99
|
+
* behavior. Bedrock models that don't support the 1-hour TTL downgrade to 5m
|
|
100
|
+
* server-side, so the default is safe to leave on.
|
|
101
|
+
*/
|
|
102
|
+
promptCacheTtl?: PromptCacheTtl;
|
|
89
103
|
};
|
|
90
104
|
export type BedrockConverseClientOptions = BedrockAnthropicInput;
|
|
91
105
|
export type BedrockAnthropicClientOptions = BedrockAnthropicInput;
|