mirror of
https://github.com/langchain-ai/langgraphjs.git
synced 2026-07-22 00:55:26 -04:00
feat(langgraph): use createReactAgent description for supervisor agent handoffs (#1515)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@langchain/langgraph-supervisor": patch
|
||||
"@langchain/langgraph": patch
|
||||
---
|
||||
|
||||
feat(langgraph): use createReactAgent description for supervisor agent handoffs
|
||||
@@ -17,7 +17,13 @@ function _normalizeAgentName(agentName: string): string {
|
||||
return agentName.trim().replace(WHITESPACE_RE, "_").toLowerCase();
|
||||
}
|
||||
|
||||
const createHandoffTool = ({ agentName }: { agentName: string }) => {
|
||||
const createHandoffTool = ({
|
||||
agentName,
|
||||
agentDescription,
|
||||
}: {
|
||||
agentName: string;
|
||||
agentDescription?: string;
|
||||
}) => {
|
||||
/**
|
||||
* Create a tool that can handoff control to the requested agent.
|
||||
*
|
||||
@@ -53,7 +59,7 @@ const createHandoffTool = ({ agentName }: { agentName: string }) => {
|
||||
{
|
||||
name: toolName,
|
||||
schema: z.object({}),
|
||||
description: "Ask another agent for help.",
|
||||
description: agentDescription ?? "Ask another agent for help.",
|
||||
}
|
||||
);
|
||||
return handoffTool;
|
||||
|
||||
@@ -207,8 +207,8 @@ const createSupervisor = <
|
||||
agentNames.add(agent.name);
|
||||
}
|
||||
|
||||
const handoffTools = agents.map((agent) =>
|
||||
createHandoffTool({ agentName: agent.name! })
|
||||
const handoffTools = agents.map(({ name, description }) =>
|
||||
createHandoffTool({ agentName: name!, agentDescription: description })
|
||||
);
|
||||
const allTools = [...(tools ?? []), ...handoffTools];
|
||||
|
||||
@@ -271,9 +271,7 @@ const createSupervisor = <
|
||||
builder = builder.addNode(
|
||||
agent.name!,
|
||||
makeCallAgent(agent, outputMode, addHandoffBackMessages, supervisorName),
|
||||
{
|
||||
subgraphs: [agent],
|
||||
}
|
||||
{ subgraphs: [agent] }
|
||||
);
|
||||
builder = builder.addEdge(agent.name!, supervisorAgent.name!);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import { LanguageModelLike } from "@langchain/core/language_models/base";
|
||||
import { tool } from "@langchain/core/tools";
|
||||
import { HumanMessage, AIMessage } from "@langchain/core/messages";
|
||||
import { MessagesAnnotation } from "@langchain/langgraph";
|
||||
import { createReactAgent } from "@langchain/langgraph/prebuilt";
|
||||
import { createReactAgent, ToolNode } from "@langchain/langgraph/prebuilt";
|
||||
import { createSupervisor } from "../supervisor.js";
|
||||
import { FakeToolCallingChatModel } from "./utils.js";
|
||||
import { withAgentName, AgentNameMode } from "../index.js";
|
||||
@@ -198,6 +198,7 @@ describe("Test supervisor basic workflow", () => {
|
||||
llm: mathLLM,
|
||||
tools: [add],
|
||||
name: "math_expert",
|
||||
description: "Math expert.",
|
||||
prompt: "You are a math expert. Always use one tool at a time.",
|
||||
});
|
||||
|
||||
@@ -205,6 +206,7 @@ describe("Test supervisor basic workflow", () => {
|
||||
llm: researchLLM,
|
||||
tools: [webSearch],
|
||||
name: "research_expert",
|
||||
description: "World class researcher with access to web search.",
|
||||
prompt:
|
||||
"You are a world class researcher with access to web search. Do not do any math.",
|
||||
});
|
||||
@@ -218,6 +220,20 @@ describe("Test supervisor basic workflow", () => {
|
||||
includeAgentName,
|
||||
});
|
||||
|
||||
const toolNode = (
|
||||
workflow.nodes.supervisor.runnable as ReturnType<
|
||||
typeof createReactAgent
|
||||
>
|
||||
).nodes.tools.bound as ToolNode;
|
||||
|
||||
expect(toolNode.tools).toMatchObject([
|
||||
{ name: "transfer_to_math_expert", description: "Math expert." },
|
||||
{
|
||||
name: "transfer_to_research_expert",
|
||||
description: "World class researcher with access to web search.",
|
||||
},
|
||||
]);
|
||||
|
||||
const app = workflow.compile();
|
||||
expect(app).toBeDefined();
|
||||
|
||||
|
||||
@@ -749,6 +749,7 @@ export class StateGraph<
|
||||
interruptBefore,
|
||||
interruptAfter,
|
||||
name,
|
||||
description,
|
||||
}: {
|
||||
checkpointer?: BaseCheckpointSaver | boolean;
|
||||
store?: BaseStore;
|
||||
@@ -756,6 +757,7 @@ export class StateGraph<
|
||||
interruptBefore?: N[] | All;
|
||||
interruptAfter?: N[] | All;
|
||||
name?: string;
|
||||
description?: string;
|
||||
} = {}): CompiledStateGraph<
|
||||
Prettify<S>,
|
||||
Prettify<U>,
|
||||
@@ -801,6 +803,7 @@ export class StateGraph<
|
||||
store,
|
||||
cache,
|
||||
name,
|
||||
description,
|
||||
});
|
||||
|
||||
// attach nodes, edges and branches
|
||||
@@ -880,9 +883,33 @@ export class CompiledStateGraph<
|
||||
> {
|
||||
declare builder: StateGraph<unknown, S, U, N, I, O, C, NodeReturnType>;
|
||||
|
||||
/**
|
||||
* The description of the compiled graph.
|
||||
* This is used by the supervisor agent to describe the handoff to the agent.
|
||||
*/
|
||||
description?: string;
|
||||
|
||||
/** @internal */
|
||||
_metaRegistry: SchemaMetaRegistry = schemaMetaRegistry;
|
||||
|
||||
constructor({
|
||||
description,
|
||||
...rest
|
||||
}: { description?: string } & ConstructorParameters<
|
||||
typeof CompiledGraph<
|
||||
N,
|
||||
S,
|
||||
U,
|
||||
StateType<ToStateDefinition<C>>,
|
||||
UpdateType<ToStateDefinition<I>>,
|
||||
StateType<ToStateDefinition<O>>,
|
||||
NodeReturnType
|
||||
>
|
||||
>[0]) {
|
||||
super(rest);
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
attachNode(key: typeof START, node?: never): void;
|
||||
|
||||
attachNode(key: N, node: StateGraphNodeSpec<S, U>): void;
|
||||
|
||||
@@ -564,6 +564,12 @@ export type CreateReactAgentParams<
|
||||
*/
|
||||
name?: string;
|
||||
|
||||
/**
|
||||
* An optional description for the agent.
|
||||
* This can be used to describe the agent to the underlying supervisor LLM.
|
||||
*/
|
||||
description?: string | undefined;
|
||||
|
||||
/**
|
||||
* Use to specify how to expose the agent name to the underlying supervisor LLM.
|
||||
|
||||
@@ -684,6 +690,7 @@ export function createReactAgent<
|
||||
preModelHook,
|
||||
postModelHook,
|
||||
name,
|
||||
description,
|
||||
version = "v1",
|
||||
includeAgentName,
|
||||
} = params;
|
||||
@@ -987,5 +994,6 @@ export function createReactAgent<
|
||||
interruptAfter,
|
||||
store,
|
||||
name,
|
||||
description,
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user