agentspan/agentspan

Agentspan is now part of Orkes Conductor

496

stars

868

commits

TypeScript

primary language

Aug 21, 2026

updated

orkes.io/content/devguide/ai
agentic-workflow
agents
conductor
go
java
javascript
orkes
python
typescript
Browse cluster: Message queuing and network protocols

README

[!IMPORTANT]

Agentspan is now part of Orkes Conductor

As of August 17, 2026, Agentspan has merged into Orkes Conductor and this repository is archived (read-only).

  • New users: start with the Conductor agent quickstart
  • Existing users: your agents keep running — see the migration guide (for most code: one install line + one import path)
  • Final release: v0.4.4 — release assets remain downloadable; pip install agentspan stays installable (final: 0.2.1)
  • Issues & contributions: conductor-oss/conductor

Agentspan

AI agents that don't die when your process does.

PyPI Downloads Stars License Discord CI

DocsQuickstart180+ ExamplesDiscordAPI Reference


⭐ If you find Agentspan useful, give us a star — it helps others find the project!


https://github.com/user-attachments/assets/dd4b720d-d11c-42e8-93a6-875c5a740fd8

Agentspan is a durable runtime for AI agents, built for Conductor. Three pillars:

Long-running agents — Write an agent; it runs as long as it needs to. Minutes, hours, or until a human approves the next step. No timeout by default. If your worker process crashes, the server resumes from the last completed step when a new worker connects.

Dynamic agents (Plan-Execute) — The LLM decides what to do at runtime; Conductor locks it in and executes it deterministically. The planner emits a JSON plan once; the server compiles it into an immutable Conductor sub-workflow — no LLM randomness in orchestration, retries, or parallelism. Dynamic agents can call existing Conductor workflows as steps, bridging AI with your existing automation. → Strategy.PLAN_EXECUTE · works across Python, TypeScript, Java, C#

Event-driven agents — Trigger agents from cron schedules, Kafka topics, SQS queues, AMQP messages, webhooks, and database events. Agentspan runs on Conductor, so every event source Conductor supports is available to agents. Each trigger is a durable execution with full history. → deploy(agent, schedules=[Schedule(cron="0 0 9 * * MON-FRI")]) · Conductor event handlers

Quickstart (60 seconds)

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.ps1 | iex

Install SDKs

Build on Agentspan with the Conductor Agent SDK, available for Python, TypeScript/JavaScript, and C#/.NET:

# Python
pip install conductor-agent-sdk

# TypeScript / JavaScript
npm install @conductor-oss/conductor-agent-sdk

# C# / .NET
dotnet add package conductor-agent-sdk
export OPENAI_API_KEY=sk-...   # or any supported provider
agentspan server start         # runs on localhost:6767 with UI
# hello.py — run with: python hello.py
from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"72F and sunny in {city}"

agent = Agent(name="weatherbot", model="openai/gpt-4o", tools=[get_weather])

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC?")
    result.print_result()

Open http://localhost:6767 to see the visual execution UI.

Alternative CLI install methods
# npm
npm install -g @agentspan-ai/agentspan

# Windows — CMD / double-click
curl -fsSL https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.bat -o install.bat && install.bat

# From source
cd cli && go build -o agentspan .

# Verify setup
agentspan doctor
All supported LLM providers (15+)
ProviderEnv VarModel Format
OpenAIOPENAI_API_KEYopenai/gpt-4o
AnthropicANTHROPIC_API_KEYanthropic/claude-sonnet-4-20250514
Google GeminiGEMINI_API_KEYgoogle_gemini/gemini-pro
Azure OpenAIAZURE_OPENAI_API_KEYazure_openai/gpt-4o
Google Vertex AIGOOGLE_CLOUD_PROJECTgoogle_vertex_ai/gemini-pro
AWS BedrockAWS_ACCESS_KEY_IDaws_bedrock/anthropic.claude-v2
MistralMISTRAL_API_KEYmistral/mistral-large
CohereCOHERE_API_KEYcohere/command-r-plus
GroqGROQ_API_KEYgroq/llama-3-70b
PerplexityPERPLEXITY_API_KEYperplexity/sonar-medium
DeepSeekDEEPSEEK_API_KEYdeepseek/deepseek-chat
Grok / xAIXAI_API_KEYgrok/grok-3
HuggingFaceHUGGINGFACE_API_KEYhugging_face/meta-llama/Llama-3-70b
Stability AISTABILITY_API_KEYstabilityai/sd3.5-large
Ollama (local)OLLAMA_BASE_URLollama/llama3

Why Agentspan?

Agentspan is the execution layer, not the replacement. Use native Agentspan, or bring LangGraph, the OpenAI Agents SDK, or Google ADK — pass your existing agent to runtime.run() and it gains crash recovery, human-in-the-loop pauses, and full execution history. Your definitions stay unchanged.

CrewAILangChainAutoGenOpenAI AgentsAgentspan
Execution modelIn-memoryCheckpointsIn-memoryClient-side loopServer-side executions
Crash recoveryManual replayCheckpointer (Postgres)NoneNoneAutomatic resume
Tool scalingSingle processSingle processDistributedSingle processDistributed workers (any language)
Human approvalStdin-blockinginterrupt() + checkpointerStdin-blockingIn-processDurable pause (days, any machine)
Orchestration APICrew, Task, Agent, FlowStateGraph, Node, EdgeAssistantAgent, GroupChatAgent, Runner, HandoffOne class: Agent
Pipeline syntaxYAML + PythonGraph builder APINested class hierarchyHandoff chainsa >> b >> c
GuardrailsTask guardrailsMiddleware-basedLimitedInput/output/toolCustom, regex, LLM — 4 failure modes
Code executionDocker sandboxCommunity packagesDocker, JupyterHosted interpreter4 built-in sandboxes
MCP toolsManual configManual configManual configManual configAuto-discovered, server-side
What makes it different (detailed)
  1. True durable execution — Your agent compiles to a server-side execution. Kill the process — the agent keeps running. Poll for results from anywhere.

  2. Cross-process agent access — Every agent has an execution ID. Check status, stream events, approve tool calls, pause, resume, or cancel from any process, any machine.

  3. Distributed workers in any language — Tools execute as distributed tasks. Write workers in Python, Java, Go, or any language. Scale each tool independently.

  4. One primitive — Everything is an Agent. Single agents, multi-agent teams, nested hierarchies — one class.

  5. Real human-in-the-loop@tool(approval_required=True) pauses the execution durably. Approve days later, from any machine.

  6. Production guardrails — Custom functions, regex, or LLM judges. Four failure modes: retry, raise, fix, or human escalation.

  7. Server-side tools — HTTP endpoints and MCP servers execute as server-side tasks. No worker needed. MCP auto-discovered at compile time.

  8. Full observability — Prometheus metrics, visual execution UI, execution history, token usage tracking. OpenTelemetry available (opt-in via config).

  9. Framework compatible — Works with Google ADK, OpenAI Agents SDK, LangChain, and LangGraph. 180+ examples.

Code Examples

Agent with Tools

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def get_weather(city: str) -> dict:
    """Get current weather for a city."""
    return {"city": city, "temp": 72, "condition": "Sunny"}

@tool
def calculate(expression: str) -> dict:
    """Evaluate a math expression."""
    return {"result": eval(expression)}

agent = Agent(
    name="assistant",
    model="openai/gpt-4o",
    tools=[get_weather, calculate],
    instructions="You are a helpful assistant.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC? Also, what's 42 * 17?")
    result.print_result()

Structured Output

from pydantic import BaseModel
from conductor.ai.agents import Agent, AgentRuntime, tool

class WeatherReport(BaseModel):
    city: str
    temperature: float
    condition: str
    recommendation: str

@tool
def get_weather(city: str) -> dict:
    """Get weather data for a city."""
    return {"city": city, "temp_f": 72, "condition": "Sunny", "humidity": 45}

agent = Agent(name="reporter", model="openai/gpt-4o", tools=[get_weather], output_type=WeatherReport)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC?")
    report: WeatherReport = result.output  # Fully typed

Credential Management

Store API keys and secrets once on the server. Tools resolve them automatically at runtime — no .env files, no hardcoded keys, no secrets in git.

Step 1: Store credentials on the server

agentspan credentials set GITHUB_TOKEN ghp_xxxxxxxxxxxx
agentspan credentials set SEARCH_API_KEY xxx-your-key

Credentials are encrypted at rest (AES-256-GCM). List them with agentspan credentials list.

Step 2: Declare which credentials a tool needs

from conductor.ai.agents import Agent, AgentRuntime, tool, get_credential

# Default: tool runs in isolated subprocess with credentials as env vars
@tool(credentials=["GITHUB_TOKEN"])
def list_repos(username: str) -> dict:
    """List GitHub repos."""
    import os
    token = os.environ["GITHUB_TOKEN"]  # Auto-injected by the runtime
    return {"repos": ["repo1", "repo2"]}

# Alternative: access credentials in-process (no subprocess)
@tool(isolated=False, credentials=["SEARCH_API_KEY"])
def search(query: str) -> dict:
    """Search using API key."""
    key = get_credential("SEARCH_API_KEY")  # Resolve from server at runtime
    return {"results": ["result1"]}

Step 3: Run — credentials resolve automatically

agent = Agent(
    name="github_helper",
    model="openai/gpt-4o",
    tools=[list_repos, search],
    credentials=["GITHUB_TOKEN"],  # Agent-level credentials (shared with all tools)
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "List my GitHub repos and search for AI papers")
    result.print_result()

Credentials work with every tool type:

from conductor.ai.agents import http_tool, mcp_tool

# HTTP tools: server substitutes ${NAME} in headers at runtime
api = http_tool(
    name="weather_api", description="Get weather data",
    url="https://api.weather.com/v1/current",
    headers={"Authorization": "Bearer ${WEATHER_KEY}"},
    credentials=["WEATHER_KEY"],
)

# MCP tools: credentials passed to MCP server connection
github = mcp_tool(server_url="http://localhost:3001/mcp", credentials=["GITHUB_TOKEN"])

No credentials leave the server unencrypted. Workers resolve them via scoped execution tokens that expire with the execution. See the 11 credential examples (16_*.py through 16k_*.py) for every mode: isolated subprocess, in-process, CLI tools, HTTP headers, MCP, and framework passthrough.

Multi-Agent Handoffs

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def check_balance(account_id: str) -> dict:
    """Check account balance."""
    return {"account_id": account_id, "balance": 5432.10}

billing = Agent(name="billing", model="openai/gpt-4o",
                instructions="Handle billing inquiries.", tools=[check_balance])
technical = Agent(name="technical", model="openai/gpt-4o",
                  instructions="Handle technical issues.")

support = Agent(
    name="support", model="openai/gpt-4o",
    instructions="Route customer requests to the right team.",
    agents=[billing, technical],
    strategy="handoff",
)

with AgentRuntime() as runtime:
    result = runtime.run(support, "What's the balance on account ACC-123?")
    result.print_result()

Pipeline Composition

from conductor.ai.agents import Agent, AgentRuntime

researcher = Agent(name="researcher", model="openai/gpt-4o",
                   instructions="Research the topic and provide key facts.")
writer = Agent(name="writer", model="openai/gpt-4o",
               instructions="Write an engaging article from the research.")
editor = Agent(name="editor", model="openai/gpt-4o",
               instructions="Polish the article for publication.")

pipeline = researcher >> writer >> editor

with AgentRuntime() as runtime:
    result = runtime.run(pipeline, "AI agents in software development")
    result.print_result()

Parallel Agents

from conductor.ai.agents import Agent, AgentRuntime

market = Agent(name="market", model="openai/gpt-4o",
               instructions="Analyze market size, growth, key players.")
risk = Agent(name="risk", model="openai/gpt-4o",
             instructions="Analyze regulatory, technical, competitive risks.")

analysis = Agent(name="analysis", model="openai/gpt-4o",
                 agents=[market, risk], strategy="parallel")

with AgentRuntime() as runtime:
    result = runtime.run(analysis, "Launching an AI healthcare tool in the US")
    result.print_result()

Human-in-the-Loop (Durable)

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool(approval_required=True)
def transfer_funds(from_acct: str, to_acct: str, amount: float) -> dict:
    """Transfer funds. Requires human approval."""
    return {"status": "completed", "amount": amount}

agent = Agent(name="banker", model="openai/gpt-4o", tools=[transfer_funds])

with AgentRuntime() as runtime:
    handle = runtime.start(agent, "Transfer $5000 from checking to savings")

# Days later, from any process, any machine:
status = handle.get_status()
if status.is_waiting:
    handle.approve()   # Or: handle.reject("Amount too high")

Guardrails

from conductor.ai.agents import Agent, AgentRuntime, Guardrail, GuardrailResult, OnFail, guardrail

@guardrail
def word_limit(content: str) -> GuardrailResult:
    """Keep responses concise."""
    if len(content.split()) > 500:
        return GuardrailResult(passed=False, message="Too long. Be more concise.")
    return GuardrailResult(passed=True)

agent = Agent(
    name="concise_bot", model="openai/gpt-4o",
    guardrails=[Guardrail(word_limit, on_fail=OnFail.RETRY)],
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Explain quantum computing.")
    result.print_result()

Streaming

from conductor.ai.agents import Agent, AgentRuntime

agent = Agent(name="writer", model="openai/gpt-4o")

with AgentRuntime() as runtime:
    for event in runtime.stream(agent, "Write a haiku about Python"):
        match event.type:
            case "tool_call":       print(f"Calling {event.tool_name}...")
            case "thinking":        print(f"Thinking: {event.content}")
            case "guardrail_pass":  print(f"Guardrail passed: {event.guardrail_name}")
            case "guardrail_fail":  print(f"Guardrail failed: {event.guardrail_name}")
            case "done":            print(f"\n{event.output}")

Server-Side Tools (No Workers Needed)

from conductor.ai.agents import Agent, AgentRuntime, api_tool, http_tool, mcp_tool

# Point to any OpenAPI/Swagger spec — all endpoints auto-discovered
stripe = api_tool(
    url="https://api.stripe.com/openapi.json",
    headers={"Authorization": "Bearer ${STRIPE_KEY}"},
    credentials=["STRIPE_KEY"],
    max_tools=20,  # LLM auto-filters 300+ ops to top 20 most relevant
)

# Single HTTP endpoint (manual definition)
weather_api = http_tool(
    name="get_weather", description="Get weather for a city",
    url="https://api.weather.com/v1/current", method="GET",
    input_schema={"type": "object", "properties": {"city": {"type": "string"}}},
)

# MCP server tools (auto-discovered)
github = mcp_tool(server_url="http://localhost:6767/mcp")

agent = Agent(name="assistant", model="openai/gpt-4o", tools=[stripe, weather_api, github])

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Create a Stripe customer for alice@example.com")
    result.print_result()

Three ways to connect APIs — all server-side, no workers needed:

  • api_tool() — point to an OpenAPI/Swagger/Postman spec, all endpoints auto-discovered
  • http_tool() — define a single HTTP endpoint manually
  • mcp_tool() — connect to an MCP server, tools auto-discovered

Code Execution

from conductor.ai.agents import Agent, AgentRuntime
from conductor.ai.agents.code_executor import DockerCodeExecutor

executor = DockerCodeExecutor(image="python:3.12-slim", timeout=30)
agent = Agent(
    name="coder", model="openai/gpt-4o",
    tools=[executor.as_tool()],
    instructions="Write and execute Python code to solve problems.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Calculate the first 20 Fibonacci numbers.")
    result.print_result()

Shared State (Tool Context)

from conductor.ai.agents import Agent, AgentRuntime, tool, ToolContext

@tool
def add_item(item: str, context: ToolContext) -> str:
    """Add an item to the shared list."""
    items = context.state.get("items", [])
    items.append(item)
    context.state["items"] = items
    return f"Added '{item}'. List now has {len(items)} items."

@tool
def get_items(context: ToolContext) -> str:
    """Get all items from the shared list."""
    items = context.state.get("items", [])
    return f"Items: {', '.join(items)}" if items else "No items yet."

agent = Agent(
    name="list_manager", model="openai/gpt-4o",
    tools=[add_item, get_items],
    instructions="Manage a shared list of items.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Add apples, bananas, and cherries, then show the list.")
    result.print_result()

Agent Lifecycle Callbacks

Hook into agent, model, and tool lifecycle events with CallbackHandler classes. Multiple handlers chain per-position in list order — each one handles a single concern:

import time
from conductor.ai.agents import Agent, AgentRuntime, CallbackHandler

class TimingHandler(CallbackHandler):
    def on_agent_start(self, **kwargs):
        self.t0 = time.time()
    def on_agent_end(self, **kwargs):
        print(f"Took {time.time() - self.t0:.2f}s")

class LoggingHandler(CallbackHandler):
    def on_model_start(self, *, messages=None, **kwargs):
        print(f"Sending {len(messages or [])} messages")
    def on_model_end(self, *, llm_result=None, **kwargs):
        print(f"LLM responded: {(llm_result or '')[:80]}")

agent = Agent(
    name="my_agent",
    model="anthropic/claude-sonnet-4-6",
    instructions="You are a helpful assistant.",
    callbacks=[TimingHandler(), LoggingHandler()],
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Hello!")
    result.print_result()

Six hook positions: on_agent_start, on_agent_end, on_model_start, on_model_end, on_tool_start, on_tool_end.

Execution order: on_agent_start → (on_model_start → LLM → on_model_end)* → on_agent_end

Multi-Agent Strategies

StrategyDescription
handoff (default)LLM chooses which sub-agent handles the request
sequentialSub-agents run in order, output feeds forward (>> operator)
parallelAll sub-agents run concurrently, results aggregated
routerRouter agent or function selects the sub-agent
round_robinAgents take turns in a fixed rotation
swarmCondition-based handoffs between agents
randomRandom sub-agent selection each turn
manualHuman selects which agent speaks each turn

Examples

180+ runnable examples covering every feature across 5 frameworks:

ExampleDescription
01_basic_agent.pyHello world
02_tools.pyMultiple tools with approval
02a_simple_tools.pyTwo tools, LLM picks the right one
02b_multi_step_tools.pyChained lookups and calculations
03_structured_output.pyPydantic output types
04_http_and_mcp_tools.pyServer-side HTTP and MCP tools
04_mcp_weather.pyMCP server tools (live weather)
05_handoffs.pyAgent delegation
06_sequential_pipeline.pyagent >> agent >> agent
07_parallel_agents.pyFan-out / fan-in
08_router_agent.pyLLM routing to specialists
09_human_in_the_loop.pyApproval patterns
09b_hitl_with_feedback.pyCustom feedback (respond API)
09c_hitl_streaming.pyStreaming + HITL approval
10_guardrails.pyOutput validation + retry
11_streaming.pyReal-time events
12_long_running.pyFire-and-forget with polling
13_hierarchical_agents.pyNested agent teams
14_existing_workers.pyExisting workers as tools
15_agent_discussion.pyRound-robin debate
16_random_strategy.pyRandom agent selection
17_swarm_orchestration.pySwarm with handoff conditions
18_manual_selection.pyHuman picks which agent speaks
19_composable_termination.pyComposable termination conditions
20_constrained_transitions.pyRestricted agent transitions
21_regex_guardrails.pyRegexGuardrail (block/allow)
22_llm_guardrails.pyLLMGuardrail (AI judge)
23_token_tracking.pyToken usage and cost tracking
24_code_execution.pyCode execution sandboxes
25_semantic_memory.pyLong-term memory with retrieval
26_opentelemetry_tracing.pyOpenTelemetry spans
28_gpt_assistant_agent.pyOpenAI Assistants API wrapper
29_agent_introductions.pyAgents introduce themselves
30_multimodal_agent.pyVision model analysis
31_tool_guardrails.pyPre-execution tool validation
32_human_guardrail.pyHuman review on guardrail failure
33_external_workers.pyWorkers in other services
33_single_turn_tool.pySingle-turn tool call
34_prompt_templates.pyServer-side prompt templates
35_standalone_guardrails.pyGuardrails without agents
36_simple_agent_guardrails.pyGuardrails on simple agents
37_fix_guardrail.pyAuto-correct with on_fail="fix"
38_tech_trends.pyTech trends research
39_local_code_execution.pyLocal code sandbox
39a_docker_code_execution.pyDocker-sandboxed execution
39b_jupyter_code_execution.pyJupyter kernel execution
39c_serverless_code_execution.pyServerless execution
40_media_generation_agent.pyImage/audio/video generation
41_sequential_pipeline_tools.pyPipeline with per-stage tools
42_security_testing.pySecurity testing pipeline
43_data_security_pipeline.pyData redaction pipeline
44_safety_guardrails.pyPII detection and sanitization
45_agent_tool.pyAgent as a callable tool
46_transfer_control.pyRestricted handoff transitions
47_callbacks.pyLifecycle hooks
48_planner.pyPlanning before execution
49_include_contents.pyContext control for sub-agents
50_thinking_config.pyExtended reasoning
51_shared_state.pyShared state via ToolContext
52_nested_strategies.pyNested parallel + sequential
53_agent_lifecycle_callbacks.pyAgent-level before/after hooks
54_software_bug_assistant.pySoftware debugging agent
55_ml_engineering.pyML engineering assistant
56_rag_agent.pyRetrieval-augmented generation
57_plan_dry_run.pyPlan execution preview
58_scatter_gather.pyMassive parallel map-reduce
59_coding_agent.pyCode generation agent
60_github_coding_agent.pyGitHub integration for coding
61_github_coding_agent_chained.pyChained GitHub operations
62_cli_tool_guardrails.pyCLI tool input validation
63_deploy.pyAgent deployment
64_swarm_with_tools.pySwarm + tool orchestration
65_parallel_with_tools.pyParallel agents with tools
66_handoff_to_parallel.pyHandoff to parallel execution
67_router_to_sequential.pyRouter to sequential pipeline
68_context_condensation.pyAuto-condense long conversations
70_ce_support_agent.pyFull support agent with Zendesk, JIRA, HubSpot
71_api_tool.pyAuto-discover tools from OpenAPI/Swagger/Postman

Framework Examples:

FrameworkCountLocation
OpenAI Agents SDK10 examplesHandoffs, guardrails, streaming, multi-model
Google ADK35 examplesFull ADK compatibility, all agent types
LangChain25 examplesReAct, memory, document analysis
LangGraph44 examplesStateGraph, human-in-the-loop, subgraphs

Google ADK Compatibility

Drop-in compatibility with the Google ADK API, backed by durable execution. 32 examples included.

from google.adk.agents import Agent, SequentialAgent

researcher = Agent(name="researcher", model="gemini-2.0-flash",
                   instruction="Research the topic.", tools=[search])
writer = Agent(name="writer", model="gemini-2.0-flash",
               instruction="Write an article from the research.")

pipeline = SequentialAgent(name="pipeline", sub_agents=[researcher, writer])

Deployment

EnvironmentGuide
Local (dev)agentspan server start — zero config, SQLite
Single serverDocker / Docker Compose
ProductionKubernetes + Helm

Full deployment guide → deployment/README.md

Project Structure

├── cli/                  # Go CLI (agentspan server start/stop/logs)
├── server/               # Java runtime server (Spring Boot + Conductor)
│   └── src/
├── deployment/
│   ├── k8s/              # Kubernetes manifests
│   ├── helm/             # Helm chart
│   └── docker-compose/   # Compose stack (single node)
├── ui/                   # React execution UI (served at localhost:6767)
├── sdk/
│   ├── python/           # Python SDK
│   │   ├── src/agentspan/agents/
│   │   ├── examples/     # 70+ progressive examples
│   │   └── validation/   # Multi-model validation framework
│   └── typescript/       # TypeScript SDK
│       ├── src/
│       └── examples/
└── docs/                 # Consolidated documentation
    ├── sdk-design/       # Multi-language SDK design specs
    ├── python-sdk/       # Python SDK reference docs
    └── server/           # Server documentation

CLI Reference

agentspan server start     # Start the Agentspan server
agentspan server stop      # Stop the server
agentspan server logs      # View server logs
agentspan doctor           # Check system dependencies

Community

We're building Agentspan in the open and would love your help.

Contributing

git clone https://github.com/agentspan-ai/agentspan.git
cd agentspan/sdk/python
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest

We welcome PRs of all sizes — from typo fixes to new examples to core features.

Spread the Word

If Agentspan is useful to you, help others find it:

API Reference

See API Reference for the complete API reference and architecture guide.

License

MIT

Contributors

v1r3n

583 commits

manan164

76 commits

mp-orkes

48 commits

NicholasDCole

43 commits

agentspan/agentspan

Agentspan is now part of Orkes Conductor

496

stars

868

commits

TypeScript

primary language

Aug 21, 2026

updated

orkes.io/content/devguide/ai
agentic-workflow
agents
conductor
go
java
javascript
orkes
python
typescript
Browse cluster: Message queuing and network protocols

README

[!IMPORTANT]

Agentspan is now part of Orkes Conductor

As of August 17, 2026, Agentspan has merged into Orkes Conductor and this repository is archived (read-only).

  • New users: start with the Conductor agent quickstart
  • Existing users: your agents keep running — see the migration guide (for most code: one install line + one import path)
  • Final release: v0.4.4 — release assets remain downloadable; pip install agentspan stays installable (final: 0.2.1)
  • Issues & contributions: conductor-oss/conductor

Agentspan

AI agents that don't die when your process does.

PyPI Downloads Stars License Discord CI

DocsQuickstart180+ ExamplesDiscordAPI Reference


⭐ If you find Agentspan useful, give us a star — it helps others find the project!


https://github.com/user-attachments/assets/dd4b720d-d11c-42e8-93a6-875c5a740fd8

Agentspan is a durable runtime for AI agents, built for Conductor. Three pillars:

Long-running agents — Write an agent; it runs as long as it needs to. Minutes, hours, or until a human approves the next step. No timeout by default. If your worker process crashes, the server resumes from the last completed step when a new worker connects.

Dynamic agents (Plan-Execute) — The LLM decides what to do at runtime; Conductor locks it in and executes it deterministically. The planner emits a JSON plan once; the server compiles it into an immutable Conductor sub-workflow — no LLM randomness in orchestration, retries, or parallelism. Dynamic agents can call existing Conductor workflows as steps, bridging AI with your existing automation. → Strategy.PLAN_EXECUTE · works across Python, TypeScript, Java, C#

Event-driven agents — Trigger agents from cron schedules, Kafka topics, SQS queues, AMQP messages, webhooks, and database events. Agentspan runs on Conductor, so every event source Conductor supports is available to agents. Each trigger is a durable execution with full history. → deploy(agent, schedules=[Schedule(cron="0 0 9 * * MON-FRI")]) · Conductor event handlers

Quickstart (60 seconds)

# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.sh | sh

# Windows (PowerShell)
irm https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.ps1 | iex

Install SDKs

Build on Agentspan with the Conductor Agent SDK, available for Python, TypeScript/JavaScript, and C#/.NET:

# Python
pip install conductor-agent-sdk

# TypeScript / JavaScript
npm install @conductor-oss/conductor-agent-sdk

# C# / .NET
dotnet add package conductor-agent-sdk
export OPENAI_API_KEY=sk-...   # or any supported provider
agentspan server start         # runs on localhost:6767 with UI
# hello.py — run with: python hello.py
from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def get_weather(city: str) -> str:
    """Get current weather for a city."""
    return f"72F and sunny in {city}"

agent = Agent(name="weatherbot", model="openai/gpt-4o", tools=[get_weather])

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC?")
    result.print_result()

Open http://localhost:6767 to see the visual execution UI.

Alternative CLI install methods
# npm
npm install -g @agentspan-ai/agentspan

# Windows — CMD / double-click
curl -fsSL https://raw.githubusercontent.com/agentspan-ai/agentspan/main/cli/install.bat -o install.bat && install.bat

# From source
cd cli && go build -o agentspan .

# Verify setup
agentspan doctor
All supported LLM providers (15+)
ProviderEnv VarModel Format
OpenAIOPENAI_API_KEYopenai/gpt-4o
AnthropicANTHROPIC_API_KEYanthropic/claude-sonnet-4-20250514
Google GeminiGEMINI_API_KEYgoogle_gemini/gemini-pro
Azure OpenAIAZURE_OPENAI_API_KEYazure_openai/gpt-4o
Google Vertex AIGOOGLE_CLOUD_PROJECTgoogle_vertex_ai/gemini-pro
AWS BedrockAWS_ACCESS_KEY_IDaws_bedrock/anthropic.claude-v2
MistralMISTRAL_API_KEYmistral/mistral-large
CohereCOHERE_API_KEYcohere/command-r-plus
GroqGROQ_API_KEYgroq/llama-3-70b
PerplexityPERPLEXITY_API_KEYperplexity/sonar-medium
DeepSeekDEEPSEEK_API_KEYdeepseek/deepseek-chat
Grok / xAIXAI_API_KEYgrok/grok-3
HuggingFaceHUGGINGFACE_API_KEYhugging_face/meta-llama/Llama-3-70b
Stability AISTABILITY_API_KEYstabilityai/sd3.5-large
Ollama (local)OLLAMA_BASE_URLollama/llama3

Why Agentspan?

Agentspan is the execution layer, not the replacement. Use native Agentspan, or bring LangGraph, the OpenAI Agents SDK, or Google ADK — pass your existing agent to runtime.run() and it gains crash recovery, human-in-the-loop pauses, and full execution history. Your definitions stay unchanged.

CrewAILangChainAutoGenOpenAI AgentsAgentspan
Execution modelIn-memoryCheckpointsIn-memoryClient-side loopServer-side executions
Crash recoveryManual replayCheckpointer (Postgres)NoneNoneAutomatic resume
Tool scalingSingle processSingle processDistributedSingle processDistributed workers (any language)
Human approvalStdin-blockinginterrupt() + checkpointerStdin-blockingIn-processDurable pause (days, any machine)
Orchestration APICrew, Task, Agent, FlowStateGraph, Node, EdgeAssistantAgent, GroupChatAgent, Runner, HandoffOne class: Agent
Pipeline syntaxYAML + PythonGraph builder APINested class hierarchyHandoff chainsa >> b >> c
GuardrailsTask guardrailsMiddleware-basedLimitedInput/output/toolCustom, regex, LLM — 4 failure modes
Code executionDocker sandboxCommunity packagesDocker, JupyterHosted interpreter4 built-in sandboxes
MCP toolsManual configManual configManual configManual configAuto-discovered, server-side
What makes it different (detailed)
  1. True durable execution — Your agent compiles to a server-side execution. Kill the process — the agent keeps running. Poll for results from anywhere.

  2. Cross-process agent access — Every agent has an execution ID. Check status, stream events, approve tool calls, pause, resume, or cancel from any process, any machine.

  3. Distributed workers in any language — Tools execute as distributed tasks. Write workers in Python, Java, Go, or any language. Scale each tool independently.

  4. One primitive — Everything is an Agent. Single agents, multi-agent teams, nested hierarchies — one class.

  5. Real human-in-the-loop@tool(approval_required=True) pauses the execution durably. Approve days later, from any machine.

  6. Production guardrails — Custom functions, regex, or LLM judges. Four failure modes: retry, raise, fix, or human escalation.

  7. Server-side tools — HTTP endpoints and MCP servers execute as server-side tasks. No worker needed. MCP auto-discovered at compile time.

  8. Full observability — Prometheus metrics, visual execution UI, execution history, token usage tracking. OpenTelemetry available (opt-in via config).

  9. Framework compatible — Works with Google ADK, OpenAI Agents SDK, LangChain, and LangGraph. 180+ examples.

Code Examples

Agent with Tools

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def get_weather(city: str) -> dict:
    """Get current weather for a city."""
    return {"city": city, "temp": 72, "condition": "Sunny"}

@tool
def calculate(expression: str) -> dict:
    """Evaluate a math expression."""
    return {"result": eval(expression)}

agent = Agent(
    name="assistant",
    model="openai/gpt-4o",
    tools=[get_weather, calculate],
    instructions="You are a helpful assistant.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC? Also, what's 42 * 17?")
    result.print_result()

Structured Output

from pydantic import BaseModel
from conductor.ai.agents import Agent, AgentRuntime, tool

class WeatherReport(BaseModel):
    city: str
    temperature: float
    condition: str
    recommendation: str

@tool
def get_weather(city: str) -> dict:
    """Get weather data for a city."""
    return {"city": city, "temp_f": 72, "condition": "Sunny", "humidity": 45}

agent = Agent(name="reporter", model="openai/gpt-4o", tools=[get_weather], output_type=WeatherReport)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "What's the weather in NYC?")
    report: WeatherReport = result.output  # Fully typed

Credential Management

Store API keys and secrets once on the server. Tools resolve them automatically at runtime — no .env files, no hardcoded keys, no secrets in git.

Step 1: Store credentials on the server

agentspan credentials set GITHUB_TOKEN ghp_xxxxxxxxxxxx
agentspan credentials set SEARCH_API_KEY xxx-your-key

Credentials are encrypted at rest (AES-256-GCM). List them with agentspan credentials list.

Step 2: Declare which credentials a tool needs

from conductor.ai.agents import Agent, AgentRuntime, tool, get_credential

# Default: tool runs in isolated subprocess with credentials as env vars
@tool(credentials=["GITHUB_TOKEN"])
def list_repos(username: str) -> dict:
    """List GitHub repos."""
    import os
    token = os.environ["GITHUB_TOKEN"]  # Auto-injected by the runtime
    return {"repos": ["repo1", "repo2"]}

# Alternative: access credentials in-process (no subprocess)
@tool(isolated=False, credentials=["SEARCH_API_KEY"])
def search(query: str) -> dict:
    """Search using API key."""
    key = get_credential("SEARCH_API_KEY")  # Resolve from server at runtime
    return {"results": ["result1"]}

Step 3: Run — credentials resolve automatically

agent = Agent(
    name="github_helper",
    model="openai/gpt-4o",
    tools=[list_repos, search],
    credentials=["GITHUB_TOKEN"],  # Agent-level credentials (shared with all tools)
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "List my GitHub repos and search for AI papers")
    result.print_result()

Credentials work with every tool type:

from conductor.ai.agents import http_tool, mcp_tool

# HTTP tools: server substitutes ${NAME} in headers at runtime
api = http_tool(
    name="weather_api", description="Get weather data",
    url="https://api.weather.com/v1/current",
    headers={"Authorization": "Bearer ${WEATHER_KEY}"},
    credentials=["WEATHER_KEY"],
)

# MCP tools: credentials passed to MCP server connection
github = mcp_tool(server_url="http://localhost:3001/mcp", credentials=["GITHUB_TOKEN"])

No credentials leave the server unencrypted. Workers resolve them via scoped execution tokens that expire with the execution. See the 11 credential examples (16_*.py through 16k_*.py) for every mode: isolated subprocess, in-process, CLI tools, HTTP headers, MCP, and framework passthrough.

Multi-Agent Handoffs

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool
def check_balance(account_id: str) -> dict:
    """Check account balance."""
    return {"account_id": account_id, "balance": 5432.10}

billing = Agent(name="billing", model="openai/gpt-4o",
                instructions="Handle billing inquiries.", tools=[check_balance])
technical = Agent(name="technical", model="openai/gpt-4o",
                  instructions="Handle technical issues.")

support = Agent(
    name="support", model="openai/gpt-4o",
    instructions="Route customer requests to the right team.",
    agents=[billing, technical],
    strategy="handoff",
)

with AgentRuntime() as runtime:
    result = runtime.run(support, "What's the balance on account ACC-123?")
    result.print_result()

Pipeline Composition

from conductor.ai.agents import Agent, AgentRuntime

researcher = Agent(name="researcher", model="openai/gpt-4o",
                   instructions="Research the topic and provide key facts.")
writer = Agent(name="writer", model="openai/gpt-4o",
               instructions="Write an engaging article from the research.")
editor = Agent(name="editor", model="openai/gpt-4o",
               instructions="Polish the article for publication.")

pipeline = researcher >> writer >> editor

with AgentRuntime() as runtime:
    result = runtime.run(pipeline, "AI agents in software development")
    result.print_result()

Parallel Agents

from conductor.ai.agents import Agent, AgentRuntime

market = Agent(name="market", model="openai/gpt-4o",
               instructions="Analyze market size, growth, key players.")
risk = Agent(name="risk", model="openai/gpt-4o",
             instructions="Analyze regulatory, technical, competitive risks.")

analysis = Agent(name="analysis", model="openai/gpt-4o",
                 agents=[market, risk], strategy="parallel")

with AgentRuntime() as runtime:
    result = runtime.run(analysis, "Launching an AI healthcare tool in the US")
    result.print_result()

Human-in-the-Loop (Durable)

from conductor.ai.agents import Agent, AgentRuntime, tool

@tool(approval_required=True)
def transfer_funds(from_acct: str, to_acct: str, amount: float) -> dict:
    """Transfer funds. Requires human approval."""
    return {"status": "completed", "amount": amount}

agent = Agent(name="banker", model="openai/gpt-4o", tools=[transfer_funds])

with AgentRuntime() as runtime:
    handle = runtime.start(agent, "Transfer $5000 from checking to savings")

# Days later, from any process, any machine:
status = handle.get_status()
if status.is_waiting:
    handle.approve()   # Or: handle.reject("Amount too high")

Guardrails

from conductor.ai.agents import Agent, AgentRuntime, Guardrail, GuardrailResult, OnFail, guardrail

@guardrail
def word_limit(content: str) -> GuardrailResult:
    """Keep responses concise."""
    if len(content.split()) > 500:
        return GuardrailResult(passed=False, message="Too long. Be more concise.")
    return GuardrailResult(passed=True)

agent = Agent(
    name="concise_bot", model="openai/gpt-4o",
    guardrails=[Guardrail(word_limit, on_fail=OnFail.RETRY)],
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Explain quantum computing.")
    result.print_result()

Streaming

from conductor.ai.agents import Agent, AgentRuntime

agent = Agent(name="writer", model="openai/gpt-4o")

with AgentRuntime() as runtime:
    for event in runtime.stream(agent, "Write a haiku about Python"):
        match event.type:
            case "tool_call":       print(f"Calling {event.tool_name}...")
            case "thinking":        print(f"Thinking: {event.content}")
            case "guardrail_pass":  print(f"Guardrail passed: {event.guardrail_name}")
            case "guardrail_fail":  print(f"Guardrail failed: {event.guardrail_name}")
            case "done":            print(f"\n{event.output}")

Server-Side Tools (No Workers Needed)

from conductor.ai.agents import Agent, AgentRuntime, api_tool, http_tool, mcp_tool

# Point to any OpenAPI/Swagger spec — all endpoints auto-discovered
stripe = api_tool(
    url="https://api.stripe.com/openapi.json",
    headers={"Authorization": "Bearer ${STRIPE_KEY}"},
    credentials=["STRIPE_KEY"],
    max_tools=20,  # LLM auto-filters 300+ ops to top 20 most relevant
)

# Single HTTP endpoint (manual definition)
weather_api = http_tool(
    name="get_weather", description="Get weather for a city",
    url="https://api.weather.com/v1/current", method="GET",
    input_schema={"type": "object", "properties": {"city": {"type": "string"}}},
)

# MCP server tools (auto-discovered)
github = mcp_tool(server_url="http://localhost:6767/mcp")

agent = Agent(name="assistant", model="openai/gpt-4o", tools=[stripe, weather_api, github])

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Create a Stripe customer for alice@example.com")
    result.print_result()

Three ways to connect APIs — all server-side, no workers needed:

  • api_tool() — point to an OpenAPI/Swagger/Postman spec, all endpoints auto-discovered
  • http_tool() — define a single HTTP endpoint manually
  • mcp_tool() — connect to an MCP server, tools auto-discovered

Code Execution

from conductor.ai.agents import Agent, AgentRuntime
from conductor.ai.agents.code_executor import DockerCodeExecutor

executor = DockerCodeExecutor(image="python:3.12-slim", timeout=30)
agent = Agent(
    name="coder", model="openai/gpt-4o",
    tools=[executor.as_tool()],
    instructions="Write and execute Python code to solve problems.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Calculate the first 20 Fibonacci numbers.")
    result.print_result()

Shared State (Tool Context)

from conductor.ai.agents import Agent, AgentRuntime, tool, ToolContext

@tool
def add_item(item: str, context: ToolContext) -> str:
    """Add an item to the shared list."""
    items = context.state.get("items", [])
    items.append(item)
    context.state["items"] = items
    return f"Added '{item}'. List now has {len(items)} items."

@tool
def get_items(context: ToolContext) -> str:
    """Get all items from the shared list."""
    items = context.state.get("items", [])
    return f"Items: {', '.join(items)}" if items else "No items yet."

agent = Agent(
    name="list_manager", model="openai/gpt-4o",
    tools=[add_item, get_items],
    instructions="Manage a shared list of items.",
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Add apples, bananas, and cherries, then show the list.")
    result.print_result()

Agent Lifecycle Callbacks

Hook into agent, model, and tool lifecycle events with CallbackHandler classes. Multiple handlers chain per-position in list order — each one handles a single concern:

import time
from conductor.ai.agents import Agent, AgentRuntime, CallbackHandler

class TimingHandler(CallbackHandler):
    def on_agent_start(self, **kwargs):
        self.t0 = time.time()
    def on_agent_end(self, **kwargs):
        print(f"Took {time.time() - self.t0:.2f}s")

class LoggingHandler(CallbackHandler):
    def on_model_start(self, *, messages=None, **kwargs):
        print(f"Sending {len(messages or [])} messages")
    def on_model_end(self, *, llm_result=None, **kwargs):
        print(f"LLM responded: {(llm_result or '')[:80]}")

agent = Agent(
    name="my_agent",
    model="anthropic/claude-sonnet-4-6",
    instructions="You are a helpful assistant.",
    callbacks=[TimingHandler(), LoggingHandler()],
)

with AgentRuntime() as runtime:
    result = runtime.run(agent, "Hello!")
    result.print_result()

Six hook positions: on_agent_start, on_agent_end, on_model_start, on_model_end, on_tool_start, on_tool_end.

Execution order: on_agent_start → (on_model_start → LLM → on_model_end)* → on_agent_end

Multi-Agent Strategies

StrategyDescription
handoff (default)LLM chooses which sub-agent handles the request
sequentialSub-agents run in order, output feeds forward (>> operator)
parallelAll sub-agents run concurrently, results aggregated
routerRouter agent or function selects the sub-agent
round_robinAgents take turns in a fixed rotation
swarmCondition-based handoffs between agents
randomRandom sub-agent selection each turn
manualHuman selects which agent speaks each turn

Examples

180+ runnable examples covering every feature across 5 frameworks:

ExampleDescription
01_basic_agent.pyHello world
02_tools.pyMultiple tools with approval
02a_simple_tools.pyTwo tools, LLM picks the right one
02b_multi_step_tools.pyChained lookups and calculations
03_structured_output.pyPydantic output types
04_http_and_mcp_tools.pyServer-side HTTP and MCP tools
04_mcp_weather.pyMCP server tools (live weather)
05_handoffs.pyAgent delegation
06_sequential_pipeline.pyagent >> agent >> agent
07_parallel_agents.pyFan-out / fan-in
08_router_agent.pyLLM routing to specialists
09_human_in_the_loop.pyApproval patterns
09b_hitl_with_feedback.pyCustom feedback (respond API)
09c_hitl_streaming.pyStreaming + HITL approval
10_guardrails.pyOutput validation + retry
11_streaming.pyReal-time events
12_long_running.pyFire-and-forget with polling
13_hierarchical_agents.pyNested agent teams
14_existing_workers.pyExisting workers as tools
15_agent_discussion.pyRound-robin debate
16_random_strategy.pyRandom agent selection
17_swarm_orchestration.pySwarm with handoff conditions
18_manual_selection.pyHuman picks which agent speaks
19_composable_termination.pyComposable termination conditions
20_constrained_transitions.pyRestricted agent transitions
21_regex_guardrails.pyRegexGuardrail (block/allow)
22_llm_guardrails.pyLLMGuardrail (AI judge)
23_token_tracking.pyToken usage and cost tracking
24_code_execution.pyCode execution sandboxes
25_semantic_memory.pyLong-term memory with retrieval
26_opentelemetry_tracing.pyOpenTelemetry spans
28_gpt_assistant_agent.pyOpenAI Assistants API wrapper
29_agent_introductions.pyAgents introduce themselves
30_multimodal_agent.pyVision model analysis
31_tool_guardrails.pyPre-execution tool validation
32_human_guardrail.pyHuman review on guardrail failure
33_external_workers.pyWorkers in other services
33_single_turn_tool.pySingle-turn tool call
34_prompt_templates.pyServer-side prompt templates
35_standalone_guardrails.pyGuardrails without agents
36_simple_agent_guardrails.pyGuardrails on simple agents
37_fix_guardrail.pyAuto-correct with on_fail="fix"
38_tech_trends.pyTech trends research
39_local_code_execution.pyLocal code sandbox
39a_docker_code_execution.pyDocker-sandboxed execution
39b_jupyter_code_execution.pyJupyter kernel execution
39c_serverless_code_execution.pyServerless execution
40_media_generation_agent.pyImage/audio/video generation
41_sequential_pipeline_tools.pyPipeline with per-stage tools
42_security_testing.pySecurity testing pipeline
43_data_security_pipeline.pyData redaction pipeline
44_safety_guardrails.pyPII detection and sanitization
45_agent_tool.pyAgent as a callable tool
46_transfer_control.pyRestricted handoff transitions
47_callbacks.pyLifecycle hooks
48_planner.pyPlanning before execution
49_include_contents.pyContext control for sub-agents
50_thinking_config.pyExtended reasoning
51_shared_state.pyShared state via ToolContext
52_nested_strategies.pyNested parallel + sequential
53_agent_lifecycle_callbacks.pyAgent-level before/after hooks
54_software_bug_assistant.pySoftware debugging agent
55_ml_engineering.pyML engineering assistant
56_rag_agent.pyRetrieval-augmented generation
57_plan_dry_run.pyPlan execution preview
58_scatter_gather.pyMassive parallel map-reduce
59_coding_agent.pyCode generation agent
60_github_coding_agent.pyGitHub integration for coding
61_github_coding_agent_chained.pyChained GitHub operations
62_cli_tool_guardrails.pyCLI tool input validation
63_deploy.pyAgent deployment
64_swarm_with_tools.pySwarm + tool orchestration
65_parallel_with_tools.pyParallel agents with tools
66_handoff_to_parallel.pyHandoff to parallel execution
67_router_to_sequential.pyRouter to sequential pipeline
68_context_condensation.pyAuto-condense long conversations
70_ce_support_agent.pyFull support agent with Zendesk, JIRA, HubSpot
71_api_tool.pyAuto-discover tools from OpenAPI/Swagger/Postman

Framework Examples:

FrameworkCountLocation
OpenAI Agents SDK10 examplesHandoffs, guardrails, streaming, multi-model
Google ADK35 examplesFull ADK compatibility, all agent types
LangChain25 examplesReAct, memory, document analysis
LangGraph44 examplesStateGraph, human-in-the-loop, subgraphs

Google ADK Compatibility

Drop-in compatibility with the Google ADK API, backed by durable execution. 32 examples included.

from google.adk.agents import Agent, SequentialAgent

researcher = Agent(name="researcher", model="gemini-2.0-flash",
                   instruction="Research the topic.", tools=[search])
writer = Agent(name="writer", model="gemini-2.0-flash",
               instruction="Write an article from the research.")

pipeline = SequentialAgent(name="pipeline", sub_agents=[researcher, writer])

Deployment

EnvironmentGuide
Local (dev)agentspan server start — zero config, SQLite
Single serverDocker / Docker Compose
ProductionKubernetes + Helm

Full deployment guide → deployment/README.md

Project Structure

├── cli/                  # Go CLI (agentspan server start/stop/logs)
├── server/               # Java runtime server (Spring Boot + Conductor)
│   └── src/
├── deployment/
│   ├── k8s/              # Kubernetes manifests
│   ├── helm/             # Helm chart
│   └── docker-compose/   # Compose stack (single node)
├── ui/                   # React execution UI (served at localhost:6767)
├── sdk/
│   ├── python/           # Python SDK
│   │   ├── src/agentspan/agents/
│   │   ├── examples/     # 70+ progressive examples
│   │   └── validation/   # Multi-model validation framework
│   └── typescript/       # TypeScript SDK
│       ├── src/
│       └── examples/
└── docs/                 # Consolidated documentation
    ├── sdk-design/       # Multi-language SDK design specs
    ├── python-sdk/       # Python SDK reference docs
    └── server/           # Server documentation

CLI Reference

agentspan server start     # Start the Agentspan server
agentspan server stop      # Stop the server
agentspan server logs      # View server logs
agentspan doctor           # Check system dependencies

Community

We're building Agentspan in the open and would love your help.

Contributing

git clone https://github.com/agentspan-ai/agentspan.git
cd agentspan/sdk/python
uv venv && source .venv/bin/activate
uv pip install -e ".[dev]"
pytest

We welcome PRs of all sizes — from typo fixes to new examples to core features.

Spread the Word

If Agentspan is useful to you, help others find it:

API Reference

See API Reference for the complete API reference and architecture guide.

License

MIT

Contributors

v1r3n

583 commits

manan164

76 commits

mp-orkes

48 commits

NicholasDCole

43 commits

Languages

TypeScript

33.1%

Python

23.7%

Java

21.0%

JavaScript

10.7%

C#

7.1%

Go

3.4%