feat: introduce deepagents, build the 6 subagents additively - #17
Merged
Conversation
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>
5 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds
deepagents(0.6.x) alongside the existing orchestration graphs -- nothing inbackend/,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()bridgesSETTINGS["llm"](generic, any OpenAI-API-compatible endpoint) to theBaseChatModeldeepagents needs, vialangchain-openai'sChatOpenAI. Fails closed at construction with the sameLLMNotConfiguredErrorEnhancedLiteLLMGatewayraises.orchestration/deep_agent.py:create_opspilot_agent()wrapscreate_deep_agent()with six subagents (email, meeting, tasks, followup, wellness, reporting). Tools are wrapped generically fromagents/tools.py's existingTool+ToolExecutor-- a pydantic args schema is built from eachTool's parameter list, and the wrapped tool delegates toToolExecutor.execute(), so the real DataRepo-backed handlers are reused, not reimplemented.interrupt_onis 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_followupalways pause;create_task/update_taskpause only for P0/P1 priority (matching the oldApprovalPolicy.CONDITIONAL_REQUIRElogic);mark_email_processednever pauses.model/checkpointerare injectable so tests exercise construction and a fullagent.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 skippedtests/test_deep_agent.py: tool bridge round-trips through the realToolExecutor,interrupt_onmatches the reconciled approval policy, agent fails closed without LLM config, agent constructs and invokes end-to-end against a stubbed modelrequirements.txtresolves cleanly in a fresh venv (matching what CI installs) -- confirmeddeepagents'slangchain>=1.3.11transitive bump is safe since nothing in this codebase imports thelangchainpackage directly (onlylangchain_core/langgraphpublic APIs)python -c "import backend.app"-- clean bootDepends on #13. Closes #14.
🤖 Generated with Claude Code