[PR #74] [MERGED] Added Support for Model Instances and Dict #441

Closed
opened 2026-02-16 09:16:02 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagents/pull/74
Author: @riadzeitounn
Created: 8/25/2025
Status: Merged
Merged: 8/25/2025
Merged by: @hwchase17

Base: masterHead: support-model-instance-format


📝 Commits (1)

  • d2c19ad Added Support for Model Instances and dict

📊 Changes

2 files changed (+15 additions, -8 deletions)

View changed files

📝 src/deepagents/graph.py (+1 -0)
📝 src/deepagents/sub_agent.py (+14 -8)

📄 Description

Improve Subagent Model Configuration: Unified Model Field

The Problem

Right now, there's a weird inconsistency between how the main agent and subagents handle models:

  • The main agent uses proper model instances like ChatAnthropic(model_name="claude-sonnet-4", max_tokens=64000)
  • But subagents have to use dictionary configs like {"model": "anthropic", "model_name": "claude-haiku"}

This is pretty annoying because:

  1. It's inconsistent - why should main agents and subagents work differently?
  2. Code duplication - you have to repeat the same model settings everywhere
  3. It's just not intuitive

My Solution

I updated the SubAgent TypedDict to use a unified model field that intelligently accepts both model instances AND dictionary settings.

Before (the old way):

subagents = [
    {
        "name": "researcher",
        "description": "Does research tasks", 
        "prompt": "You are a researcher...",
        "model_settings": {"model": "anthropic", "model_name": "claude-haiku-3"}  # Ugh, separate field
    }
]

After (unified and flexible):

from langchain_anthropic import ChatAnthropic

# Create model instances
fast_model = ChatAnthropic(model_name="claude-haiku-3", max_tokens=4000)

# Use the same 'model' field for both approaches!
subagents = [
    {
        "name": "researcher", 
        "description": "Does research tasks",
        "prompt": "You are a researcher...",
        "model": fast_model  # ✅ Model instance - clean and reusable!
    },
    {
        "name": "writer",
        "description": "Does writing tasks", 
        "prompt": "You are a writer...",
        "model": {"model": "anthropic", "model_name": "claude-sonnet-4"}  # ✅ Dict settings - still works!
    },
    {
        "name": "analyzer",
        "description": "Does analysis tasks",
        "prompt": "You are an analyzer..."
        # ✅ No model field - uses main model
    }
]

What I Changed

  1. Updated SubAgent TypedDict in src/deepagents/sub_agent.py:

    • Replaced model_settings: NotRequired[dict[str, Any]]
    • With model: NotRequired[Union[LanguageModelLike, dict[str, Any]]]
  2. Smart model resolution logic in _create_task_tool:

    • Detects if model is a dictionary → creates model with init_chat_model(**agent_model)
    • Detects if model is an instance → uses directly
    • Falls back to main model if no model specified
  3. Updated documentation to reflect the unified approach

Benefits

  • Unified API - one model field handles both approaches
  • Flexible - accepts both model instances and dictionary settings
  • Backward compatible - existing dictionary code still works
  • Type safe - proper typing with Union[LanguageModelLike, dict[str, Any]]
  • Intuitive - same field name, smart value handling
  • Less duplication - create models once, reuse them

This makes the subagent model configuration much more intuitive and consistent with the rest of the codebase!


Files Changed:

  • src/deepagents/sub_agent.py - Updated TypedDict and model resolution logic
  • src/deepagents/graph.py - Updated documentation

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagents/pull/74 **Author:** [@riadzeitounn](https://github.com/riadzeitounn) **Created:** 8/25/2025 **Status:** ✅ Merged **Merged:** 8/25/2025 **Merged by:** [@hwchase17](https://github.com/hwchase17) **Base:** `master` ← **Head:** `support-model-instance-format` --- ### 📝 Commits (1) - [`d2c19ad`](https://github.com/langchain-ai/deepagents/commit/d2c19ad4835ec1f9704782bbb70c7b3f8c88e537) Added Support for Model Instances and dict ### 📊 Changes **2 files changed** (+15 additions, -8 deletions) <details> <summary>View changed files</summary> 📝 `src/deepagents/graph.py` (+1 -0) 📝 `src/deepagents/sub_agent.py` (+14 -8) </details> ### 📄 Description # Improve Subagent Model Configuration: Unified Model Field ## The Problem Right now, there's a weird inconsistency between how the main agent and subagents handle models: - The main agent uses proper model instances like `ChatAnthropic(model_name="claude-sonnet-4", max_tokens=64000)` - But subagents have to use dictionary configs like `{"model": "anthropic", "model_name": "claude-haiku"}` This is pretty annoying because: 1. **It's inconsistent** - why should main agents and subagents work differently? 2. **Code duplication** - you have to repeat the same model settings everywhere 3. **It's just not intuitive** ## My Solution I updated the `SubAgent` TypedDict to use a **unified `model` field** that intelligently accepts **both model instances AND dictionary settings**. ### Before (the old way): ```python subagents = [ { "name": "researcher", "description": "Does research tasks", "prompt": "You are a researcher...", "model_settings": {"model": "anthropic", "model_name": "claude-haiku-3"} # Ugh, separate field } ] ``` ### After (unified and flexible): ```python from langchain_anthropic import ChatAnthropic # Create model instances fast_model = ChatAnthropic(model_name="claude-haiku-3", max_tokens=4000) # Use the same 'model' field for both approaches! subagents = [ { "name": "researcher", "description": "Does research tasks", "prompt": "You are a researcher...", "model": fast_model # ✅ Model instance - clean and reusable! }, { "name": "writer", "description": "Does writing tasks", "prompt": "You are a writer...", "model": {"model": "anthropic", "model_name": "claude-sonnet-4"} # ✅ Dict settings - still works! }, { "name": "analyzer", "description": "Does analysis tasks", "prompt": "You are an analyzer..." # ✅ No model field - uses main model } ] ``` ## What I Changed 1. **Updated `SubAgent` TypedDict** in `src/deepagents/sub_agent.py`: - Replaced `model_settings: NotRequired[dict[str, Any]]` - With `model: NotRequired[Union[LanguageModelLike, dict[str, Any]]]` 2. **Smart model resolution logic** in `_create_task_tool`: - Detects if `model` is a dictionary → creates model with `init_chat_model(**agent_model)` - Detects if `model` is an instance → uses directly - Falls back to main model if no `model` specified 3. **Updated documentation** to reflect the unified approach ## Benefits - ✅ **Unified API** - one `model` field handles both approaches - ✅ **Flexible** - accepts both model instances and dictionary settings - ✅ **Backward compatible** - existing dictionary code still works - ✅ **Type safe** - proper typing with `Union[LanguageModelLike, dict[str, Any]]` - ✅ **Intuitive** - same field name, smart value handling - ✅ **Less duplication** - create models once, reuse them This makes the subagent model configuration much more intuitive and consistent with the rest of the codebase! --- **Files Changed:** - `src/deepagents/sub_agent.py` - Updated TypedDict and model resolution logic - `src/deepagents/graph.py` - Updated documentation --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 09:16:02 -05:00
yindo closed this issue 2026-02-16 09:16:02 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagents#441