AgentPaaS is a Platform-as-a-Service for deploying, managing, and running Lambda-calculus-based AI agents. It wraps the lambdagent DSL with a multi-tenant API server, persistent sessions, provider management, and monitoring.
CLI / HTTP Client
|
┌─────▼─────┐
│ FastAPI │ agentpaas/src/agentpaas/api/app.py
│ Server │ (serve --dev)
└─────┬─────┘
|
┌──────────────┼──────────────┐
| | |
┌──────▼──────┐ ┌────▼────┐ ┌───────▼───────┐
│ Agent CRUD │ │ Auth / │ │ Status / │
│ + Execution │ │ Tenant │ │ Metrics │
└──────┬──────┘ └─────────┘ └───────────────┘
|
┌──────▼──────────────────────┐
│ lambdagent Engine │
│ (Compiler + Runtime) │
│ │
│ YAML → Lambda Term → CEK │
│ ConversationLam (session) │
└──────┬──────────────────────┘
|
┌──────▼──────────────────────┐
│ Unified Provider System │
│ │
│ claude-code (no API key) │
│ anthropic (API key) │
│ ollama (local) │
│ openai (API key) │
│ dashscope (API key) │
└─────────────────────────────┘
Key components:
agentpaas serve) — REST API with multi-tenant auth, SSE streaming, OpenAPI docs at /docs.Define an agent via YAML config and deploy to the platform:
# Write YAML config
cat > my-agent.yml <<'EOF'
agentId: my-agent
name: MyAgent
type: react
model:
provider: claude-code
name: sonnet
systemPrompt: "You are a helpful research assistant."
react:
maxSteps: 10
EOF
# Lint before deploying
python -m lambdagent lint my-agent.yml
# Deploy to PaaS
python -m agentpaas agent create --name my-agent --config my-agent.yml
# Output: Agent created: ag_abc123
The agent is live immediately after agent create. The PaaS server compiles the YAML into a Lambda term at execution time, so no build step is needed. The API endpoint is:
POST /api/v1/agents/{agent_id}/run
POST /api/v1/agents/{agent_id}/run/stream (SSE)
Use agentpaas chat for interactive multi-turn conversation:
agentpaas chat my-agent
The chat command resolves the agent by name (fuzzy match) or ID, opens an interactive session with SSE streaming, and maintains conversation context server-side.
With provider: claude-code in the YAML config, no API key is required -- the agent calls Claude Code CLI directly.
Iterate on the agent config with automatic versioning:
# Edit config, then update
python -m agentpaas agent update ag_abc123 --config my-agent-v2.yml --changelog "Added search tools"
# View version history
python -m agentpaas agent versions ag_abc123
# Rollback if needed
python -m agentpaas agent rollback ag_abc123 --version 1
Each update increments the version. If the config content is unchanged, no new version is created.
AgentPaaS uses a unified provider system. The provider is specified in the agent's YAML config under model.provider:
| Provider | Type | API Key Required | Notes |
|---|---|---|---|
claude-code |
Claude Code CLI | No | Uses Claude Code Max Plan subscription |
anthropic |
Anthropic API | Yes (ANTHROPIC_API_KEY) |
Direct API access |
ollama |
Local inference | No | Requires ollama serve running locally |
openai |
OpenAI API | Yes (OPENAI_API_KEY) |
GPT models |
dashscope |
Alibaba Cloud | Yes (DASHSCOPE_API_KEY) |
Qwen models |
model:
provider: claude-code # Switch provider here
name: sonnet # Model name (provider-specific)
temperature: 0.0
When provider is not specified, the system auto-detects:
dashscope/qwen-max), use that provider.claude-* -> anthropic, gpt-* -> openai).# List providers and status
python -m agentpaas provider list
# Test a provider connection
python -m agentpaas provider test anthropic
# Add/configure a provider
python -m agentpaas provider add dashscope --api-key sk-xxxx
ConversationLam is the core mechanism for multi-turn conversation support. It wraps any LLMProvider with conversation history management.
ConversationLam(provider, prompt) = lambda x. provider(history ++ [x])
Each apply() call:
Lam |
ConversationLam |
|
|---|---|---|
| State | Stateless -- each call is independent | Stateful -- builds on all previous calls |
| History | None | Full message list with windowing |
| Use case | Single-shot tasks | Multi-turn chat, ReAct loops |
from lambdagent.conversation import ConversationLam
from lambdagent.providers.claude_code_provider import ClaudeCodeProvider
provider = ClaudeCodeProvider(config)
lam = ConversationLam(
name="agent",
provider=provider,
system_prompt="You are a helpful assistant.",
max_history_tokens=80000, # Token window limit
keep_recent_turns=20, # Minimum recent turns to keep
)
r1 = lam.apply("read the README") # Creates conversation
r2 = lam.apply("[tool result] ...") # Continues with full memory
r3 = lam.apply("summarize what we did") # Still remembers r1, r2
This is what eliminates hallucination in multi-step ReAct agents: the LLM sees its complete conversation history, not a lossy compressed state string.
By default, agents inherit globally available MCP tools. The --strict-mcp-config flag (or strictMcpConfig: true in YAML) enables MCP isolation: the agent can only access tools explicitly declared in its own config.
strictMcpConfig: true
mcp:
onlineTool:
my-server:
- search
- read_file
localTools:
- terminate
This is important for multi-tenant deployments where agents should not access each other's tools.
All endpoints are under /api/v1/ and require an API key header (X-API-Key).
| Method | Path | Description |
|---|---|---|
POST |
/agents |
Create agent |
GET |
/agents |
List agents |
GET |
/agents/{id} |
Get agent details |
PUT |
/agents/{id} |
Update agent config |
DELETE |
/agents/{id} |
Delete agent (soft) |
POST |
/agents/{id}/rollback |
Rollback to version |
GET |
/agents/{id}/versions |
List versions |
| Method | Path | Description |
|---|---|---|
POST |
/agents/{id}/run |
Execute agent (sync) |
POST |
/agents/{id}/run/stream |
Execute agent (SSE streaming) |
GET |
/agents/{id}/runs |
List run history |
POST |
/agents/{id}/runs/record |
Record external run |
| Method | Path | Description |
|---|---|---|
POST |
/auth/keys |
Create API key |
GET |
/auth/keys |
List API keys |
DELETE |
/auth/keys/{id} |
Revoke API key |
POST |
/admin/tenants |
Create tenant |
GET |
/admin/tenants/{id} |
Get tenant |
PUT |
/admin/tenants/{id}/quota |
Update quota |
| Method | Path | Description |
|---|---|---|
GET |
/status |
Platform overview |
GET |
/status/agents |
All agents status |
GET |
/status/agents/{id} |
Single agent status |
GET |
/status/agents/{id}/health |
Health score |
GET |
/metrics/overview |
Platform metrics |
GET |
/billing/usage |
Usage/billing data |
| Method | Path | Description |
|---|---|---|
GET |
/traces/{run_id} |
Get run trace |
GET |
/traces/{run_id}/tools |
Get tool calls |
POST |
/traces/{run_id}/confirm |
Confirm tool action |
| Method | Path | Description |
|---|---|---|
GET |
/health |
Server health check |
GET |
/.well-known/agent.json |
Agent discovery |
GET |
/jobs/{id} |
Async job status |
POST |
/jobs/{id}/cancel |
Cancel async job |