Uh oh!
There was an error while loading. Please reload this page.
feat(cli): add Temporal + LangGraph agent template and example - #383
Conversation
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
1c291ed to
3ccb61cCompareReview the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Uh oh!
There was an error while loading. Please reload this page.
3ccb61c to
d556838Comparedanielmillerp
commented
Jun 1, 2026
Pushed fixes for the failing CI + review comments (rebased on latest CI failure (the blocker): the example Review comments:
Also — made the example minimal. Per feedback that it had more state/machinery than the other LangGraph tutorials, the Re-verified locally: example tests pass (hermetic ReAct + a live end-to-end run through the real Temporal plugin on a local server), |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
d556838 to
7562843CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
7562843 to
cf64c14Comparedanielmillerp
commented
Jun 1, 2026
Thanks @smoreinis — addressed all three:
Re-verified: rendered template builds the graph, ruff clean, |
Uh oh!
There was an error while loading. Please reload this page.
Adds a `temporal-langgraph` init template (registered in the Temporal submenu of `agentex init`) plus a runnable tutorial example, filling the gap left by the existing `temporal-openai-agents` / `temporal-pydantic-ai` templates — LangGraph previously only had `default-langgraph` and `sync-langgraph`. Uses the official Temporal LangGraph plugin (`temporalio.contrib.langgraph`, shipped in `temporalio[langgraph]>=1.27.0`): each LangGraph node runs as a durable Temporal activity (the LLM/`agent` node) or inline in the workflow (the `tools` node). Temporal is the runtime; LangGraph is the agent framework. Verified the plugin's behavior locally (Temporal dev server + real LLM) and encoded the working shape into the template: - agent node `execute_in="activity"`, tools node `execute_in="workflow"` (tool-node-as-activity is broken in the experimental plugin — AIMessage doesn't survive the activity boundary); - async router + async tools (sync callables hit run_in_executor, which Temporal's workflow loop forbids); - AgentexWorker's UnsandboxedWorkflowRunner makes langchain imports safe. Showcases nodes-as-activities, human-in-the-loop via LangGraph `interrupt` resumed by a Temporal `provide_approval` signal + `Command(resume=...)`, multi-turn memory on the workflow, graph-visualization queries (mermaid/ascii), and tracing. Example: examples/.../10_temporal/130_langgraph (full agent + tests). Tests: - tests/lib/cli/test_init_templates.py — renders every init template and asserts valid, substituted Python (catches .j2 regressions), with focused coverage of the new template (nodes-as-activities, HIL, queries, deps). - example tests/test_graph_temporal.py — hermetic graph + HIL coverage with a stub model, plus a live end-to-end run through the real Temporal plugin (skipped without LITELLM_API_KEY); tests/test_agent.py — live integration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
cf64c14 to
ab18952Comparedanielmillerp
commented
Jun 1, 2026
Good catch — fixed. Verified with a unit check on both shapes (OpenAI str → text; Claude block-list → joined text); ruff clean; rebased on latest |
What
Adds a
temporal-langgraphtemplate toagentex init(in the Async → Temporal submenu) and a runnable tutorial example (examples/tutorials/10_async/10_temporal/130_langgraph). LangGraph previously haddefault-langgraphandsync-langgraphbut no Temporal variant; OpenAI Agents and Pydantic AI both did.Approach: the official Temporal LangGraph plugin
Uses
temporalio.contrib.langgraph.LangGraphPlugin(shipped intemporalio[langgraph]>=1.27.0, experimental). Each LangGraph node runs as a durable Temporal activity or inline in the workflow, set per node viaexecute_in. Temporal is the runtime; LangGraph is the agent framework.Verified locally before shipping
I ran the plugin against a local Temporal server (
WorkflowEnvironment.start_local) with a real LLM and encoded the working shape into the template (the docs don't spell these out):agent(LLM) node →execute_in="activity";toolsnode →execute_in="workflow". Tool-node-as-activity is broken in the experimental plugin (theAIMessagewith tool calls doesn't survive the activity payload boundary →ToolNoderaises "No AIMessage found"); running it in the workflow keeps it intact and is also where LangGraphinterruptmust run.run_in_executor, which Temporal's workflow event loop forbids (NotImplementedError).AgentexWorker'sUnsandboxedWorkflowRunner, so langchain imports in the workflow module are fine.Showcase
interrupt; the workflow pauses on aprovide_approvalTemporal signal and resumes withCommand(resume=...).get_status,get_pending_approval,get_graph_state,get_graph_mermaid/get_graph_ascii.Tests
tests/lib/cli/test_init_templates.py— renders every init template and asserts valid, substituted Python (catches.j2regressions; already caught a Jinja brace bug), with focused coverage of the new template.tests/test_graph_temporal.py— hermetic ReAct + HIL approve/reject via a stub model (no network), plus a live end-to-end run through the real Temporal plugin (skipped unlessLITELLM_API_KEYis set).tests/test_agent.py— live integration against a running agent.Verification run in this PR
pytest tests/lib/cli/→ 59 passed.execute_inmetadata.interrupt→signal→Command(resume)) and multi-turn message round-tripping verified live on a local Temporal server.🤖 Generated with Claude Code
Greptile Summary
This PR introduces a
temporal-langgraphtemplate toagentex initand a matching runnable tutorial example, making LangGraph a first-class option alongside the existing OpenAI Agents and Pydantic AI Temporal templates. The integration usestemporalio.contrib.langgraph.LangGraphPlugin(≥ 1.27.0) to run graph nodes as durable Temporal activities, with human-in-the-loop gating via LangGraphinterruptand Temporal signals.src/agentex/lib/cli/templates/temporal-langgraph/): full project scaffold with customtools_nodesupporting HIL approval, multi-turn memory on the workflow instance, graph-visualization queries, and per-nodeexecute_inmetadata routing the LLM call to a retried activity._langgraph_messages.py): converts finished LangGraph messages to Agentex task messages afterainvoke, handling both plain-string and list-of-blocksAIMessage.content.examples/tutorials/10_async/10_temporal/130_langgraph/): simplified (no HIL) variant with hermetic ReAct tests via a stub model plus a live end-to-end Temporal-plugin test gated onLITELLM_API_KEY.Confidence Score: 4/5
Safe to merge with one open concern: the signal handler in the template workflow runs the full LangGraph turn (including awaiting LLM activities) directly inside on_task_event_send, which was flagged in a previous review thread and remains unaddressed.
The template's on_task_event_send signal handler awaits compiled.ainvoke(...) for the entire agent turn. If a second user message arrives while that await is in progress, a second handler coroutine starts concurrently, and both share self._messages, self._emitted, self._status, and self._pending_approval. Whichever handler writes last silently drops the other turn's messages. Everything else in the PR — the ADK helper, the graph template, the test suite, the pyproject deps, and the CLI wiring — looks correct and well-tested.
src/agentex/lib/cli/templates/temporal-langgraph/project/workflow.py.j2 — the on_task_event_send signal handler deserves the most attention due to the concurrent-execution concern noted in a prior review thread.
Important Files Changed
Reviews (6): Last reviewed commit: "feat(cli): add Temporal + LangGraph agen..." | Re-trigger Greptile