REST API Controllers

Purpose

The REST API Controllers subtopic addresses the need to expose the internal functionalities of the agent framework and related services over HTTP. It provides HTTP handlers responsible for managing runtime execution of agents, user session lifecycle, artifact storage and retrieval, application listings, and debugging interfaces. This subtopic is essential for enabling external clients—such as web UIs, CLI tools, or third-party integrations—to interact with the system in a standardized, stateless manner through RESTful endpoints.

Unlike the broader main topic REST API and Web Launchers, which covers the overall server setup, routing, and embedded UI serving, the REST API Controllers specifically implement the HTTP handlers that translate HTTP requests into service calls and manage HTTP responses. This includes parsing request parameters, invoking backend services, handling errors, and formatting responses, thus acting as the gateway between external API consumers and the internal agent runtime and state management components.

Functionality

The REST API Controllers are organized by domain, each targeting a distinct aspect of the system:

Key Workflows

Runtime Agent Execution Request Flow

  1. Client submits a request to run an agent on a given session with a new user message.

  2. The RuntimeAPIController decodes the request and validates the session exists.

  3. It loads the configured agent for the specified app and creates a runner instance.

  4. The runner executes the agent logic, producing a stream or batch of session events.

  5. Events are encoded and returned as JSON (synchronous) or streamed via SSE (asynchronous).

Session Creation and Management

Artifact Handling

Example Code Snippet

The RuntimeAPIController’s core function RunHandler illustrates the pattern of request decoding, agent execution, and response encoding:

func (c *RuntimeAPIController) RunHandler(rw http.ResponseWriter, req *http.Request) error {
	runAgentRequest, err := decodeRequestBody(req)
	if err != nil {
		return err
	}
	sessionEvents, err := c.runAgent(req.Context(), runAgentRequest)
	if err != nil {
		return err
	}
	var events []models.Event
	for _, event := range sessionEvents {
		events = append(events, models.FromSessionEvent(*event))
	}
	EncodeJSONResponse(events, http.StatusOK, rw)
	return nil
}

This method exemplifies the controller’s role as a bridge: converting HTTP payloads to internal structures, invoking agent runtime logic, and formatting domain events back to JSON responses.

Integration

REST API Controllers integrate tightly with several other subtopics and core components:

This layered interaction ensures that controllers act as the HTTP interface layer, delegating business logic and state management to dedicated services and agents.

Diagram

sequenceDiagram
participant Client
participant RESTController as REST API Controller
participant SessionSvc as Session Service
participant AgentLoader as Agent Loader
participant Runner
participant ArtifactSvc as Artifact Service
Client->>RESTController: HTTP Request (e.g., run agent)
RESTController->>SessionSvc: Validate session exists
SessionSvc-->>RESTController: Session info
RESTController->>AgentLoader: Load agent for app
AgentLoader-->>RESTController: Agent instance
RESTController->>Runner: Create runner with agent and services
Runner-->>Runner: Execute agent logic
Runner->>ArtifactSvc: Load/store artifacts if needed
Runner-->>RESTController: Streamed or batch session events
RESTController-->>Client: JSON or SSE response with events

This sequence diagram captures the core interaction flow when a client requests agent execution via the REST API controllers, illustrating how the controller orchestrates calls to session validation, agent loading, runner execution, and artifact management before responding.