|
1 | 1 | # Agentomatic Studio 🎨 |
2 | 2 |
|
3 | | -Agentomatic provides a built-in visual development environment specifically designed to help you debug, inspect, and trace the execution of your agents in real-time. It completely removes the guesswork from debugging multi-agent graphs and provides native support for features like Time-Travel and Conditional Breakpoints. |
| 3 | +Agentomatic provides a built-in visual development environment specifically designed to help you debug, inspect, and trace the execution of your agents in real-time. It works with **any agent framework** — LangGraph, LangChain, CrewAI, AutoGen, or raw Python — via a universal adapter system. |
4 | 4 |
|
5 | 5 | ## Quick Start |
6 | 6 |
|
7 | | -You don't need to configure a separate repository or run separate containers. The studio is bundled directly into the `agentomatic` pip package. |
8 | | - |
9 | | -To install the optional studio dependencies and launch the server: |
| 7 | +The studio is bundled directly into the `agentomatic` pip package. No separate setup required. |
10 | 8 |
|
11 | 9 | ```bash |
12 | 10 | pip install "agentomatic[studio]" |
13 | 11 | agentomatic run --studio |
14 | 12 | ``` |
15 | 13 |
|
16 | | -The unified platform will start serving both your API endpoints at `http://localhost:8000` and the Studio UI at `http://localhost:8000/studio/ui/`. |
| 14 | +The unified platform starts serving your API endpoints at `http://localhost:8000` and the Studio UI at `http://localhost:8000/studio/ui/`. |
| 15 | + |
| 16 | +--- |
| 17 | + |
| 18 | +## Framework Support |
| 19 | + |
| 20 | +Agentomatic Studio uses a **universal adapter system** to provide the best possible debugging experience for every agent: |
| 21 | + |
| 22 | +| Capability | LangGraph | LangChain / Custom | With Decorators | |
| 23 | +|---|:---:|:---:|:---:| |
| 24 | +| Graph Topology | ✅ Real graph | ✅ Synthetic linear | ✅ Custom graph | |
| 25 | +| SSE Node Streaming | ✅ `astream_events` | ✅ Trace-based | ✅ Custom stream | |
| 26 | +| Time-Travel History | ✅ Checkpointer | ✅ In-memory traces | ✅ In-memory traces | |
| 27 | +| State Inspection | ✅ Checkpointer | ✅ Last I/O capture | ✅ Custom provider | |
| 28 | +| State Mutation | ✅ `aupdate_state` | ⚠️ In-memory only | ⚠️ In-memory only | |
| 29 | +| Breakpoints | ✅ `interrupt_before` | ❌ | ❌ | |
| 30 | +| HITL Support | ✅ Native | ❌ | ❌ | |
17 | 31 |
|
18 | 32 | --- |
19 | 33 |
|
20 | 34 | ## Key Features |
21 | 35 |
|
22 | 36 | ### 1. Live Node Streaming |
23 | | -When you execute an agent query via the chat interface, the **Graph View** maps directly to your agent's underlying LangGraph topology. As the execution progresses, nodes will visually pulse and light up. |
24 | 37 |
|
25 | | -- Server-Sent Events (SSE) stream the node transitions directly from the backend `astream_events` API. |
26 | | -- You can follow complex conditional edges and loops perfectly. |
| 38 | +When you execute an agent query, the **Graph View** maps directly to your agent's topology. As the execution progresses, nodes pulse and light up in real-time. |
| 39 | + |
| 40 | +- **LangGraph agents**: Server-Sent Events stream node transitions directly from `astream_events`. |
| 41 | +- **Other agents**: The generic adapter wraps execution with trace events that capture timing, input/output payloads, and exceptions. |
27 | 42 |
|
28 | 43 | ### 2. Time-Travel Debugging |
29 | | -Debugging deeply nested loops or non-deterministic agent flows can be difficult. Agentomatic natively records every step using the checkpointer. |
30 | 44 |
|
31 | | -- **History View**: Inside the Debug Console, the **Time Travel** tab lists all past checkpoints for the active thread. |
32 | | -- **Replay**: Click **"Replay from here"** on any historical snapshot to branch your thread. The execution will perfectly resume from that prior state, allowing you to try a different input or test a different edge path. |
| 45 | +Agentomatic records every execution step for historical replay. |
| 46 | + |
| 47 | +- **History View**: The **Time Travel** tab lists all past checkpoints (LangGraph) or execution traces (other frameworks). |
| 48 | +- **Replay**: Click **"Replay from here"** on any snapshot to branch your thread and resume from that state. |
33 | 49 |
|
34 | 50 | ### 3. Conditional Breakpoints |
35 | | -You can freeze execution right before an agent performs a critical action (like calling an external API or making a final decision). |
36 | 51 |
|
37 | | -- **Setting Breakpoints**: Right-click any node in the Graph View and select **"Add Breakpoint"**. |
38 | | -- **Execution**: When the graph reaches that node, it will pause. The node will pulse, and the backend checkpointer will suspend the thread. |
39 | | -- **Resuming**: You can either resume execution, or edit the state before continuing. |
| 52 | +Freeze execution before a critical node (LangGraph only). |
| 53 | + |
| 54 | +- **Setting Breakpoints**: Right-click any node in the Graph View → **"Add Breakpoint"**. |
| 55 | +- **Execution**: The graph pauses before the target node. The node pulses, and the thread is suspended. |
| 56 | +- **Resuming**: Resume execution or edit the state before continuing. |
40 | 57 |
|
41 | 58 | ### 4. Live State Editing |
42 | | -While the graph is suspended (either due to a breakpoint or a `Human-in-the-loop` interrupt), you can manually mutate the internal LangGraph state payload. |
43 | 59 |
|
44 | | -- **State View**: In the Debug Console, navigate to the **State** tab to see your `StateGraph` variables in real-time. |
45 | | -- **Editing**: Click **"Edit State"**, modify the JSON directly, and click **"Save"**. |
46 | | -- **Backend Mutate**: The studio fires an update command which natively triggers `graph.aupdate_state(config, values)`. When you resume execution, the agent will use your injected state! |
| 60 | +During a breakpoint pause or HITL interrupt, you can mutate the graph state. |
| 61 | + |
| 62 | +- **State View**: Navigate to the **State** tab in the Debug Console. |
| 63 | +- **Editing**: Click **"Edit State"**, modify the JSON, and click **"Save"**. |
| 64 | +- **LangGraph**: Changes are persisted via `graph.aupdate_state()`. |
| 65 | +- **Other frameworks**: Changes are stored in the in-memory trace store. |
| 66 | + |
| 67 | +--- |
| 68 | + |
| 69 | +## Studio Decorators |
| 70 | + |
| 71 | +For non-LangGraph agents, you can incrementally opt-in to richer Studio capabilities using decorators. These let you provide custom graph topologies, state providers, and stream functions. |
| 72 | + |
| 73 | +### `@studio_graph` |
| 74 | + |
| 75 | +Register a custom graph topology for your agent: |
| 76 | + |
| 77 | +```python |
| 78 | +from agentomatic.studio import studio_graph |
| 79 | + |
| 80 | +@studio_graph |
| 81 | +def my_topology(): |
| 82 | + return { |
| 83 | + "nodes": [ |
| 84 | + {"id": "__start__", "name": "Start", "type": "start"}, |
| 85 | + {"id": "fetch_data", "name": "Fetch Data", "type": "tool"}, |
| 86 | + {"id": "process", "name": "Process", "type": "agent"}, |
| 87 | + {"id": "validate", "name": "Validate", "type": "condition"}, |
| 88 | + {"id": "__end__", "name": "End", "type": "end"}, |
| 89 | + ], |
| 90 | + "edges": [ |
| 91 | + {"source": "__start__", "target": "fetch_data"}, |
| 92 | + {"source": "fetch_data", "target": "process"}, |
| 93 | + {"source": "process", "target": "validate"}, |
| 94 | + {"source": "validate", "target": "__end__", "condition": "valid"}, |
| 95 | + {"source": "validate", "target": "process", "condition": "retry"}, |
| 96 | + ] |
| 97 | + } |
| 98 | +``` |
| 99 | + |
| 100 | +### `@studio_state` |
| 101 | + |
| 102 | +Register a custom state provider: |
| 103 | + |
| 104 | +```python |
| 105 | +from agentomatic.studio import studio_state |
| 106 | + |
| 107 | +@studio_state |
| 108 | +async def get_my_state(thread_id: str) -> dict: |
| 109 | + """Return the current state for a thread.""" |
| 110 | + return await my_database.get_thread_state(thread_id) |
| 111 | +``` |
| 112 | + |
| 113 | +### `@studio_stream` |
| 114 | + |
| 115 | +Register a custom SSE event stream: |
| 116 | + |
| 117 | +```python |
| 118 | +from agentomatic.studio import studio_stream |
| 119 | +from agentomatic.studio.models import StudioRunEvent |
| 120 | + |
| 121 | +@studio_stream |
| 122 | +async def my_streamer(state, config, breakpoints): |
| 123 | + yield StudioRunEvent(event="node_start", run_id="", timestamp="...", node="my_node") |
| 124 | + result = await my_agent.process(state) |
| 125 | + yield StudioRunEvent(event="node_end", run_id="", timestamp="...", node="my_node", data={"output": result}) |
| 126 | +``` |
47 | 127 |
|
48 | 128 | --- |
49 | 129 |
|
50 | | -## How It Works Under The Hood |
| 130 | +## Architecture |
51 | 131 |
|
52 | | -The Agentomatic Studio is built on React and communicates via standard Agentomatic APIs mounted under the `/studio/` router. |
| 132 | +The Studio uses a layered adapter architecture: |
53 | 133 |
|
54 | | -- **Topology Extraction**: `GET /studio/agents/{name}/graph` extracts your node mapping via `graph.get_graph().to_json()`. |
55 | | -- **SSE Tracking**: `POST /studio/agents/{name}/runs/stream` wraps your execution config with any active breakpoints (`interrupt_before_nodes`). It streams all `on_chat_model_stream`, `on_tool_start`, and custom node events back to the UI. |
56 | | -- **State Patching**: `POST /studio/agents/{name}/threads/{tid}/state` patches the checkpoint database dynamically. |
| 134 | +``` |
| 135 | +┌──────────────────────────────────────────────────────┐ |
| 136 | +│ Studio Router │ |
| 137 | +│ (FastAPI endpoints at /studio/) │ |
| 138 | +└──────────────────┬───────────────────────────────────┘ |
| 139 | + │ resolve_adapter(agent) |
| 140 | + ┌──────────────┼──────────────────┐ |
| 141 | + │ │ │ |
| 142 | + ▼ ▼ ▼ |
| 143 | +┌────────┐ ┌──────────┐ ┌──────────────┐ |
| 144 | +│LangGraph│ │ Generic │ │ Custom │ |
| 145 | +│Adapter │ │ Adapter │ │ Adapter │ |
| 146 | +│ (full) │ │ (traces) │ │(user-defined)│ |
| 147 | +└────────┘ └──────────┘ └──────────────┘ |
| 148 | +``` |
57 | 149 |
|
58 | | -There is no "mock" data — the studio gives you 100% accurate insights into how your code operates in production. |
| 150 | +- **Studio Router**: Framework-agnostic FastAPI endpoints. |
| 151 | +- **Adapter Factory**: Automatically selects the best adapter based on the agent's configuration. |
| 152 | +- **LangGraphAdapter**: Full-featured — uses `CompiledGraph` APIs natively. |
| 153 | +- **GenericAdapter**: Trace-based — wraps `node_fn()` with timing and I/O capture. |
| 154 | +- **Custom Adapter**: User-registered via decorators or direct assignment. |
| 155 | + |
| 156 | +### API Endpoints |
| 157 | + |
| 158 | +| Endpoint | Method | Description | |
| 159 | +|---|---|---| |
| 160 | +| `/studio/info` | GET | Platform metadata and capabilities | |
| 161 | +| `/studio/agents` | GET | List agents with capabilities | |
| 162 | +| `/studio/agents/{name}/graph` | GET | Graph topology (real or synthetic) | |
| 163 | +| `/studio/agents/{name}/schemas` | GET | Input/output JSON schemas | |
| 164 | +| `/studio/agents/{name}/runs/stream` | POST | SSE-streamed execution | |
| 165 | +| `/studio/agents/{name}/threads/{tid}/state` | GET | Thread state snapshot | |
| 166 | +| `/studio/agents/{name}/threads/{tid}/state` | POST | Update thread state | |
| 167 | +| `/studio/agents/{name}/threads/{tid}/history` | GET | Checkpoint/trace history | |
0 commit comments