# AgentPaaS Platform Documentation 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. --- ## Architecture Overview ``` 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:** - **FastAPI Server** (`agentpaas serve`) — REST API with multi-tenant auth, SSE streaming, OpenAPI docs at `/docs`. - **Agent Store** — SQLite/Postgres-backed CRUD for agent configs, versions, run history. - **lambdagent Engine** — Compiles YAML into Lambda terms, executes via CEK machine with ReAct loops, tool routing, and beta-reduction tracing. - **ConversationLam** — Session-persistent Lambda abstraction that maintains conversation history across turns. - **Unified Provider System** — Five core providers with automatic detection and YAML-based switching. --- ## Agent Lifecycle ### 1. Create Define an agent via YAML config and deploy to the platform: ```bash # 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 ``` ### 2. Deploy 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) ``` ### 3. Chat (Interactive) Use `agentpaas chat` for interactive multi-turn conversation: ```bash 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. ### 4. Update Iterate on the agent config with automatic versioning: ```bash # 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. --- ## Provider Configuration 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 | ### Provider in YAML ```yaml model: provider: claude-code # Switch provider here name: sonnet # Model name (provider-specific) temperature: 0.0 ``` ### Provider detection priority When `provider` is not specified, the system auto-detects: 1. If model name has a known prefix (e.g., `dashscope/qwen-max`), use that provider. 2. If model name matches known patterns (e.g., `claude-*` -> anthropic, `gpt-*` -> openai). 3. Fall back to environment variable detection. ### Managing providers via CLI ```bash # 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 ``` --- ## Session Persistence via ConversationLam `ConversationLam` is the core mechanism for multi-turn conversation support. It wraps any `LLMProvider` with conversation history management. ### Lambda semantics ``` ConversationLam(provider, prompt) = lambda x. provider(history ++ [x]) ``` Each `apply()` call: 1. Appends the input as a user message to the history. 2. Calls the provider with the full conversation (or windowed subset). 3. Records the assistant response. 4. Returns the response. ### Key difference from stateless Lam | | `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 | ### Configuration ```python 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. --- ## MCP Isolation: --strict-mcp-config 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. ```yaml 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. --- ## API Endpoints Overview All endpoints are under `/api/v1/` and require an API key header (`X-API-Key`). ### Agents | 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 | ### Execution | 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 | ### Auth & Tenants | 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 | ### Monitoring | 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 | ### Traces | 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 | ### Other | 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 |