@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.
Files changed (105) hide show
  1. package/dist/cjs/agents/AgentContext.cjs +25 -8
  2. package/dist/cjs/agents/AgentContext.cjs.map +1 -1
  3. package/dist/cjs/graphs/Graph.cjs +7 -4
  4. package/dist/cjs/graphs/Graph.cjs.map +1 -1
  5. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs +4 -3
  6. package/dist/cjs/hooks/createWorkspacePolicyHook.cjs.map +1 -1
  7. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs +20 -4
  8. package/dist/cjs/llm/anthropic/utils/message_inputs.cjs.map +1 -1
  9. package/dist/cjs/llm/bedrock/index.cjs +7 -1
  10. package/dist/cjs/llm/bedrock/index.cjs.map +1 -1
  11. package/dist/cjs/llm/bedrock/toolCache.cjs +5 -4
  12. package/dist/cjs/llm/bedrock/toolCache.cjs.map +1 -1
  13. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs +34 -17
  14. package/dist/cjs/llm/bedrock/utils/message_inputs.cjs.map +1 -1
  15. package/dist/cjs/llm/openrouter/index.cjs +1 -0
  16. package/dist/cjs/llm/openrouter/index.cjs.map +1 -1
  17. package/dist/cjs/llm/openrouter/toolCache.cjs +18 -5
  18. package/dist/cjs/llm/openrouter/toolCache.cjs.map +1 -1
  19. package/dist/cjs/main.cjs +4 -0
  20. package/dist/cjs/messages/anthropicToolCache.cjs +75 -13
  21. package/dist/cjs/messages/anthropicToolCache.cjs.map +1 -1
  22. package/dist/cjs/messages/cache.cjs +91 -35
  23. package/dist/cjs/messages/cache.cjs.map +1 -1
  24. package/dist/cjs/summarization/node.cjs +3 -2
  25. package/dist/cjs/summarization/node.cjs.map +1 -1
  26. package/dist/cjs/tools/ReadFile.cjs +2 -2
  27. package/dist/cjs/tools/ReadFile.cjs.map +1 -1
  28. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs +11 -11
  29. package/dist/cjs/tools/cloudflare/CloudflareProgrammaticToolCalling.cjs.map +1 -1
  30. package/dist/cjs/tools/local/LocalCodingTools.cjs +11 -11
  31. package/dist/cjs/tools/local/LocalCodingTools.cjs.map +1 -1
  32. package/dist/esm/agents/AgentContext.mjs +26 -9
  33. package/dist/esm/agents/AgentContext.mjs.map +1 -1
  34. package/dist/esm/graphs/Graph.mjs +8 -5
  35. package/dist/esm/graphs/Graph.mjs.map +1 -1
  36. package/dist/esm/hooks/createWorkspacePolicyHook.mjs +4 -3
  37. package/dist/esm/hooks/createWorkspacePolicyHook.mjs.map +1 -1
  38. package/dist/esm/llm/anthropic/utils/message_inputs.mjs +20 -4
  39. package/dist/esm/llm/anthropic/utils/message_inputs.mjs.map +1 -1
  40. package/dist/esm/llm/bedrock/index.mjs +7 -1
  41. package/dist/esm/llm/bedrock/index.mjs.map +1 -1
  42. package/dist/esm/llm/bedrock/toolCache.mjs +5 -4
  43. package/dist/esm/llm/bedrock/toolCache.mjs.map +1 -1
  44. package/dist/esm/llm/bedrock/utils/message_inputs.mjs +34 -17
  45. package/dist/esm/llm/bedrock/utils/message_inputs.mjs.map +1 -1
  46. package/dist/esm/llm/openrouter/index.mjs +1 -0
  47. package/dist/esm/llm/openrouter/index.mjs.map +1 -1
  48. package/dist/esm/llm/openrouter/toolCache.mjs +18 -5
  49. package/dist/esm/llm/openrouter/toolCache.mjs.map +1 -1
  50. package/dist/esm/main.mjs +2 -2
  51. package/dist/esm/messages/anthropicToolCache.mjs +75 -13
  52. package/dist/esm/messages/anthropicToolCache.mjs.map +1 -1
  53. package/dist/esm/messages/cache.mjs +88 -36
  54. package/dist/esm/messages/cache.mjs.map +1 -1
  55. package/dist/esm/summarization/node.mjs +4 -3
  56. package/dist/esm/summarization/node.mjs.map +1 -1
  57. package/dist/esm/tools/ReadFile.mjs +2 -2
  58. package/dist/esm/tools/ReadFile.mjs.map +1 -1
  59. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs +11 -11
  60. package/dist/esm/tools/cloudflare/CloudflareProgrammaticToolCalling.mjs.map +1 -1
  61. package/dist/esm/tools/local/LocalCodingTools.mjs +11 -11
  62. package/dist/esm/tools/local/LocalCodingTools.mjs.map +1 -1
  63. package/dist/types/agents/AgentContext.d.ts +11 -0
  64. package/dist/types/agents/__tests__/promptCacheLiveHelpers.d.ts +2 -0
  65. package/dist/types/llm/bedrock/index.d.ts +13 -0
  66. package/dist/types/llm/bedrock/toolCache.d.ts +2 -1
  67. package/dist/types/llm/openrouter/index.d.ts +8 -0
  68. package/dist/types/llm/openrouter/toolCache.d.ts +2 -1
  69. package/dist/types/messages/anthropicToolCache.d.ts +2 -1
  70. package/dist/types/messages/cache.d.ts +49 -5
  71. package/dist/types/tools/ReadFile.d.ts +4 -4
  72. package/dist/types/types/llm.d.ts +14 -0
  73. package/package.json +1 -1
  74. package/src/agents/AgentContext.ts +64 -17
  75. package/src/agents/__tests__/AgentContext.anthropic.live.test.ts +6 -2
  76. package/src/agents/__tests__/AgentContext.bedrock.live.test.ts +7 -5
  77. package/src/agents/__tests__/AgentContext.openrouter.live.test.ts +1 -1
  78. package/src/agents/__tests__/AgentContext.test.ts +31 -19
  79. package/src/agents/__tests__/promptCacheLiveHelpers.ts +6 -2
  80. package/src/graphs/Graph.ts +40 -4
  81. package/src/hooks/__tests__/createWorkspacePolicyHook.test.ts +12 -12
  82. package/src/hooks/createWorkspacePolicyHook.ts +7 -6
  83. package/src/llm/anthropic/utils/message_inputs.ts +33 -6
  84. package/src/llm/bedrock/index.ts +21 -1
  85. package/src/llm/bedrock/llm.spec.ts +61 -0
  86. package/src/llm/bedrock/toolCache.test.ts +24 -0
  87. package/src/llm/bedrock/toolCache.ts +12 -7
  88. package/src/llm/bedrock/utils/message_inputs.ts +57 -40
  89. package/src/llm/openrouter/index.ts +9 -0
  90. package/src/llm/openrouter/toolCache.test.ts +52 -1
  91. package/src/llm/openrouter/toolCache.ts +40 -6
  92. package/src/messages/__tests__/anthropicToolCache.test.ts +168 -0
  93. package/src/messages/anthropicToolCache.ts +118 -15
  94. package/src/messages/cache.test.ts +175 -0
  95. package/src/messages/cache.ts +133 -48
  96. package/src/summarization/node.ts +21 -2
  97. package/src/tools/ReadFile.ts +2 -2
  98. package/src/tools/__tests__/LocalExecutionTools.test.ts +25 -25
  99. package/src/tools/__tests__/ProgrammaticToolCalling.test.ts +5 -5
  100. package/src/tools/__tests__/ReadFile.test.ts +3 -3
  101. package/src/tools/__tests__/ToolNode.session.test.ts +2 -2
  102. package/src/tools/__tests__/workspaceSeam.test.ts +2 -2
  103. package/src/tools/cloudflare/CloudflareProgrammaticToolCalling.ts +11 -11
  104. package/src/tools/local/LocalCodingTools.ts +14 -14
  105. 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: { file_path: 'note.md', content: 'hi\n' },
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: { file_path: 'note.md' },
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(file_path, offset=None, limit=None):
482
- resolved = _resolve(file_path)
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(file_path, content):
486
+ async def write_file(path, content):
487
487
  _assert_writable("write_file")
488
- resolved = _resolve(file_path)
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(file_path, old_text=None, new_text=None, edits=None):
495
+ async def edit_file(path, old_text=None, new_text=None, edits=None):
496
496
  _assert_writable("edit_file")
497
- resolved = _resolve(file_path)
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 {file_path}")
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.file_path);
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.file_path);
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.file_path);
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.file_path);
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
- file_path: {
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: ['file_path'],
66
+ required: ['path'],
67
67
  };
68
68
 
69
69
  export const LocalWriteFileToolSchema: t.JsonSchemaType = {
70
70
  type: 'object',
71
71
  properties: {
72
- file_path: {
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: ['file_path', 'content'],
82
+ required: ['path', 'content'],
83
83
  };
84
84
 
85
85
  export const LocalEditFileToolSchema: t.JsonSchemaType = {
86
86
  type: 'object',
87
87
  properties: {
88
- file_path: {
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: ['file_path'],
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
- file_path: string;
394
+ path: string;
395
395
  offset?: number;
396
396
  limit?: number;
397
397
  };
398
398
  const path = await resolveWorkspacePathSafe(
399
- input.file_path,
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.file_path}`);
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 { file_path: string; content: string };
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.file_path,
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
- file_path: string;
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.file_path,
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.file_path}. ` +
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;