# AGUIMock

Mock the AG-UI (Agent-to-UI) protocol for CopilotKit frontend testing. Point your frontend at aimock instead of a real agent backend and get deterministic SSE event streams from fixtures.

## Quick Start

Standalone mode typescript

    import { AGUIMock } from "@copilotkit/aimock";

    const agui = new AGUIMock();
    agui.onMessage("hello", "Hi! How can I help?");
    agui.onToolCall(/search/, "web_search", '{"q":"test"}', { result: "[]" });

    const url = await agui.start();
    // POST to url with RunAgentInput body

## How It Works

1. Client sends POST with `RunAgentInput` JSON body
2. AGUIMock matches the request against registered fixtures
3. On match: streams back AG-UI events as SSE
4. On miss with recording enabled: proxies to upstream, records events
5. On miss without recording: returns 404

## Registration API

Fluent methods for registering fixture responses:

Method | Match on | Response
--- | --- | ---
`onMessage(pattern, text)` | Last user message | Text response events
`onRun(pattern, events)` | Last user message | Raw event sequence
`onToolCall(pattern, name, args, opts?)` | Last user message | Tool call events
`onStateKey(key, snapshot)` | State key presence | State snapshot
`onReasoning(pattern, text)` | Last user message | Reasoning events
`onPredicate(fn, events)` | Custom function | Raw event sequence

## Event Types

AG-UI protocol event categories:

Category | Events | Description
--- | --- | ---
Lifecycle | `RUN_STARTED`, `RUN_FINISHED`, `RUN_ERROR`, `STEP_STARTED`, `STEP_FINISHED` | Run management
Text | `TEXT_MESSAGE_START`, `TEXT_MESSAGE_CONTENT`, `TEXT_MESSAGE_END`, `TEXT_MESSAGE_CHUNK` | Streaming text
Tool Calls | `TOOL_CALL_START`, `TOOL_CALL_ARGS`, `TOOL_CALL_END`, `TOOL_CALL_RESULT` | Tool execution
State | `STATE_SNAPSHOT`, `STATE_DELTA`, `MESSAGES_SNAPSHOT` | Frontend state sync
Activity | `ACTIVITY_SNAPSHOT`, `ACTIVITY_DELTA` | Progress indicators
Reasoning | `REASONING_START`, ..., `REASONING_END` | Chain of thought
Special | `RAW`, `CUSTOM` | Extensibility

## Event Builders

Convenience functions for constructing event sequences:

Builder | Returns
--- | ---
`buildTextResponse(text)` | Full text response with lifecycle
`buildToolCallResponse(name, args)` | Tool call with optional result
`buildStateUpdate(snapshot)` | State snapshot
`buildStateDelta(patches)` | JSON Patch incremental update
`buildErrorResponse(message)` | Error termination
`buildCompositeResponse(outputs[])` | Multiple builders merged

## Record & Replay

Record mode proxies unmatched requests to an upstream agent, saves the event stream as a fixture, and replays it on subsequent matches. Proxy-only mode forwards every time without saving, ideal for demos mixing canned and live scenarios.

Recording setup typescript

    const agui = new AGUIMock();
    agui.onMessage("hello", "Hi!"); // known scenario
    agui.enableRecording({
      upstream: "http://localhost:8000/agent",
      proxyOnly: true, // false to save fixtures
    });

## CLI Usage

CLI flags shell

    npx -p @copilotkit/aimock llmock --fixtures ./fixtures \
      --agui-record \
      --agui-upstream http://localhost:8000/agent

Flags: `--agui-record`, `--agui-upstream`, `--agui-proxy-only`

## JSON Config

aimock.json json

    {
      "agui": {
        "path": "/agui",
        "fixtures": [
          { "match": { "message": "hello" }, "text": "Hi!" }
        ]
      }
    }

## Mounting

AGUIMock implements `Mountable` and can be mounted at any path on an LLMock server via `llm.mount("/agui", agui)`. See Mount & Composition for details.