isA Agent SDK
Build intelligent AI agents with advanced features including streaming, tools, human-in-the-loop, and durable execution.
Installation
pip install isa-agent-sdkQuick Start
from isa_agent_sdk import query
async for msg in query("Hello, world!"):
print(msg.content, end="" if msg.is_text else "\n")Latest Updates (2026-04-08)
- Production resilience shipped - Circuit breakers on all service clients, bulkhead isolation, error classification, MCP fallback, recovery playbooks, and graceful degradation.
- Observability upgraded - OpenTelemetry service tracing, structured error logging, production monitoring guide with SLOs.
- Intent-driven tier routing - SenseNode classifies intent (direct_answer, team_discovery, delegation, tool_use) and routes to FAST or REASONING model tier.
- BaseNode migration complete - All 6 production nodes migrated to ISP-compliant base classes (ReasoningNode, ToolExecutionNode). Zero deprecation warnings.
- SDK client bugs fixed - Stream exception propagation, content deduplication, event loop safety, A2A resubscribe.
- Test coverage - 3,500+ tests including chaos testing framework.
Core Concepts
Streaming vs Single Mode
The SDK supports both streaming and single-turn interactions:
# Streaming - get messages as they arrive
async for msg in query("Explain AI"):
if msg.is_text:
print(msg.content, end="")
elif msg.is_tool_use:
print(f"[Using: {msg.tool_name}]")
# Single mode - get complete response
from isa_agent_sdk import ask
result = await ask("What is 2+2?")
print(result.content)Configuration Options
Control agent behavior with ISAAgentOptions:
from isa_agent_sdk import query, ISAAgentOptions
options = ISAAgentOptions(
model="gpt-4o-mini",
allowed_tools=["web_search", "read_file"],
max_iterations=30,
skills=["code-review", "debug"]
)
async for msg in query("Review this code", options=options):
print(msg.content, end="" if msg.is_text else "\n")Tools & MCP Integration
Access a wide range of tools via the Model Context Protocol:
from isa_agent_sdk import execute_tool, get_available_tools
# Discover tools
tools = await get_available_tools(user_query="search the web")
# Execute directly
result = await execute_tool("web_search", {"query": "Python tutorials"})Human-in-the-Loop
Enable agents to pause and request human approval:
from isa_agent_sdk import request_tool_permission
authorized = await request_tool_permission(
tool_name="delete_file",
tool_args={"path": "/data/file.txt"},
reason="Cleaning up old data"
)
if authorized:
# proceed
passSkills System
Activate specialized behaviors via prompt injection:
options = ISAAgentOptions(
skills=["code-review", "debug", "refactor"]
)Built-in skills:
code-review- Expert code reviewerdebug- Systematic debuggerrefactor- Refactoring specialisttest-writer- Test coverage expertdocumentation- Technical writer
Event Triggers
Enable proactive agent activation:
from isa_agent_sdk import register_trigger, TriggerType
trigger_id = await register_trigger(
user_id="user-123",
trigger_type=TriggerType.THRESHOLD,
description="Alert on price drop",
conditions={"threshold_value": 5.0, "direction": "down"},
action_config={"prompt": "Analyze the drop"}
)A2A (Agent-to-Agent)
Run interoperable agent-to-agent communication using Agent Card discovery and JSON-RPC endpoints.
Steward (Personal)
The agent acts as a personal steward, managing tasks, calendar, and proactive automation:
# Via agent conversation
"Create a todo task called 'Review PR' with high priority"
"What's on my calendar tomorrow?"
"Alert me when Bitcoin drops 5%"
# Programmatic access
options = ISAAgentOptions(
user_id="user-123",
allowed_tools=[
"create_task", "list_tasks", "complete_task",
"create_calendar_event", "get_upcoming_events",
"register_price_alert", "list_triggers"
]
)Steward capabilities:
- Task Management (9 tools) - TODO, reminders, tracking
- Calendar (9 tools) - Events, scheduling, sync
- Event Triggers (6 tools) - Alerts, automation
Structured Outputs
Get validated JSON matching your schema:
from pydantic import BaseModel
from isa_agent_sdk import query, ISAAgentOptions, OutputFormat
class Recipe(BaseModel):
name: str
ingredients: list[str]
prep_time_minutes: int
async for msg in query(
"Find a chocolate chip cookie recipe",
options=ISAAgentOptions(
output_format=OutputFormat.from_pydantic(Recipe)
)
):
if msg.has_structured_output:
recipe = msg.parse(Recipe)
print(f"Recipe: {recipe.name}")Structured outputs documentation
Desktop Execution
Route tool execution to a user’s local desktop via Pool Manager:
from isa_agent_sdk import query, ISAAgentOptions, ExecutionEnv
options = ISAAgentOptions(
env=ExecutionEnv.DESKTOP,
user_id="xenodennis",
allowed_tools=["read_file", "write_file", "bash_execute", "glob_files"]
)
async for msg in query("Find all Python files and search for 'API'", options=options):
if msg.is_tool_use:
print(f"[Executing on desktop: {msg.tool_name}]")
elif msg.is_text:
print(msg.content, end="")The LLM intelligently decides which tools to use, and all tool calls are routed through:
SDK → Pool Manager → Desktop Agent → Local FilesystemDesktop execution documentation
Durable Execution
Checkpoint and resume long-running tasks:
from isa_agent_sdk import query, resume, ExecutionMode
options = ISAAgentOptions(
execution_mode=ExecutionMode.COLLABORATIVE,
session_id="my-task-123"
)
# Later, resume from checkpoint
async for msg in resume("my-task-123"):
print(msg.content)Advanced Features
Voice Service
Full-duplex voice conversations with audio buffering, speech-to-text rewriting, and barge-in support:
from isa_agent_sdk.services.voice import VoiceOrchestrator, VoiceSessionConfig
orchestrator = VoiceOrchestrator(
realtime_gateway_url="ws://localhost:8082/v1/realtime",
config=VoiceSessionConfig(
audio_format="pcm16",
sample_rate=16000,
barge_in_enabled=True,
turn_detection_threshold=0.5,
),
)
await orchestrator.start_session()
await orchestrator.process_audio(audio_chunk)
await orchestrator.handle_barge_in()
await orchestrator.stop_session()Components:
- VoiceOrchestrator — manages full-duplex sessions with mic state FSM (IDLE → LISTENING → THINKING → SPEAKING)
- AudioRingBuffer — fixed-capacity circular buffer for audio frames
- DictationRewriter — post-STT rewrite pipeline with filler removal, repetition cleanup, self-correction merge, and punctuation/casing
Multi-Agent Orchestration
Build agent teams with dynamic handoffs and DAG execution:
from isa_agent_sdk import Agent, ISAAgentOptions
from isa_agent_sdk.agents.swarm import SwarmOrchestrator
researcher = Agent(name="researcher", options=ISAAgentOptions(
allowed_tools=["web_search"], system_prompt="You research topics."
))
writer = Agent(name="writer", options=ISAAgentOptions(
system_prompt="You write articles based on research."
))
swarm = SwarmOrchestrator(
agents={"researcher": researcher, "writer": writer},
entry_agent="researcher",
max_handoffs=10,
)
# Sequential handoffs
result = await swarm.run("Write an article about quantum computing")
print(result.text)
print(f"Handoff trace: {result.handoff_trace}")
# DAG execution (parallel where possible)
result = await swarm.run_dag(tasks=[...], parallel=True)Also available: MultiAgentOrchestrator for router-based agent selection where a routing function picks the next agent at each step.
Delegation System
Delegate tasks to remote agent teams via A2A protocol with circuit breaker protection:
from isa_agent_sdk.delegation import (
DelegationClient, TeamDefinition, TeamRegistry, DelegationRequest
)
registry = TeamRegistry()
registry.register(TeamDefinition(
name="data-team",
description="Handles data analysis tasks",
skills=["data-analysis", "visualization"],
url="http://data-agents:8102",
auth_token_env="DATA_TEAM_TOKEN",
))
client = DelegationClient(registry, circuit_breaker_threshold=3)
result = await client.delegate(DelegationRequest(
team_name="data-team",
task="Analyze Q4 sales trends",
context={"dataset": "sales_2025"},
))
print(f"Status: {result.status}, Duration: {result.duration_ms}ms")Agent Lifecycle
Manage long-running agent processes with graceful shutdown, heartbeats, and in-flight work tracking:
from isa_agent_sdk.agents.lifecycle import AgentLifecycle
lifecycle = AgentLifecycle(
name="my-worker",
drain_timeout=30.0,
heartbeat_interval=30.0,
on_start=lambda: print("Started"),
on_stop=lambda: print("Stopped"),
)
await lifecycle.start()
# Track in-flight work — stop() waits for tracked work to complete
async with lifecycle.track_work():
await process_task()
print(lifecycle.health()) # {"state": "RUNNING", "uptime_seconds": ..., "in_flight_count": 0}
await lifecycle.stop() # Graceful drain, handles SIGTERM/SIGINTStates: INITIALIZING → RUNNING → PAUSED → DRAINING → STOPPED
Writer/Reviewer Pattern
Quality-assured content generation with isolated review context:
from isa_agent_sdk.agents.review import writer_reviewer_run
result = await writer_reviewer_run(
writer=writer_agent,
reviewer=reviewer_agent,
prompt="Write a technical blog post about microservices",
max_rounds=2,
review_instructions="Check for technical accuracy and clarity",
)
print(f"Approved: {result.approved}")
print(f"Rounds: {result.rounds_completed}")
print(result.final_text)The reviewer sees only the requirements and artifact (context-isolated), and can verdict APPROVE, REVISE, or REJECT.
Loop Detection
Automatically detect stuck agents via tool repetition, cycle detection, and state convergence:
from isa_agent_sdk.services.auto_detection.loop_detector import LoopDetector
detector = LoopDetector(
repetition_threshold=3,
cycle_min_occurrences=2,
convergence_threshold=0.9,
)
detection = detector.check_tool_loop(tool_calls)
if detection:
print(f"Loop type: {detection.loop_type}") # tool_repetition, tool_cycle
print(f"Confidence: {detection.confidence}")
print(f"Suggestion: {detection.suggestion}")Runtime Observability
Prometheus metrics for agent node execution, model calls, tool execution, and pool management:
from isa_agent_sdk.services.observability.metrics import (
record_node_execution,
record_model_call,
record_tool_execution,
metrics_text,
)
# Automatically instrumented when prometheus_client is installed
# Metrics include:
# - agent_node_duration_seconds, agent_node_executions_total
# - agent_model_call_duration_seconds, agent_model_tokens_total
# - agent_tool_duration_seconds, agent_tool_executions_total
# - agent_pool_acquire_duration_seconds, agent_pool_active_vms
# - agent_hil_interrupts_total, agent_checkpoint_operations_total
# Expose metrics endpoint
metrics_bytes = metrics_text()TLS/mTLS Support
Secure inter-service communication with TLS 1.2+ and optional mutual TLS:
from isa_agent_sdk.core.resilience.tls import create_tls_client, get_uvicorn_tls_kwargs
# Client with mTLS
client = create_tls_client(
ca_bundle="/certs/ca.pem",
client_cert="/certs/client.pem",
client_key="/certs/client-key.pem",
)
# Server with TLS
uvicorn_kwargs = get_uvicorn_tls_kwargs(
server_cert="/certs/server.pem",
server_key="/certs/server-key.pem",
)Environment variables: ISA_TLS_ENABLED, ISA_TLS_CA_BUNDLE, ISA_TLS_CLIENT_CERT, ISA_TLS_CLIENT_KEY, ISA_TLS_MIN_VERSION
Per-User Rate Limiting
Tier-based rate limiting middleware with sliding window algorithm:
from isa_agent_sdk.core.resilience.rate_limiter import RateLimitMiddleware, UserTier
# Tier limits (requests per minute / daily):
# FREE: 10/min, 100/day
# STARTER: 30/min, 1000/day
# PRO: 60/min, 5000/day
# ENTERPRISE: 120/min, 50000/day
# Add as FastAPI middleware — tier resolved from X-User-Tier header or JWT claim
app.add_middleware(RateLimitMiddleware)Response headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, Retry-After
Subscription Proxy
Manage subscription-based provider lifecycles with health tracking and circuit breakers:
from isa_agent_sdk.services.proxy import SubscriptionProxyManager
manager = SubscriptionProxyManager()
await manager.register_provider("anthropic-sub", config={...})
await manager.start_provider("anthropic-sub")
health = await manager.check_health() # HEALTHY, DEGRADED, or UNHEALTHYStates: STOPPED → STARTING → RUNNING → STOPPING → ERROR with exponential backoff on failures.
Deploy to isA Cloud
Deploy your custom agents to production:
# 1. Create deployment
curl -X POST http://localhost:8095/api/v1/deployments \
-H "X-User-ID: user123" \
-d '{"app_name": "my-agent"}'
# 2. Upload code (auto-builds)
tar -czf my-agent.tar.gz -C my-agent .
curl -X POST http://localhost:8095/api/v1/deployments/{id}/upload \
-F "file=@my-agent.tar.gz"
# 3. Deploy version
curl -X POST http://localhost:8095/api/v1/deployments/{id}/deploy \
-d '{"version": "v1.0.0", "replicas": 2}'
# 4. Query your deployed agent
curl -X POST http://localhost:8095/api/v1/apps/{id}/query \
-d '{"prompt": "Hello from the cloud!"}'Documentation
Getting Started
- Quick Start - First steps with the SDK
- Agent Client - Bidirectional client & error handling
- Streaming - Streaming vs single mode
Configuration
Features
- Tools - Tools & MCP integration
- Steward - Task, Calendar & Event tools (Personal 管家)
- Human-in-the-Loop - Approval workflows
- Structured Outputs - JSON schema & Pydantic integration
- Triggers - Event-based activation
- Checkpointing - Durable execution
- Messages - Message types reference
Advanced
- Workflows - Swarm, DAG, and multi-agent orchestration
- A2A - Agent-to-Agent protocol
- Memory - Persistent memory backends
- API Reference - Full API surface
Deployment
- Deployment Guide - Deploy agents to isA Cloud
Testing
- Testing & Verification - Verified E2E test results
API Reference
Core Functions
| Function | Description |
|---|---|
query(prompt, options) | Stream agent responses |
ask(prompt, options) | Get single response |
resume(session_id) | Resume from checkpoint |
execute_tool(name, args) | Execute tool directly |
get_available_tools() | List available tools |
Classes
| Class | Description |
|---|---|
Agent | Reusable agent with name and options |
ISAAgentOptions | Configuration for agent behavior |
ISAAgentClient | Bidirectional client (local/remote) |
SwarmOrchestrator | Multi-agent swarm with handoffs |
MultiAgentOrchestrator | Router-based agent selection |
DelegationClient | Remote team delegation via A2A |
AgentLifecycle | Long-running agent state machine |
VoiceOrchestrator | Full-duplex voice session manager |
LoopDetector | Stuck agent detection |
AgentTemplateStore | Persistent agent template versioning |
Message Types
| Type | Description |
|---|---|
text | Text content |
thinking | Chain-of-thought |
tool_use | Tool being called |
tool_result | Tool result |
checkpoint | Requires input |
voice_* | Voice session events |
error | Error message |
Execution Modes
| Mode | Description |
|---|---|
REACTIVE | Standard request-response |
COLLABORATIVE | Durable with checkpoints |
PROACTIVE | Event-driven autonomous |
Agent Client
The SDK provides two client interfaces:
ISAAgentClient (Bidirectional)
For interactive multi-turn conversations (Claude SDK compatible):
from isa_agent_sdk import ISAAgentClient
async with ISAAgentClient() as client:
await client.query("Remember the number 42")
async for msg in client.receive():
print(msg.content)
# Continue conversation
await client.query("What number did I mention?")
async for msg in client.receive():
print(msg.content) # Will recall 42
# Or use convenience method
response = await client.ask("What is 2 + 2?")ISAAgent (HTTP Client)
For deployed applications:
from isa_agent_sdk import ISAAgent
client = ISAAgent(base_url="http://localhost:8000")
# Simple chat
response = client.chat.create(message="Hello!", user_id="user123")
# Streaming
for event in client.chat.stream(message="Explain AI"):
if event.is_content:
print(event.content, end="")Examples
Code Review Agent
from isa_agent_sdk import query, ISAAgentOptions
options = ISAAgentOptions(
skills=["code-review"],
allowed_tools=["read_file"]
)
async for msg in query("Review main.py for issues", options=options):
print(msg.content, end="" if msg.is_text else "\n")Research Agent
options = ISAAgentOptions(
allowed_tools=["web_search", "fetch_url"],
max_iterations=50
)
async for msg in query("Research latest AI developments", options=options):
if msg.is_tool_use:
print(f"[Searching: {msg.tool_args}]")
elif msg.is_text:
print(msg.content, end="")File Processing Agent
options = ISAAgentOptions(
execution_mode=ExecutionMode.COLLABORATIVE,
allowed_tools=["read_file", "write_file", "bash"]
)
async for msg in query("Process all CSV files in /data", options=options):
if msg.is_checkpoint:
await msg.respond({"continue": True})
elif msg.is_text:
print(msg.content, end="")Error Handling
The SDK provides typed errors for precise error handling:
from isa_agent_sdk import (
ISASDKError, # Base error
ConnectionError, # Service connection failed
ToolExecutionError, # Tool failed
SessionError, # Session issues
ValidationError, # Input validation
)
try:
async for msg in query("Do something"):
...
except ToolExecutionError as e:
print(f"Tool {e.tool_name} failed: {e.message}")
except SessionError as e:
print(f"Session {e.session_id} error: {e}")
except ISASDKError as e:
print(f"SDK error: {e}")Environment Variables
| Variable | Description |
|---|---|
ISA_API_KEY | API key for isA platform |
ISA_MODEL_URL | Model service URL |
ISA_MCP_URL | MCP service URL |
CHECKPOINTER_BACKEND | Checkpointer backend |
Support
- Report issues at the project repository
- Check documentation for troubleshooting guides