Skip to content

feat: introduce deepagents, build the 6 subagents additively - #17

Merged
kowshikdev merged 1 commit into
mainfrom
feat/deepagents-subagents
Jul 23, 2026
Merged

feat: introduce deepagents, build the 6 subagents additively#17
kowshikdev merged 1 commit into
mainfrom
feat/deepagents-subagents

Conversation

@kowshikdev

Copy link
Copy Markdown
Owner

Summary

Adds deepagents (0.6.x) alongside the existing orchestration graphs -- nothing in backend/, agents/smart_chat.py, or any existing entry point imports this yet, so it ships with zero user-facing behavior change. The cutover is #15.

  • agents/llm_model.py: get_chat_model() bridges SETTINGS["llm"] (generic, any OpenAI-API-compatible endpoint) to the BaseChatModel deepagents needs, via langchain-openai's ChatOpenAI. Fails closed at construction with the same LLMNotConfiguredError EnhancedLiteLLMGateway raises.
  • orchestration/deep_agent.py: create_opspilot_agent() wraps create_deep_agent() with six subagents (email, meeting, tasks, followup, wellness, reporting). Tools are wrapped generically from agents/tools.py's existing Tool + ToolExecutor -- a pydantic args schema is built from each Tool's parameter list, and the wrapped tool delegates to ToolExecutor.execute(), so the real DataRepo-backed handlers are reused, not reimplemented.
  • interrupt_on is the single reconciled approval source of truth, replacing the three inconsistent definitions found during migration research (see Dead/duplicate agent code: react_agent.py, duplicate EmailAgent, unused ApprovalPolicy, missing checkpointer #13): send_email/schedule_meeting/create_followup always pause; create_task/update_task pause only for P0/P1 priority (matching the old ApprovalPolicy.CONDITIONAL_REQUIRE logic); mark_email_processed never pauses.
  • model/checkpointer are injectable so tests exercise construction and a full agent.invoke() with a stubbed tool-calling model and an in-memory checkpointer -- no real LLM or Redis required.

Test plan

  • pytest tests/ -- 80 passed (70 existing + 10 new), 2 skipped
  • New tests/test_deep_agent.py: tool bridge round-trips through the real ToolExecutor, interrupt_on matches the reconciled approval policy, agent fails closed without LLM config, agent constructs and invokes end-to-end against a stubbed model
  • Verified requirements.txt resolves cleanly in a fresh venv (matching what CI installs) -- confirmed deepagents's langchain>=1.3.11 transitive bump is safe since nothing in this codebase imports the langchain package directly (only langchain_core/langgraph public APIs)
  • python -c "import backend.app" -- clean boot

Depends on #13. Closes #14.

🤖 Generated with Claude Code

Adds deepagents (0.6.x) alongside the existing orchestration graphs --
nothing in backend/, agents/smart_chat.py, or any existing entry point
imports this yet, so it ships with zero user-facing behavior change.
The cutover is issue #15.

- agents/llm_model.py: get_chat_model() bridges SETTINGS["llm"]
  (base_url/api_key/model_id -- generic, any OpenAI-API-compatible
  endpoint) to the BaseChatModel deepagents' create_deep_agent(model=)
  expects, via langchain-openai's ChatOpenAI. Fails closed at
  construction with the same LLMNotConfiguredError
  EnhancedLiteLLMGateway raises, rather than three steps into a run.

- orchestration/deep_agent.py: create_opspilot_agent() wraps
  create_deep_agent() with six subagents (email, meeting, tasks,
  followup, wellness, reporting). Tools are wrapped generically from
  agents/tools.py's existing Tool + ToolExecutor -- a pydantic args
  schema is built from each Tool's ToolParameter list, and the wrapped
  tool delegates to ToolExecutor.execute(), so the real DataRepo-backed
  handlers are reused, not reimplemented.

- interrupt_on is the single reconciled approval source of truth,
  replacing the three inconsistent definitions found during migration
  research (Tool.requires_approval flags the old executor sometimes
  bypassed, hardcoded False literals in autonomous_graph.py, and the
  now-deleted unused ApprovalPolicy class from #13): send_email,
  schedule_meeting, and create_followup always pause; create_task and
  update_task pause only for P0/P1 priority (matching
  ApprovalPolicy.CONDITIONAL_REQUIRE's old logic); mark_email_processed
  never pauses.

- model/checkpointer are injectable on create_opspilot_agent() so
  tests/test_deep_agent.py can exercise construction and a full
  agent.invoke() with a stubbed tool-calling model and an in-memory
  checkpointer -- no real LLM or Redis required, same testability
  pattern as test_gateway.py/test_checkpointer.py.

Verified: pytest tests/ (80 passed, 2 skipped) both in this environment
and in a fresh venv installing only requirements.txt +
backend/requirements.txt (matching what CI does), and a clean
backend.app import.

Closes #14

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@kowshikdev
kowshikdev merged commit c8e9eb2 into main Jul 23, 2026
2 checks passed
@kowshikdev
kowshikdev deleted the feat/deepagents-subagents branch July 23, 2026 11:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Introduce deepagents: build the 6 subagents additively, reconcile approval logic

1 participant