Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,7 @@ export interface Tool {
type: "function";
function: {
name: string;
type?: string;
description?: string;
parameters?: Record<string, any>;
strict?: boolean | null;
Expand Down
34 changes: 26 additions & 8 deletions core/llm/llms/Bedrock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -281,21 +281,31 @@ class Bedrock extends BaseLLM {
let toolConfig: undefined | ToolConfiguration = undefined;
const availableTools = new Set<string>();
if (supportsTools && options.tools && options.tools.length > 0) {
toolConfig = {
tools: options.tools.map((tool) => ({
const isClaudeModel = options.model.includes("claude");

// For Claude models, filter out tools with a type property
// For other models, include all tools
const toolSpecs = options.tools
.filter((tool) => !isClaudeModel || !tool.function.type)
.map((tool) => ({
toolSpec: {
name: tool.function.name,
description: tool.function.description,
inputSchema: {
json: tool.function.parameters,
},
},
})),
} as ToolConfiguration;
const shouldCacheToolsConfig = this.completionOptions.promptCaching;
if (shouldCacheToolsConfig) {
toolConfig.tools!.push({ cachePoint: { type: "default" } });
}));

if (toolSpecs.length > 0) {
toolConfig = { tools: toolSpecs } as ToolConfiguration;
const shouldCacheToolsConfig = this.completionOptions.promptCaching;
if (shouldCacheToolsConfig) {
toolConfig.tools!.push({ cachePoint: { type: "default" } });
}
}

// Add all tool names to availableTools set
options.tools.forEach((tool) => {
availableTools.add(tool.function.name);
});
Expand Down Expand Up @@ -329,14 +339,22 @@ class Bedrock extends BaseLLM {
.slice(0, 4),
},
additionalModelRequestFields: {
tools: options.model.includes("claude") && options.tools
? options.tools
.filter((tool) => tool.function.type)
.map((tool) => ({
name: tool.function.name,
type: tool.function.type,
}))
: undefined,
thinking: options.reasoning
? {
type: "enabled",
budget_tokens: options.reasoningBudgetTokens,
}
: undefined,
anthropic_beta: options.model.includes("claude")
? ["fine-grained-tool-streaming-2025-05-14"]
? ["fine-grained-tool-streaming-2025-05-14","context-management-2025-06-27"]
: undefined,
},
};
Expand Down
1 change: 1 addition & 0 deletions core/tools/builtIn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export enum BuiltInToolNames {
RequestRule = "request_rule",
FetchUrlContent = "fetch_url_content",
CodebaseTool = "codebase",
Memory = "memory",

// excluded from allTools for now
ViewRepoMap = "view_repo_map",
Expand Down
3 changes: 3 additions & 0 deletions core/tools/callTool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { searchWebImpl } from "./implementations/searchWeb";
import { viewDiffImpl } from "./implementations/viewDiff";
import { viewRepoMapImpl } from "./implementations/viewRepoMap";
import { viewSubdirectoryImpl } from "./implementations/viewSubdirectory";
import { memoryToolImpl } from "./implementations/memory";
import { safeParseToolCallArgs } from "./parseArgs";

async function callHttpTool(
Expand Down Expand Up @@ -166,6 +167,8 @@ export async function callBuiltInTool(
return await searchWebImpl(args, extras);
case BuiltInToolNames.FetchUrlContent:
return await fetchUrlContentImpl(args, extras);
case BuiltInToolNames.Memory:
return await memoryToolImpl(args, extras);
case BuiltInToolNames.ViewDiff:
return await viewDiffImpl(args, extras);
case BuiltInToolNames.LSTool:
Expand Down
1 change: 1 addition & 0 deletions core/tools/definitions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { globSearchTool } from "./globSearch";
export { grepSearchTool } from "./grepSearch";
export { lsTool } from "./ls";
export { multiEditTool } from "./multiEdit";
export { memoryTool } from "./memory";
export { readCurrentlyOpenFileTool } from "./readCurrentlyOpenFile";
export { readFileTool } from "./readFile";

Expand Down
92 changes: 92 additions & 0 deletions core/tools/definitions/memory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { Tool } from "../..";
import { BUILT_IN_GROUP_NAME, BuiltInToolNames } from "../builtIn";

const COMMAND_OPTIONS = [
"view",
"create",
"insert",
"str_replace",
"delete",
"rename",
];

export const memoryTool: Tool = {
type: "function",
displayTitle: "Memory",
wouldLikeTo:
"manage persistent memories using the {{{ command }}} command at {{{ path }}}",
isCurrently:
"managing persistent memories using the {{{ command }}} command at {{{ path }}}",
hasAlready:
"managed persistent memories using the {{{ command }}} command at {{{ path }}}",
readonly: false,
group: BUILT_IN_GROUP_NAME,
function: {
name: BuiltInToolNames.Memory,
type: "memory_20250818",
description: "Anthropic claude memory tool",
parameters: {
type: "object",
required: ["command"],
properties: {
command: {
type: "string",
enum: COMMAND_OPTIONS,
description:
"The memory operation to perform: view, create, insert, str_replace, delete, or rename.",
},
path: {
type: "string",
description:
"Path within the /memories namespace targeted by the command. Must begin with /memories.",
},
view_range: {
type: "array",
description:
"Optional [start, end] line range (1-indexed, inclusive) when viewing a memory file. Use -1 for end to read to EOF.",
items: { type: "number" },
},
file_text: {
type: "string",
description: "Content to write when creating a new memory file.",
},
insert_line: {
type: "number",
description:
"0-based line number where insert_text should be added when using the insert command.",
},
insert_text: {
type: "string",
description: "Text to insert when using the insert command.",
},
old_str: {
type: "string",
description:
"Existing text to replace when using the str_replace command. Must appear exactly once.",
},
new_str: {
type: "string",
description:
"Replacement text to use when the str_replace command is invoked.",
},
old_path: {
type: "string",
description: "Existing path to rename when using the rename command.",
},
new_path: {
type: "string",
description: "New path to rename to when using the rename command.",
},
},
},
},
systemMessageDescription: {
prefix: `To manage long-term memories stored under /memories, use the ${BuiltInToolNames.Memory} tool. Always provide a command (view, create, insert, str_replace, delete, or rename) and paths that begin with /memories. For example, to view the index file you could respond with:`,
exampleArgs: [
["command", "view"],
["path", "/memories/index.md"],
],
},
defaultToolPolicy: "allowedWithoutPermission",
toolCallIcon: "ArchiveBoxIcon",
};
Loading
Loading