Add Deep Agents plugin samples - #328
Draft
DABH wants to merge 5 commits into
Draft
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new deepagents_plugin/ sample suite demonstrating how the upcoming temporalio.contrib.deepagents integration makes LangChain Deep Agents durable (model/tool/backend calls executed as Temporal Activities while the agent loop replays in Workflow code). It also introduces an optional deepagents dependency group (Python ≥ 3.11) and a guarded offline test suite under tests/deepagents_plugin/.
Changes:
- Add eight runnable Deep Agents plugin sample scenarios under
deepagents_plugin/(worker/starter pairs + per-scenario READMEs). - Add offline pytest coverage for the scenarios (skipped at collection time when the plugin isn’t importable / Python < 3.11).
- Register the sample package in
pyproject.toml, update root README, and updateuv.lockfor the new dependency group resolution.
Reviewed changes
Copilot reviewed 43 out of 53 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Locks new deepagents group deps and associated transitive packages. |
| pyproject.toml | Adds deepagents dependency group (Python ≥ 3.11) and registers deepagents_plugin as a package. |
| README.md | Adds deepagents_plugin to the root sample list. |
| deepagents_plugin/init.py | Package marker for the Deep Agents samples. |
| deepagents_plugin/README.md | Suite-level documentation, prerequisites, and run instructions. |
| deepagents_plugin/hello_world/workflow.py | Minimal durable agent workflow example. |
| deepagents_plugin/hello_world/run_worker.py | Worker wiring with DeepAgentsPlugin. |
| deepagents_plugin/hello_world/run_workflow.py | Starter for hello world scenario. |
| deepagents_plugin/hello_world/README.md | Scenario documentation. |
| deepagents_plugin/hello_world/init.py | Package marker. |
| deepagents_plugin/react_agent/workflow.py | Tool loop example showing activity_as_tool vs tool_as_activity + explicit TemporalModel. |
| deepagents_plugin/react_agent/run_worker.py | Worker wiring + registers the user activity tool. |
| deepagents_plugin/react_agent/run_workflow.py | Starter for react-agent scenario. |
| deepagents_plugin/react_agent/README.md | Scenario documentation. |
| deepagents_plugin/react_agent/init.py | Package marker. |
| deepagents_plugin/human_in_the_loop/workflow.py | Interrupt/resume mapping to Temporal Query + Update. |
| deepagents_plugin/human_in_the_loop/run_worker.py | Worker wiring with plugin. |
| deepagents_plugin/human_in_the_loop/run_workflow.py | Starter demonstrating query polling + update resume. |
| deepagents_plugin/human_in_the_loop/README.md | Scenario documentation. |
| deepagents_plugin/human_in_the_loop/init.py | Package marker. |
| deepagents_plugin/continue_as_new/workflow.py | run_deep_agent continue-as-new contract example. |
| deepagents_plugin/continue_as_new/run_worker.py | Worker wiring with plugin. |
| deepagents_plugin/continue_as_new/run_workflow.py | Starter for continue-as-new scenario. |
| deepagents_plugin/continue_as_new/README.md | Scenario documentation. |
| deepagents_plugin/continue_as_new/init.py | Package marker. |
| deepagents_plugin/filesystem_backend/workflow.py | TemporalBackend(FilesystemBackend(...)) durable file I/O example. |
| deepagents_plugin/filesystem_backend/run_worker.py | Worker wiring with plugin. |
| deepagents_plugin/filesystem_backend/run_workflow.py | Starter for filesystem-backend scenario. |
| deepagents_plugin/filesystem_backend/README.md | Scenario documentation. |
| deepagents_plugin/filesystem_backend/init.py | Package marker. |
| deepagents_plugin/subagents/workflow.py | Sub-agent durability inheritance example. |
| deepagents_plugin/subagents/run_worker.py | Worker wiring with plugin. |
| deepagents_plugin/subagents/run_workflow.py | Starter for subagents scenario. |
| deepagents_plugin/subagents/README.md | Scenario documentation. |
| deepagents_plugin/subagents/init.py | Package marker. |
| deepagents_plugin/streaming/workflow.py | Streaming model chunks to workflow-streams topic example. |
| deepagents_plugin/streaming/run_worker.py | Worker wiring enabling streaming dispatch. |
| deepagents_plugin/streaming/run_workflow.py | Starter subscribing to streamed chunks and printing live output. |
| deepagents_plugin/streaming/README.md | Scenario documentation. |
| deepagents_plugin/streaming/init.py | Package marker. |
| deepagents_plugin/langsmith_tracing/workflow.py | Durable agent workflow used for tracing scenario. |
| deepagents_plugin/langsmith_tracing/main.py | Single-process driver composing LangSmithPlugin + DeepAgentsPlugin. |
| deepagents_plugin/langsmith_tracing/README.md | Scenario documentation (no offline test). |
| deepagents_plugin/langsmith_tracing/init.py | Package marker. |
| tests/deepagents_plugin/conftest.py | Collection-time guard to skip tests when plugin isn’t available / Python < 3.11. |
| tests/deepagents_plugin/hello_world_test.py | Offline test for hello world scenario using mock_model_provider. |
| tests/deepagents_plugin/react_agent_test.py | Offline test for tool loop scenario. |
| tests/deepagents_plugin/human_in_the_loop_test.py | Offline test for interrupt/resume scenario. |
| tests/deepagents_plugin/continue_as_new_test.py | Offline tests for run_deep_agent contract + continue-as-new carry behavior. |
| tests/deepagents_plugin/filesystem_backend_test.py | Offline test for durable filesystem backend ops. |
| tests/deepagents_plugin/subagents_test.py | Offline test for sub-agent durability inheritance. |
| tests/deepagents_plugin/streaming_test.py | Offline test for streaming topic publishing. |
| tests/deepagents_plugin/init.py | Test package marker. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…test - human_in_the_loop: clear the pending-approval prompt on resume so the query honors its documented contract, and add an update validator that rejects decisions other than approve/reject before they enter history - tests conftest: replace find_spec with a guarded import so collection is skipped when the plugin package exists but its runtime deps do not - streaming test: replace the fixed sleep-then-cancel drain with a condition-based subscriber awaited via wait_for, matching the other streaming tests
…tests - CODEOWNERS: add /deepagents_plugin/ and /tests/deepagents_plugin/ for the AI SDK team, matching the sibling AI suites - Suite README: state the Python >= 3.11 floor in Prerequisites (on 3.10 the dependency group silently resolves to nothing) - streaming/run_workflow.py: drain the subscriber until the full durable result has been printed (bounded by a timeout) instead of cancelling it immediately and dropping tail chunks - subagents_test: script the coordinator -> task tool -> researcher -> synthesis path so the delegation headline is actually exercised, and assert three invoke_model activities in history - hello_world_test: assert the model call was scheduled as a deepagents.invoke_model activity (shared count_scheduled_activities helper) - pyproject: cap langchain-anthropic at <2 like its group siblings
- Drop the workflow.unsafe.imports_passed_through() guards from all eight workflows: the plugin passes the deepagents/LangChain import tree through the sandbox itself, and its README highlights bare imports as the intended developer experience. hello_world carries a comment explaining why no guard is needed. Verified by the full test suite (real sandboxed worker) plus an ad-hoc sandbox run of the untested langsmith_tracing workflow. - continue_as_new: use run_deep_agent's default server-suggested mode (the documented recommended mode) instead of a hardcoded event threshold; the probe test retains continue_as_new_after=1 as explicit-override coverage. - react_agent: build the agent with create_temporal_deep_agent and per-agent activity_options — the recommended way to scope model-call timeouts — replacing the bare TemporalModel construction. - Extend the history seam assertions to every testable scenario: react_agent (get_weather + invoke_tool), filesystem_backend (backend_op >= 2), streaming (invoke_model_streaming, no invoke_model), human_in_the_loop (invoke_tool after resume). - HITL README: note that a production loop would re-check __interrupt__ after each resume.
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.
What
Samples for the upcoming Temporal ↔ LangChain Deep Agents integration (
temporalio.contrib.deepagents): eight scenarios underdeepagents_plugin/, each a runnable worker/starter pair with its own README, plus offline tests (fake model provider, no API keys) undertests/deepagents_plugin/.hello_world— vanillacreate_deep_agent(...).ainvoke(...)inside a workflow; the only change isplugins=[DeepAgentsPlugin()], and every model call becomes a Temporal Activity.react_agent— the explicit per-tool Workflow-vs-Activity choice:activity_as_tool(surface an existing@activity.defn) andtool_as_activity(route an I/O LangChain tool through an activity), with an explicitTemporalModel.human_in_the_loop— the native LangGraph interrupt/resume protocol mapped to a Temporal Query + Update; no custom shim.continue_as_new—run_deep_agent(..., continue_as_new_after=N)carrying the conversation and the model/tool result cache across continue-as-new.filesystem_backend—TemporalBackend(FilesystemBackend(...)): the agent's built-in file tools execute as durabledeepagents.backend_opactivities instead of doing I/O in workflow code.subagents— sub-agents inherit the durable model automatically; delegation needs no per-sub-agent wiring.streaming—streaming_topic=...publishes chunk batches to a workflow-streams topic for live subscribers while the durable result stays identical to the non-streaming path.langsmith_tracing— composingDeepAgentsPluginwithLangSmithPluginfor tracing (no test; needs real API keys).Repo registration: a
deepagentsdependency group (gated on Python ≥ 3.11), the wheelpackagesentry, and the root README row.Status
Draft until the plugin lands in sdk-python. The plugin distribution is experimental and not yet published, so the dependency group deliberately does not include it (an unresolvable dep would break
uv lock/uv syncfor everyone), andtests/deepagents_plugin/skips collection when the plugin isn't importable — CI stays green with no plugin present.pyproject.tomlcarries an inline note with the one-line group change to make when the plugin publishes.How to run / test evidence
Interim install (documented in
deepagents_plugin/README.md): install the plugin into the repo venv, thenCurrent result against the in-development plugin: 8 passed, with
ruff check/ruff format --check/mypyclean on the new directories.