Sabir Moglad
Sabir Moglad

Reputation: 899

Langgraph.js dynamically create graph

How to Dynamically Generate a Graph with TypeScript?

I'm working on a TypeScript project where I need to dynamically generate a graph based on configurations. Below is a simplified example of my setup:

Agent Configuration Example

I have agent specifications like this:

export const markdownFormatterAgentSpec: AgentSpec = {
  id: "markdown-formatter-agent-id-1",
  name: "Markdown Formatter Agent",
  description: "An agent that formats text using Markdown.",
  coreInstructions: markdownFormatterAgentCoreInstructions,
  model: {
    name: "gpt-3.5-turbo",
    temperature: 0.2, // Optional: Adjust temperature if needed
  },
  subAgents: [], // No subagents in this case, can be populated if needed
  tools: [], // No tools for the markdown formatter agent
};

Node Generation

I generate nodes dynamically from a record of agents like this:

function generateNodes(
  agents: Record<string, ReturnType<typeof createReactAgent>>
): Record<string, AgentNodeFunction> {
  const nodes: Record<string, AgentNodeFunction> = {};

  for (const [id, agent] of Object.entries(agents)) {
    nodes[id] = async (state, config) => {
      try {
        const result = await agent.invoke(state, config);
        const newMessages = result.messages.map(
          (msg: any) =>
            new HumanMessage({
              content: msg.content,
              name: id,
            })
        );
        return {
          ...state,
          messages: [...state.messages, ...newMessages],
        };
      } catch (error: any) {
        return {
          ...state,
          messages: [
            ...state.messages,
            new SystemMessage(`Error in ${id}: ${error.message}`),
          ],
        };
      }
    };
  }

  return nodes;
}

Graph Generation

To create the graph, I use the following function:

function generateGraph(
  agents: Record<string, ReturnType<typeof createReactAgent>>,
  rootAgentId: string
) {
  const nodes = generateNodes(agents);
  const graph = new StateGraph(AgentState);

  // Add nodes to the graph
  for (const [id, node] of Object.entries(nodes)) {
    graph.addNode(id, node);
  }

  // Dynamically define edges based on hierarchy
  function addEdges(agentSpec: AgentSpec) {
    if (agentSpec.subAgents && agentSpec.subAgents.length > 0) {
      for (const subAgent of agentSpec.subAgents) {
        const agentId = agentSpec.id;
        const subAgentId = subAgent.id;
        graph.addEdge(agentId, subAgentId); // Connect parent to sub-agent
        addEdges(subAgent); // Recursively add edges for sub-agents
      }
    }
  }

  // Add edges starting from the root agent
  if (agents[rootAgentId]) {
    addEdges(agents[rootAgentId]);
  } else {
    throw new Error(
      `Root agent with ID ${rootAgentId} is not defined in agents map.`
    );
  }

  // Connect START to the root agent
  graph.addEdge(START, rootAgentId);

  // Connect all agents back to END
  for (const id of Object.keys(nodes)) {
    graph.addEdge(id, END);
  }

  return graph.compile();
}

The Problem The issue arises with the addEdge method when I try to dynamically add edges using addEdge:


graph.addEdge(agentId, subAgentId);
TypeScript throws the following error:
Argument of type 'string' is not assignable to parameter of type '"__start__" | "__start__"[]'.ts(2345)
It seems that when the id is a literal value, it works fine. However, when the id comes from a variable, TypeScript complains about type incompatibility.

Question How can I dynamically generate the graph and resolve the type issue with addEdge? Is there a way to make the id dynamically typed or enforce the correct type in this scenario?

Any insights or suggestions would be greatly appreciated!

Upvotes: 0

Views: 115

Answers (0)

Related Questions