Skip to content

feat: Claude Agent SDK with Temporal — durable agent execution#54

Open
febinct wants to merge 2 commits intotemporalio:mainfrom
febinct:feat/claude-agent-sdk-example
Open

feat: Claude Agent SDK with Temporal — durable agent execution#54
febinct wants to merge 2 commits intotemporalio:mainfrom
febinct:feat/claude-agent-sdk-example

Conversation

@febinct
Copy link
Copy Markdown

@febinct febinct commented Feb 22, 2026

Summary

Adds a new cookbook example (agents/claude_agent_sdk_python/) demonstrating how to run the Claude Agent SDK (claude-code-sdk) inside a Temporal workflow for durable, observable agent execution.

Unlike the existing agentic_loop_tool_call_claude_python example that builds a manual tool-calling loop with the Messages API, this example delegates the entire agentic loop to the Claude Agent SDK — the SDK handles tool selection, execution, and multi-turn conversation internally. The Temporal activity wraps this as a single long-running operation with streaming event collection.

Key patterns demonstrated

  • Background heartbeatsasyncio.create_task() sends Temporal heartbeats every 60s, independent of the SDK event stream. Critical for long-running tools (e.g., git operations) that emit no events for extended periods.
  • Staleness guard — Stops heartbeating after 15 min of no events, letting Temporal kill truly hung agents instead of blocking the full 30-min timeout.
  • Response deduplication — The SDK emits both StreamEvent (incremental chunks) and AssistantMessage (complete blocks) with the same text. Only AssistantMessage is accumulated to avoid doubling the response.
  • Errors as completions — Agent failures return AgentOutput(status="error") rather than raising exceptions.

Files

File Description
README.md Full walkthrough with comparison table
models.py Pydantic I/O models
activities/agent_executor.py Core activity with heartbeat + staleness + dedup
workflows/agent.py 2-step durable workflow
worker.py Temporal worker
start_workflow.py CLI entrypoint
tests/test_workflow.py Workflow tests with mocked activities
tests/test_activity.py Activity tests with mocked SDK events

Context

These patterns were developed running Claude Agent SDK in production with Temporal for Slack-triggered and webhook-triggered agent execution. The three key patterns (heartbeats, staleness, dedup) solved real production issues — we stripped them down to a minimal, self-contained cookbook example.

Test plan

  • uv sync resolves dependencies
  • uv sync --extra test && uv run pytest tests/ -v passes all tests
  • uv run python -m worker starts successfully (with local Temporal)
  • uv run python -m start_workflow "hello" executes and returns a response
  • README renders correctly on GitHub

🤖 Generated with Claude Code

@CLAassistant
Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Febin .Sathar seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

@febinct febinct force-pushed the feat/claude-agent-sdk-example branch from 4c4d332 to b8ce97d Compare February 22, 2026 13:22
Add a new cookbook example demonstrating how to run the Claude Agent SDK
(claude-code-sdk) inside a Temporal workflow for durable agent execution.

Key patterns demonstrated:
- Background heartbeats via asyncio.create_task() (independent of event stream)
- Staleness guard to detect hung agents (15-min idle threshold)
- Response deduplication (AssistantMessage vs StreamEvent)
- Errors modeled as completions (not exceptions)

Includes workflow tests (mocked activities) and activity tests (mocked SDK).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@febinct febinct force-pushed the feat/claude-agent-sdk-example branch from b8ce97d to 496316e Compare February 22, 2026 13:30
Capture session_id from SystemMessage(init) events and support resuming
conversations via --resume flag. The SDK stores sessions as JSONL files
on disk; passing resume_session_id tells it to continue from a previous
session.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@webchick webchick added sdk: python Example using Python labels Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sdk: python Example using Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants