Skip to content

Commit c3fa01b

Browse files
committed
fix(core): duplicate static tools provided to llm
1 parent 9fed94c commit c3fa01b

File tree

2 files changed

+46
-10
lines changed

2 files changed

+46
-10
lines changed

packages/core/src/agent/agent.spec-d.ts

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1091,7 +1091,44 @@ describe("Agent Type System", () => {
10911091
});
10921092

10931093
// Agent should accept complex tools
1094-
expectTypeOf(agent).toHaveProperty("tools");
1094+
expect(agent.getTools()).toHaveLength(1);
1095+
expect(agent.dynamicTools).toBeUndefined();
1096+
});
1097+
1098+
it("should work with dynamic tools", () => {
1099+
const complexTool = new Tool({
1100+
name: "analyzer",
1101+
description: "Analyze data",
1102+
parameters: z.object({
1103+
data: z.array(
1104+
z.object({
1105+
id: z.number(),
1106+
value: z.string(),
1107+
metadata: z.record(z.unknown()).optional(),
1108+
}),
1109+
),
1110+
options: z.object({
1111+
format: z.enum(["json", "csv", "xml"]),
1112+
includeHeaders: z.boolean().default(true),
1113+
}),
1114+
}),
1115+
execute: async (params) => ({
1116+
result: `Analyzed ${params.data.length} items`,
1117+
format: params.options.format,
1118+
}),
1119+
});
1120+
1121+
const toolsFn = async () => [complexTool];
1122+
const agent = new Agent({
1123+
name: "Test",
1124+
instructions: "Test",
1125+
model: mockModel,
1126+
tools: toolsFn,
1127+
});
1128+
1129+
// Agent should accept dynamic tools function
1130+
expect(agent.getTools()).toHaveLength(0);
1131+
expect(agent.dynamicTools).toBe(toolsFn);
10951132
});
10961133

10971134
it("should handle tool execution context types", async () => {

packages/core/src/agent/agent.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ export class Agent {
244244
readonly purpose?: string;
245245
readonly instructions: InstructionsDynamicValue;
246246
readonly model: LanguageModel | DynamicValue<LanguageModel>;
247-
readonly tools: (Tool<any, any> | Toolkit)[] | DynamicValue<(Tool<any, any> | Toolkit)[]>;
247+
readonly dynamicTools?: DynamicValue<(Tool<any, any> | Toolkit)[]>;
248248
readonly hooks: AgentHooks;
249249
readonly temperature?: number;
250250
readonly maxOutputTokens?: number;
@@ -271,7 +271,7 @@ export class Agent {
271271
this.purpose = options.purpose;
272272
this.instructions = options.instructions;
273273
this.model = options.model;
274-
this.tools = options.tools || [];
274+
this.dynamicTools = typeof options.tools === "function" ? options.tools : undefined;
275275
this.hooks = options.hooks || {};
276276
this.temperature = options.temperature;
277277
this.maxOutputTokens = options.maxOutputTokens;
@@ -312,7 +312,7 @@ export class Agent {
312312
this.memoryManager = new MemoryManager(this.id, this.memory, {}, this.logger);
313313

314314
// Initialize tool manager with static tools
315-
const staticTools = typeof this.tools === "function" ? [] : this.tools || [];
315+
const staticTools = typeof options.tools === "function" ? [] : options.tools;
316316
this.toolManager = new ToolManager(staticTools, this.logger);
317317
if (options.toolkits) {
318318
this.toolManager.addItems(options.toolkits);
@@ -1278,10 +1278,6 @@ export class Agent {
12781278
tools: Record<string, any>;
12791279
maxSteps: number;
12801280
}> {
1281-
// Resolve dynamic values
1282-
const model = await this.resolveValue(this.model, oc);
1283-
const agentToolList = await this.resolveValue(this.tools, oc);
1284-
12851281
// Prepare messages (system + memory + input) as UIMessages
12861282
const buffer = this.getConversationBuffer(oc);
12871283
const uiMessages = await this.prepareMessages(input, oc, options, buffer);
@@ -1304,10 +1300,13 @@ export class Agent {
13041300
// Calculate maxSteps (use provided option or calculate based on subagents)
13051301
const maxSteps = options?.maxSteps ?? this.calculateMaxSteps();
13061302

1303+
// Resolve dynamic values
1304+
const model = await this.resolveValue(this.model, oc);
1305+
const dynamicToolList = (await this.resolveValue(this.dynamicTools, oc)) || [];
1306+
13071307
// Merge agent tools with option tools
1308-
const agentToolsArray = Array.isArray(agentToolList) ? agentToolList : [];
13091308
const optionToolsArray = options?.tools || [];
1310-
const mergedTools = [...agentToolsArray, ...optionToolsArray];
1309+
const mergedTools = [...dynamicToolList, ...optionToolsArray];
13111310

13121311
// Prepare tools with execution context
13131312
const tools = await this.prepareTools(mergedTools, oc, maxSteps, options);

0 commit comments

Comments
 (0)