AgentAPI

repository·main·Indexed 23 days ago

https://github.com/coder/agentapi

A tool that provides an HTTP API to programmatically control coding agents such as Claude Code, Aider, and Goose by emulating a terminal session. It includes a server to wrap agents, a CLI for installation and session attachment, and a React-based chat interface. The API provides endpoints for managing messages, checking agent status, and streaming real-time updates via SSE.

Tokens
7.9K
Snippets
22
Records
53
Agent score
80%

What's inside agentapi

  1. How AgentAPI processes terminal output

    main

    AgentAPI uses an in-memory terminal emulator to translate API calls into keystrokes and parse terminal output into discrete messages.

    Message Splitting Logic

    1. Initial State: The terminal output present before any user messages are sent is treated as the agent's first message.
    2. User Input: When a user sends a message via the API, a terminal snapshot is taken before keystrokes are sent.
    3. Agent Response: After the user message is submitted, AgentAPI takes snapshots whenever the terminal output changes. It diffs these against the previous snapshot; any new text appearing below the previous content is treated as a new agent message.
    4. Updates: If the terminal changes again before the next user message, the current agent message is updated.

    TUI Element Removal

    To provide a clean chat experience, AgentAPI automatically strips:

    • User Echo: Lines containing the text of the user's last message.
    • Input Boxes: Lines at the end of a message containing common TUI elements like > or ------.
  2. How the AgentAPI E2E testing framework works

    main

    The E2E framework simulates realistic agent interactions using a script-based approach. The process follows these steps:

    1. Data Loading: The framework reads a scripted conversation from a JSON file located in testdata/.
    2. Server Initialization: It starts the AgentAPI server using a fake agent (echo.go).
    3. Scripted Interaction: The fake agent reads the JSON script and waits for messages. When a message is received, the fake agent validates it against the expectMessage field.
    4. Simulated Response: The fake agent waits for the specified thinkDurationMS and then sends the responseMessage defined in the script.
    5. Validation: The testing framework compares the actual responses received from the server against the expected outcomes defined in the test logic.
  3. Add a new end-to-end test case

    main

    To add a new test to the framework, follow these four steps:

    1. Create a script file: Create a new JSON file in the testdata/ directory with a unique name.
    2. Define the conversation: In the JSON file, define the scripted conversation. Each message object must include:
      • expectMessage: The specific message from the user that the fake agent expects to receive.
      • thinkDurationMS: The duration (in milliseconds) the fake agent should simulate 'thinking' before responding.
      • responseMessage: The message the fake agent is scripted to send back.
    3. Register the test: Add a new test case in echo_test.go that references your JSON file. Note: The name of the test case must exactly match the name of the JSON file.
    4. Execute: Run go test ./e2e to verify the new test case.
  4. Install the AgentAPI CLI

    main

    To install the agentapi binary, run the following command which detects your OS and architecture and downloads the latest release:

    OS=$(uname -s | tr "[:upper:]" "[:lower:]");
    ARCH=$(uname -m | sed "s/x86_64/amd64/;s/aarch64/arm64/");
    curl -fsSL "https://github.com/coder/agentapi/releases/latest/download/agentapi-${OS}-${ARCH}" -o agentapi && chmod +x agentapi

    Alternatively, you can download the latest release binary manually from the releases page.

    After installation, verify it by running:

    agentapi --help

    Note for macOS users: If you receive a warning that the system was unable to verify the binary, navigate to System Settings -> Privacy & Security, click "Open Anyway", and run the command again.

  5. Set up the AgentAPI Chat Interface development environment

    main

    To run the AgentAPI Chat Interface demo locally, follow these steps:

    1. Start the AgentAPI backend server: Ensure the backend is running on localhost:3284. From the root of the repository, run:
      go run main.go server -- claude
    2. Install dependencies: Use bun to install the necessary packages:
      bun install
    3. Start the frontend development server: Run the following command:
      bun run dev
    4. Access the interface: Open the following URL in your browser: http://localhost:3000/chat/?url=http://localhost:3284
    go run main.go server -- claude
    bun install
    bun run dev
  6. Run the AgentAPI end-to-end tests

    main

    To execute the end-to-end (E2E) testing framework, use the standard Go test command targeting the e2e directory. This will run the simulated agent interactions defined in the test suite.

    go test ./e2e
  7. Message types in AgentAPI

    main

    When sending messages to the agent, you can specify a MessageType to control how the content is handled:

    • user: The message is logged in the conversation history and submitted to the agent. AgentAPI will wait until the agent starts carrying out the task described in the message before responding. Success is indicated when the agent begins executing the task.
    • raw: The content is written directly to the agent's terminal session as keystrokes and is not saved in the conversation history. This is useful for sending escape sequences to the terminal. Success is indicated when the keystrokes are sent to the terminal.
  8. Configure Allowed Hosts for `agentapi server`

    main

    By default, the server only accepts requests with the localhost host header. To host AgentAPI on a different host, use the --allowed-hosts flag or the AGENTAPI_ALLOWED_HOSTS environment variable. Hosts must be hostnames only (no ports).

    • Allow all hosts: Use *.
    • Allow a specific host: Use the hostname (e.g., example.com).
    • Multiple hosts: Use a comma-separated list with the flag, or a space-separated list with the environment variable.

    Examples:

    # Using flag (comma-separated)
    agentapi server --allowed-hosts 'example.com,example.org' -- claude
    
    # Using environment variable (space-separated)
    AGENTAPI_ALLOWED_HOSTS='example.com example.org' agentapi server -- claude
    
    # Allow everything
    agentapi server --allowed-hosts '*' -- claude
    agentapi server --allowed-hosts 'example.com,example.org' -- claude
  9. Configure Allowed Origins (CORS) for `agentapi server`

    main

    To control which origins can make cross-origin requests to AgentAPI, use the --allowed-origins flag or the AGENTAPI_ALLOWED_ORIGINS environment variable. Origins must include the protocol (http:// or https://) and support wildcards.

    • Allow all origins: Use *.
    • Multiple origins: Use a comma-separated list with the flag, or a space-separated list with the environment variable.

    Examples:

    # Using flag (comma-separated)
    agentapi server --allowed-origins 'https://example.com,http://localhost:3000' -- claude
    
    # Using environment variable (space-separated)
    AGENTAPI_ALLOWED_ORIGINS='https://example.com http://localhost:3000' agentapi server -- claude
    
    # Allow everything
    agentapi server --allowed-origins '*' -- claude
    agentapi server --allowed-origins 'https://example.com,http://localhost:3000' -- claude
  10. Use the AgentAPI HTTP Endpoints

    main

    Once the server is running, you can interact with the agent using the following endpoints (default port 3284):

    • GET /messages: Returns a list of all messages in the current conversation.
    • POST /message: Sends a message to the agent. A 200 response indicates AgentAPI has detected the agent started processing.
    • GET /status: Returns the current agent status: stable or running.
    • GET /events: An SSE (Server-Sent Events) stream providing real-time message and status updates.

    Documentation: An OpenAPI schema is available at http://localhost:3284/openapi.json and a documentation UI is available at http://localhost:3284/docs.

    # Send a message
    curl -X POST localhost:3284/message \
      -H "Content-Type: application/json" \
      -d '{"content": "Hello, agent!", "type": "user"}'
    
    # Get conversation history
    curl localhost:3284/messages
  11. Configure ServerConfig for AgentAPI

    main

    The ServerConfig struct defines the operational parameters for the Server:

    FieldTypeDescription
    AgentTypemf.AgentTypeThe type of agent being served (e.g., Claude Code, Goose, Aider).
    AgentIOst.AgentIOThe interface to the agent's I/O (e.g., a PTY process or ACP interface).
    TransportTransportThe communication protocol (e.g., TransportPTY or TransportACP).
    PortintThe port on which the HTTP server will listen.
    ChatBasePathstringThe base path for serving the static chat interface.
    AllowedHosts[]stringA list of valid host headers. Supports * for all hosts.
    AllowedOrigins[]stringA list of allowed CORS origins. Supports * for all origins.
    InitialPromptstringAn optional prompt to send to the agent immediately upon startup.
    Clockquartz.ClockA clock implementation for time-sensitive operations.
    StatePersistenceConfigst.StatePersistenceConfigConfiguration for saving/loading conversation state.