Skip to content

Migrate existing agents to current version

Users with agents constructed using the Agentic Starter template prior to version 11.8.1 must perform a one-time update to maintain compatibility with newer releases. This is due to a change in the way the template constructs agents and how tools reach the workflow:

  • LangGraph, CrewAI, and LlamaIndex no longer rely on a handwritten MyAgent subclass. Build the native framework object (graph, crew, or workflow) first, then wrap it with a datarobot_agent_class_from_* factory that produces MyAgent.
  • Base (generic) still subclasses BaseAgent, with simplified construction and LLM wiring. custompy_adaptor passes llm=get_llm(...), consistent with other templates.
  • NAT (NVIDIA NeMo Agent Toolkit) still subclasses NatAgent. __init__ is smaller, custompy_adaptor omits model=, and LLMs stay declarative in workflow.yaml.

Across these patterns, the LLM is decoupled from ad hoc class state. Framework-specific get_llm() helpers resolve the model inside custompy_adaptor (and, for DRAgent, in register.py). MCP and workflow tools are injected at runtime instead of being read from self.mcp_tools on a LangGraphAgent-style subclass.

This page summarizes migration steps by framework. For step-by-step diffs, before-and-after examples, and test updates, see the framework migration guides in the template repository (docs/agent/).

Before you start

  • Back up your repository and .env file before you merge template updates.
  • Update the template (pull the latest Agentic Starter changes, or run dr component update for the agent component) so pyproject.toml, uv.lock, and generated stubs match the version you target.
  • Rename environment variables if you still use deprecated names. Deployed LLM configuration expects LLM_DEPLOYMENT_ID (not TEXTGEN_DEPLOYMENT_ID). See Configure LLM providers with metadata.
  • Keep the MyAgent export—infrastructure and tests expect that symbol. Do not rename it.

Changes that apply to most frameworks

custompy_adaptor and the LLM

In custompy_adaptor, replace passing a model= string into MyAgent(...) with passing llm= from get_llm(...) in the appropriate module:

  • LangGraph / Base: datarobot_genai.langgraph.llm.get_llm
  • CrewAI: datarobot_genai.crewai.llm.get_llm (CrewAI may need extra parameters, for example {"stream_options": None})
  • LlamaIndex: datarobot_genai.llama_index.llm.get_llm

Filter placeholder model names with a small set such as _PLACEHOLDER_MODELS = frozenset({"unknown"}) so a placeholder model_name from DataRobot does not force an invalid model.

Configuration

In myagent.py, remove from agent.config import Config where the new pattern delegates configuration to get_llm() and the runtime environment. If your template still loads MCP-related settings in custom.py, keep Config there.

Tests

Across frameworks, tests that constructed MyAgent(model=..., api_key=...) should use MyAgent(llm=Mock(), ...) instead. Remove tests that target deleted llm() methods or old __init__ signatures. Add tests for graph_factory or other module-level wiring where applicable.

Framework-specific migration

LangGraph

  • Replace class MyAgent(LangGraphAgent) with:
  • A module-level prompt_template
  • Remove llm(), __init__ boilerplate, and Config imports from myagent.py as described in the LangGraph migration guide.

CrewAI

  • Move agents, tasks, crew, and kickoff_inputs to module level; call get_llm() once at module scope where appropriate.
  • Replace the class with MyAgent = datarobot_agent_class_from_crew(crew, agents, tasks, kickoff_inputs).
  • Tools are injected at runtime; do not rely on self.tools on the old class.
  • Crew stream: often False at module scope; DRAgent can adjust streaming at runtime (see the migration guide in the template repository).

LlamaIndex

  • Use a module-level LiteLLM(model="placeholder") (or equivalent) for agents until custompy_adaptor injects the real LLM.
  • Move agents, workflow, state tools, and extract_response_text to module level. Remove make_input_message (the factory handles it).
  • MyAgent = datarobot_agent_class_from_llamaindex(workflow, agents, extract_response_text).

Base (generic)

  • MyAgent still subclasses BaseAgent. __init__ is simplified because BaseAgent owns initialization.
  • Remove manual _llm, self.config, and Config usage from the class. Pass llm=get_llm(...) from custompy_adaptor as in the Base migration guide.

NAT

  • NAT requires fewer structural changes than other frameworks: MyAgent(NatAgent) still subclasses NatAgent, but __init__ forwards *args / **kwargs to super() and supplies a default workflow_path.
  • In custompy_adaptor, omit model= when constructing MyAgent; LLMs are defined in workflow.yaml.

After you migrate

  1. Run dr task run agent:install (or your template’s install task), then dr task run agent:test.
  2. Start the local stack with dr run dev or task dev, exercise the app, and run task agent:cli as described in Customize agents.
  3. Deploy to a non-production environment first. Confirm traces and MCP behavior in the DataRobot UI.

For ongoing development tasks after migration, see Customize agents and Agent components.