| name | agentspan |
| description | Build, run, monitor, and manage durable AI agents with AgentSpan. Use when the user wants to create agents, define tools, orchestrate multi-agent teams, handle human-in-the-loop approvals, stream events, or manage credentials. Uses the `agentspan` CLI or Python SDK. Requires AGENTSPAN_SERVER_URL. |
| allowed-tools | Bash(agentspan *), Bash(python3 *), Bash(pip install *), Bash(npm install *), Bash(chmod *), Bash(* --version), Bash(* --help), Bash(echo *), Read, Write, Edit, Grep, Glob |
AgentSpan — Build Durable AI Agents
AI agents that don't die when your process dies. Agents compile to server-side workflows, survive crashes, scale across machines, and pause for human approval.
Rules
- Always install and use the
agentspan CLI proactively. If missing, run npm install -g @agentspan-ai/agentspan. Verify with agentspan --version and agentspan doctor. Do not just tell the user to install it — do it yourself.
- Never hardcode credentials in code. Always use
agentspan credentials set --name KEY and reference via credentials=["KEY"] in Agent definitions.
- Never use
python3 -c for any purpose. Write Python to files using the Write tool, then run them.
- Server resolution:
AGENTSPAN_SERVER_URL env var or agentspan configure settings. Default local server: http://localhost:6767.
- Always check
result.is_success before using result.output — especially in autonomous agent flows.
- Agent names must be unique — alphanumeric + underscore/hyphen, start with letter or underscore.
- Tools need type hints and docstrings — schema is auto-generated from them.
- Use
result.output["result"] for text output, not result.output directly (it's a dict).
- Deploy is idempotent — safe to call on every startup.
- Serve blocks forever — triggering comes from outside (CLI, API, another process).
Updating this skill
curl -sSL https://raw.githubusercontent.com/agentspan-ai/agentspan-skills/main/install.sh | bash -s -- --all --upgrade
On Windows:
irm https://raw.githubusercontent.com/agentspan-ai/agentspan-skills/main/install.ps1 -OutFile install.ps1; .\install.ps1 -All -Upgrade
First-time setup
Follow every step in order. Do not skip steps.
Step 1 — Install the CLI
agentspan --version
If not installed:
npm --version
If npm is missing, install Node.js first (see https://nodejs.org). Then:
npm install -g @agentspan-ai/agentspan
Verify:
agentspan --version
agentspan doctor
Fallback: Only if CLI and npm are both unavailable, install the Python SDK directly:
pip install agentspan
Step 2 — Choose a server
Ask the user whether they want:
- Option A — Start a local server (development/testing)
- Option B — Connect to an existing remote server
Option A — Local server:
agentspan server start
Verify: agentspan doctor
Option B — Remote server:
agentspan configure --url https://your-server.example.com --auth-key YOUR_KEY
Step 3 — Test connectivity
agentspan doctor
agentspan agent list
If 401/403, ask user for credentials:
agentspan configure --url URL --auth-key KEY --auth-secret SECRET
Step 4 — Install Python SDK
pip install agentspan
Setup is complete.
1) Creating agents
Basic agent
from agentspan.agents import Agent, AgentRuntime
agent = Agent(
name="helper",
model="openai/gpt-4o",
instructions="You are a helpful assistant.",
)
with AgentRuntime() as rt:
result = rt.run(agent, "What is quantum computing?")
print(result.output["result"])
Agent with all options
Agent(
name="my_agent",
model="openai/gpt-4o",
instructions="You are a ...",
tools=[my_tool],
max_turns=25,
timeout_seconds=0,
max_tokens=None,
temperature=None,
output_type=MyPydanticModel,
planner=False,
thinking_budget_tokens=None,
credentials=["API_KEY"],
metadata={"team": "backend"},
)
@agent decorator
from agentspan.agents import agent
@agent(model="openai/gpt-4o", tools=[search])
def researcher():
"""You are a research assistant. Find and summarize information."""
Model formats
"openai/gpt-4o", "anthropic/claude-sonnet-4-6", "google_gemini/gemini-2.5-flash", "claude-code/opus", "aws_bedrock/anthropic.claude-v2", "azure_openai/gpt-4o", "groq/llama-3-70b", "ollama/llama3", "deepseek/deepseek-chat", "mistral/mistral-large", "grok/grok-3"
2) Tools
@tool decorator
from agentspan.agents import tool
@tool
def search(query: str) -> str:
"""Search the web for information."""
return f"Results for: {query}"
@tool(approval_required=True, credentials=["API_KEY"])
def delete_file(path: str) -> str:
"""Delete a file. Requires human approval."""
os.remove(path)
return f"Deleted {path}"
Tool functions must have type hints and a docstring. Schema is auto-generated.
ToolContext (dependency injection)
from agentspan.agents import tool, ToolContext
@tool
def lookup(query: str, context: ToolContext) -> str:
"""Search with context."""
exec_id = context.execution_id
state = context.state
deps = context.dependencies
return f"Found in execution {exec_id}"
Server-side tools (no local worker needed)
from agentspan.agents import http_tool, mcp_tool, search_tool
weather = http_tool(
name="get_weather",
description="Get weather for a city",
url="https://api.weather.com/v1/current?city=${city}",
credentials=["WEATHER_API_KEY"],
)
github = mcp_tool(
server_url="https://mcp.github.com",
tool_names=["create_issue", "list_repos"],
credentials=["GITHUB_TOKEN"],
)
Agent as tool
from agentspan.agents import agent_tool
specialist = Agent(name="math_expert", model="openai/gpt-4o", instructions="Solve math problems.")
orchestrator = Agent(
name="orchestrator",
model="openai/gpt-4o",
tools=[agent_tool(specialist, description="Call the math expert")],
)
3) Running agents
Ephemeral (one-shot)
with AgentRuntime() as rt:
result = rt.run(agent, "prompt")
result = await rt.run_async(agent, "prompt")
result = rt.run(agent, "prompt",
session_id="conv-123",
media=["https://example.com/image.png"],
timeout=60000,
credentials=["MY_API_KEY"],
)
Streaming
stream = rt.stream(agent, "prompt")
for event in stream:
print(event.type, event.content)
result = stream.get_result()
Non-blocking
handle = rt.start(agent, "prompt")
status = rt.get_status(handle.execution_id)
handle.pause()
handle.resume()
handle.cancel("no longer needed")
Production (deploy + serve)
rt.deploy(agent)
rt.serve(agent)
Trigger from outside:
agentspan agent run --name helper "What is quantum computing?"
CLI execution
agentspan agent run --name helper "What is quantum computing?"
agentspan agent run --config agent.yaml "prompt"
agentspan agent status <execution-id>
agentspan agent stream <execution-id>
4) Multi-agent orchestration
Sequential pipeline (>>)
researcher = Agent(name="researcher", model="openai/gpt-4o", instructions="Research the topic.")
writer = Agent(name="writer", model="openai/gpt-4o", instructions="Write a summary.")
pipeline = researcher >> writer
result = rt.run(pipeline, "Quantum computing breakthroughs")
Parallel
Agent(
name="analysis",
model="openai/gpt-4o",
agents=[pros_agent, cons_agent],
strategy="parallel",
)
Router
Agent(
name="team",
model="openai/gpt-4o",
agents=[billing, technical],
strategy="router",
router=router_agent,
)
Swarm (peer-to-peer handoff)
from agentspan.agents.handoff import OnTextMention
coder = Agent(name="coder", model="openai/gpt-4o", instructions="Code. Say HANDOFF_TO_QA when done.")
qa = Agent(name="qa", model="openai/gpt-4o", instructions="Test. Say HANDOFF_TO_CODER if bugs found.")
Agent(
name="dev_team",
model="openai/gpt-4o",
agents=[coder, qa],
strategy="swarm",
handoffs=[
OnTextMention(text="HANDOFF_TO_QA", target="qa"),
OnTextMention(text="HANDOFF_TO_CODER", target="coder"),
],
)
Scatter-gather (fan-out/fan-in)
from agentspan.agents import scatter_gather
coordinator = scatter_gather(
name="multi_search",
worker=Agent(name="searcher", model="openai/gpt-4o-mini", instructions="Search and summarize."),
timeout_seconds=300,
)
Strategies: handoff, sequential, parallel, router, round_robin, random, swarm, manual
5) Monitoring and managing
List agents
agentspan agent list
Get agent definition
agentspan agent get <name>
Search executions
agentspan agent execution --status FAILED --since 1d
agentspan agent execution --status RUNNING --since 7d
agentspan agent execution --status COMPLETED
Execution details
agentspan agent status <execution-id>
Stream events (SSE)
agentspan agent stream <execution-id>
Delete agent
agentspan agent delete <name>
6) Human-in-the-loop
Mark any tool with approval_required=True — execution pauses durably (days, not minutes):
@tool(approval_required=True)
def deploy_to_prod(service: str) -> str:
"""Deploy service to production. Requires approval."""
return f"Deployed {service}"
agent = Agent(name="deployer", model="openai/gpt-4o", tools=[deploy_to_prod])
When the agent calls this tool, execution pauses. Approve or reject from any machine:
agentspan agent respond <execution-id> --approve
agentspan agent respond <execution-id> --deny --reason "Not ready"
Or via Python:
handle = rt.start(agent, "Deploy the auth service")
handle.approve()
7) Guardrails
from agentspan.agents import RegexGuardrail, LLMGuardrail, Guardrail, GuardrailResult
RegexGuardrail(
name="no_emails",
patterns=[r"[\w.+-]+@[\w-]+\.[\w.-]+"],
message="Remove email addresses.",
on_fail="retry",
max_retries=3,
)
LLMGuardrail(
name="safety",
model="openai/gpt-4o-mini",
policy="Reject responses with medical advice.",
on_fail="raise",
)
def no_ssn(content: str) -> GuardrailResult:
if re.search(r"\b\d{3}-\d{2}-\d{4}\b", content):
return GuardrailResult(passed=False, message="Redact SSNs.")
return GuardrailResult(passed=True)
Guardrail(no_ssn, position="output", on_fail="retry", max_retries=3)
Failure modes: retry (auto-retry), raise (throw exception), fix (LLM auto-fix), human (escalate)
8) Memory and state
Conversation memory (chat history)
from agentspan.agents import ConversationMemory
agent = Agent(
name="chatbot",
model="openai/gpt-4o",
memory=ConversationMemory(max_messages=50),
)
Semantic memory (long-term, searchable)
from agentspan.agents import SemanticMemory
memory = SemanticMemory()
memory.add("User prefers Python over JavaScript")
memory.add("User works at Acme Corp")
results = memory.search("What language does the user prefer?")
9) Credentials management
Credentials are always resolved from the server. No env var fallback. Missing credentials cause FAILED_WITH_TERMINAL_ERROR.
agentspan credentials set GITHUB_TOKEN ghp_xxxxxxxxxxxx
agentspan credentials set OPENAI_API_KEY sk-xxxxxxxxxxxx
agentspan credentials list
Agent(
name="github_agent",
model="openai/gpt-4o",
credentials=["GITHUB_TOKEN"],
tools=[my_github_tool],
)
10) Advanced features
Structured output
from pydantic import BaseModel
class Analysis(BaseModel):
sentiment: str
confidence: float
summary: str
agent = Agent(name="analyzer", model="openai/gpt-4o", output_type=Analysis)
result = rt.run(agent, "Analyze this text...")
analysis: Analysis = result.output
Termination conditions
from agentspan.agents import TextMentionTermination, MaxMessageTermination
Agent(
name="worker",
model="openai/gpt-4o",
instructions="Say DONE when finished.",
termination=TextMentionTermination("DONE"),
)
Gates (conditional pipelines)
from agentspan.agents.gate import TextGate
checker = Agent(name="checker", model="openai/gpt-4o",
instructions="Output NO_ISSUES if everything is fine.",
gate=TextGate("NO_ISSUES"),
)
fixer = Agent(name="fixer", model="openai/gpt-4o", instructions="Fix the issue.")
pipeline = checker >> fixer
Callbacks
from agentspan.agents import CallbackHandler
class MyCallbacks(CallbackHandler):
def on_agent_start(self, **kwargs): pass
def on_agent_end(self, **kwargs): pass
def on_model_start(self, **kwargs): pass
def on_model_end(self, **kwargs): pass
Agent(name="agent", model="openai/gpt-4o", callbacks=[MyCallbacks()])
Claude Code agents
from agentspan.agents import Agent, ClaudeCode
reviewer = Agent(
name="reviewer",
model="claude-code/sonnet",
instructions="Review code for quality.",
tools=["Read", "Glob", "Grep"],
max_turns=10,
)
reviewer = Agent(
name="reviewer",
model=ClaudeCode("opus", permission_mode=ClaudeCode.PermissionMode.ACCEPT_EDITS),
instructions="Review code.",
tools=["Read", "Edit", "Bash"],
)
Code execution
Agent(
name="data_scientist",
model="openai/gpt-4o",
instructions="Write and run Python code.",
local_code_execution=True,
allowed_languages=["python"],
)
Framework integration
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
graph = create_react_agent(ChatOpenAI(model="gpt-4o"), tools=[my_tool])
with AgentRuntime() as rt:
result = rt.run(graph, "What is 15 * 7?")
from agents import Agent as OpenAIAgent
agent = OpenAIAgent(name="helper", instructions="...", model="gpt-4o")
with AgentRuntime() as rt:
result = rt.run(agent, "Hello")
AgentResult reference
result = rt.run(agent, "prompt")
result.output
result.output["result"]
result.status
result.execution_id
result.error
result.token_usage
result.finish_reason
result.is_success
result.is_failed
result.sub_results
result.print_result()
Output formatting
- Present agent results as structured summaries: execution_id, status, output, token_usage.
- For executions, show a table with execution_id, agent_name, status, start_time.
- On failures, include the error message, failed task, and finish_reason.
- Never echo credentials or secrets in output.
Troubleshooting
- CLI not found: Install via
npm install -g @agentspan-ai/agentspan, or use pip install agentspan for SDK-only.
- Connection refused: Verify
AGENTSPAN_SERVER_URL is correct and server is running. Try agentspan doctor.
- 401 Unauthorized: Run
agentspan configure with correct credentials.
- Missing credentials: Store with
agentspan credentials set KEY value. Agent gets FAILED_WITH_TERMINAL_ERROR if credential is missing.
- Tool schema errors: Ensure tool functions have type hints and docstrings.
- Agent name collision: Agent names must be unique. Check with
agentspan agent list.
- Docs: https://github.com/agentspan-ai/agentspan