Skip to content

Commit 680b529

Browse files
chore: remove requireContext from tools (#1949)
1 parent 389acbd commit 680b529

File tree

5 files changed

+53
-74
lines changed

5 files changed

+53
-74
lines changed

.changeset/chatty-numbers-attack.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@llamaindex/workflow": patch
3+
"@llamaindex/core": patch
4+
---
5+
6+
Remove requireContext from tools - better use binding to pass context

examples/agents/agent/multiple-agents.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ async function multiWeatherAgent() {
9292
agentInputEvent.include(event) ||
9393
stopAgentEvent.include(event)
9494
) {
95-
console.log(event);
95+
console.log(event.data);
9696
} else if (agentStreamEvent.include(event)) {
9797
for (const chunk of event.data.delta) {
9898
process.stdout.write(chunk);

packages/core/src/llms/type.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,6 @@ export type ToolMetadata<
256256
* @link https://json-schema.org/understanding-json-schema
257257
*/
258258
parameters?: Parameters;
259-
/**
260-
* Whether the tool requires workflow context to be passed in.
261-
*/
262-
requireContext?: boolean;
263259
};
264260

265261
/**

packages/core/src/tools/function-tool.ts

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -134,32 +134,16 @@ export class FunctionTool<
134134
};
135135

136136
call = (input: T) => {
137-
if (this.#metadata.requireContext) {
138-
const inputWithContext = input as Record<string, unknown>;
139-
if (!inputWithContext.context) {
140-
throw new Error(
141-
"Tool call requires context, but context parameter is missing",
142-
);
143-
}
144-
}
137+
let params = input;
145138
if (this.#zodType) {
146139
const result = this.#zodType.safeParse(input);
147140
if (result.success) {
148-
if (this.#metadata.requireContext) {
149-
const { context } = input as Record<string, unknown>;
150-
return this.#fn.call(
151-
null,
152-
{ context, ...result.data },
153-
this.#additionalArg,
154-
);
155-
} else {
156-
return this.#fn.call(null, result.data, this.#additionalArg);
157-
}
141+
params = result.data;
158142
} else {
159143
console.warn(result.error.errors);
160144
}
161145
}
162-
return this.#fn.call(null, input, this.#additionalArg);
146+
return this.#fn.call(null, params, this.#additionalArg);
163147
};
164148
}
165149

packages/workflow/src/agent/agent-workflow.ts

Lines changed: 43 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import { Settings } from "@llamaindex/core/global";
1313
import type { ChatMessage, MessageContent } from "@llamaindex/core/llms";
1414
import { ChatMemoryBuffer } from "@llamaindex/core/memory";
1515
import { PromptTemplate } from "@llamaindex/core/prompts";
16-
import { FunctionTool } from "@llamaindex/core/tools";
16+
import { tool } from "@llamaindex/core/tools";
1717
import { stringifyJSONToMessageContent } from "@llamaindex/core/utils";
1818
import { z } from "zod";
1919
import type { AgentWorkflowState, BaseWorkflowAgent } from "./base";
@@ -244,7 +244,7 @@ export class AgentWorkflow implements Workflow {
244244
agent.canHandoffTo.forEach((name) => {
245245
toHandoffAgents.set(name, this.agents.get(name)!);
246246
});
247-
const handoffTool = createHandoffTool(toHandoffAgents);
247+
const handoffTool = this.createHandoffTool(toHandoffAgents);
248248
if (
249249
agent.canHandoffTo.length > 0 &&
250250
!agent.tools.some((t) => t.metadata.name === handoffTool.metadata.name)
@@ -558,15 +558,7 @@ export class AgentWorkflow implements Workflow {
558558
if (!tool) {
559559
throw new Error(`Tool ${toolCall.toolName} not found`);
560560
}
561-
if (tool.metadata.requireContext) {
562-
const input = {
563-
context: this.stateful.getContext().state,
564-
...toolCall.toolKwargs,
565-
};
566-
return tool.call(input);
567-
} else {
568-
return tool.call(toolCall.toolKwargs);
569-
}
561+
return tool.call(toolCall.toolKwargs);
570562
}
571563

572564
private createInitialState(): AgentWorkflowState {
@@ -620,42 +612,16 @@ export class AgentWorkflow implements Workflow {
620612
}
621613
return finalEvent;
622614
}
623-
}
624615

625-
const createHandoffTool = (agents: Map<string, BaseWorkflowAgent>) => {
626-
const agentInfo = Array.from(agents.values()).reduce(
627-
(acc, a) => {
628-
acc[a.name] = a.description;
629-
return acc;
630-
},
631-
{} as Record<string, string>,
632-
);
633-
return FunctionTool.from(
634-
({
635-
context,
636-
toAgent,
637-
reason,
638-
}: {
639-
context?: AgentWorkflowState;
640-
toAgent: string;
641-
reason: string;
642-
}) => {
643-
if (!context) {
644-
throw new Error("Context is required for handoff");
645-
}
646-
const agents = context.agents;
647-
if (!agents.includes(toAgent)) {
648-
return `Agent ${toAgent} not found. Select a valid agent to hand off to. Valid agents: ${agents.join(
649-
", ",
650-
)}`;
651-
}
652-
context.nextAgentName = toAgent;
653-
return DEFAULT_HANDOFF_OUTPUT_PROMPT.format({
654-
to_agent: toAgent,
655-
reason: reason,
656-
});
657-
},
658-
{
616+
createHandoffTool(agents: Map<string, BaseWorkflowAgent>) {
617+
const agentInfo = Array.from(agents.values()).reduce(
618+
(acc, a) => {
619+
acc[a.name] = a.description;
620+
return acc;
621+
},
622+
{} as Record<string, string>,
623+
);
624+
return tool({
659625
name: "handOff",
660626
description: DEFAULT_HANDOFF_PROMPT.format({
661627
agent_info: JSON.stringify(agentInfo),
@@ -668,7 +634,34 @@ const createHandoffTool = (agents: Map<string, BaseWorkflowAgent>) => {
668634
description: "The reason for handing off to the agent",
669635
}),
670636
}),
671-
requireContext: true,
672-
},
673-
);
674-
};
637+
execute: (
638+
{
639+
toAgent,
640+
reason,
641+
}: {
642+
toAgent: string;
643+
reason: string;
644+
},
645+
contextProvider?: () => AgentWorkflowState,
646+
) => {
647+
if (!contextProvider) {
648+
throw new Error(
649+
"Handoff tool internal error: Context was not provided.",
650+
);
651+
}
652+
const context = contextProvider();
653+
const agents = context.agents;
654+
if (!agents.includes(toAgent)) {
655+
return `Agent ${toAgent} not found. Select a valid agent to hand off to. Valid agents: ${agents.join(
656+
", ",
657+
)}`;
658+
}
659+
context.nextAgentName = toAgent;
660+
return DEFAULT_HANDOFF_OUTPUT_PROMPT.format({
661+
to_agent: toAgent,
662+
reason: reason,
663+
});
664+
},
665+
}).bind(() => this.stateful.getContext().state);
666+
}
667+
}

0 commit comments

Comments
 (0)