runtime.go
Overview
This file implements the RuntimeAPIController, the primary REST API controller responsible for executing AI agents within user sessions. It handles HTTP requests to run agents synchronously or stream their output via Server-Sent Events (SSE). The controller validates session existence, loads the specified agent, configures the agent runner, invokes the agent with the provided user message, and returns the resulting session events to clients.
The controller serves as the gateway between external API clients and the internal agent execution framework, coordinating interactions with the session service, artifact service, and agent loader components.
This file falls under the REST API Controllers subtopic, which covers HTTP handlers that bridge REST API requests to underlying agent and session services.
Types and Functions
RuntimeAPIController
type RuntimeAPIController struct {
sessionService session.Service
artifactService artifact.Service
agentLoader agent.Loader
}
Purpose: Manages runtime agent execution API endpoints.
Fields:
sessionService: Interface to manage sessions and their state (Session Management).artifactService: Interface for managing artifacts related to sessions (Artifact Management).agentLoader: Loads agent instances by application name (LLM Integration and Agents).
NewRuntimeAPIController
func NewRuntimeAPIController(sessionService session.Service, agentLoader agent.Loader, artifactService artifact.Service) *RuntimeAPIController
Purpose: Constructor to instantiate a new
RuntimeAPIController.Parameters:
sessionService: Session management service instance.agentLoader: Agent loading service instance.artifactService: Artifact management service instance.
Returns: Pointer to a new
RuntimeAPIController.
RunHandler
func (c *RuntimeAPIController) RunHandler(rw http.ResponseWriter, req *http.Request) error
Purpose: Handles synchronous HTTP requests to run an agent for a specified session and user message.
Workflow:
Decodes the HTTP request body into a
RunAgentRequest.Validates the session exists.
Runs the agent using
runAgent.Converts internal session events into API response models (
models.Event).Encodes and writes a JSON response with HTTP 200 status.
Parameters:
rw: HTTP response writer.req: HTTP request.
Returns: Error if decoding, validation, or agent execution fails.
Usage Example:
Typically invoked by the REST API router on POST/run.
RunSSEHandler
func (c *RuntimeAPIController) RunSSEHandler(rw http.ResponseWriter, req *http.Request) error
Purpose: Handles HTTP requests to run an agent and stream events incrementally via Server-Sent Events (SSE).
Details:
Checks that the response writer supports flushing.
Sets headers for SSE (
Content-Type: text/event-stream, etc.).Decodes request, validates session, loads the runner.
Executes the agent run.
Streams session events as SSE data messages, flushing after each event.
Handles errors during streaming gracefully by sending error text to client.
Parameters:
rw: HTTP response writer supporting streaming.req: HTTP request.
Returns: Error on any step failure or streaming write errors.
Usage Example:
Used by clients needing real-time incremental event delivery, e.g., POST/run_sse.
runAgent (private method)
func (c *RuntimeAPIController) runAgent(ctx context.Context, runAgentRequest models.RunAgentRequest) ([]*session.Event, error)
Purpose: Core logic to execute the agent run synchronously and collect all resulting session events.
Steps:
Validates the session exists.
Loads the agent and creates a runner configured for streaming or non-streaming mode.
Calls
runner.Runwith the user message and run configuration.Collects streamed session events, returning an error if any event stream error occurs.
Parameters:
ctx: Context for request cancellation and deadlines.runAgentRequest: Structured request containing appName, userId, sessionId, and new message.
Returns:
Slice of pointers to
session.Event.Error if session validation, agent loading, or agent execution fails.
flashEvent (private function)
func flashEvent(flusher http.Flusher, rw http.ResponseWriter, event session.Event) error
Purpose: Writes a single SSE event to the HTTP response stream.
Details:
Writes the
data:prefix.Encodes the event as JSON.
Writes a newline and flushes the stream.
Returns errors if writing or encoding fails.
Parameters:
flusher: HTTP flusher interface to flush buffered data.rw: HTTP response writer.event: Session event to send.
Returns: Error on failure to write or encode the event.
validateSessionExists (private method)
func (c *RuntimeAPIController) validateSessionExists(ctx context.Context, appName, userID, sessionID string) error
Purpose: Confirms that a session with the specified identifiers exists.
Process:
Uses the
sessionService.Getmethod.Returns a 404 status error if session is not found.
Parameters:
ctx: Context for cancellation.appName: Application name identifier.userID: User identifier.sessionID: Session identifier.
Returns: Error if session not found or retrieval fails.
getRunner (private method)
func (c *RuntimeAPIController) getRunner(req models.RunAgentRequest) (*runner.Runner, *agent.RunConfig, error)
Purpose: Loads the agent, creates a runner instance, and configures run options.
Steps:
Loads the agent for the specified app name via
agentLoader.Instantiates a new
runner.Runnerwith the agent and configured session/artifact services.Sets the streaming mode to SSE or none based on request.
Parameters:
req: RunAgentRequest containing app name and streaming preference.
Returns:
*runner.Runner: Runner instance to execute agent runs.*agent.RunConfig: Run configuration specifying streaming mode.error: If loading or creating runner fails.
decodeRequestBody (private function)
func decodeRequestBody(req *http.Request) (decodedReq models.RunAgentRequest, err error)
Purpose: Decodes JSON request body into a
RunAgentRequeststruct.Details:
Uses a JSON decoder with
DisallowUnknownFieldsto enforce strict schema.Closes the request body after decoding.
Parameters:
req: HTTP request with JSON body.
Returns:
Decoded
RunAgentRequest.Error if decoding fails or if unknown fields are present.
Important Implementation Details
Session Validation: Before running an agent, the controller confirms the session exists using the session service, avoiding processing invalid or stale sessions.
Agent Loading and Runner Creation: Agents are dynamically loaded by app name, enabling modular agent deployment. The runner abstracts the execution of the agent logic, handling message appending, state management, and event streaming.
Streaming Support: The
RunSSEHandleruses HTTP streaming with SSE to incrementally deliver events, providing real-time feedback to clients. This contrasts with the synchronous batch response ofRunHandler.Error Handling: Errors during request decoding, session validation, agent loading, or execution are wrapped with HTTP status codes for proper response signaling. Streaming errors are handled gracefully by sending error messages and continuing the stream where possible.
Event Conversion: Internal
session.Eventobjects are converted to API response models (models.Event) for consistent JSON output.
Interaction with Other System Components
Uses the session.Service to manage and validate sessions (Session Management).
Uses the artifact.Service to access and manage session-related artifacts (Artifact Management).
Loads agents via agent.Loader, which abstracts agent retrieval and initialization (LLM Integration and Agents).
Creates and runs agents via runner.Runner, coordinating agent invocation, message handling, and event generation (Agent Execution Runner).
Converts internal session events to API-friendly models defined in the
modelspackage, which is part of the REST API domain.Responds to HTTP requests routed from the REST API router (Router Setup), which maps
/runand/run_sseendpoints to this controller.
Usage Examples
Running an Agent Synchronously (Non-Streaming)
A client POSTs to /run with JSON body:
{
"appName": "chatbot",
"userId": "user123",
"sessionId": "sess456",
"newMessage": {
"text": "Hello, agent!"
},
"streaming": false
}
The RunHandler will:
Decode the request.
Validate the session.
Load the agent and create a runner.
Run the agent synchronously.
Return a JSON array of session events.
Running an Agent with Streaming (SSE)
A client POSTs to /run_sse with "streaming": true in the body. The server responds with an SSE stream:
data: {"eventType":"message", "content": "..."}
data: {"eventType":"update", "content": "..."}
...
Events are flushed incrementally as the agent produces them, enabling real-time client updates.
Visual Diagram: RuntimeAPIController Structure and Workflow
classDiagram
class RuntimeAPIController {
-sessionService: session.Service
-artifactService: artifact.Service
-agentLoader: agent.Loader
+RunHandler()
+RunSSEHandler()
-runAgent()
-validateSessionExists()
-getRunner()
}
RuntimeAPIController --> session.Service
RuntimeAPIController --> artifact.Service
RuntimeAPIController --> agent.Loader
RuntimeAPIController ..> runner.Runner : creates and uses
Visual Diagram: Agent Execution Flow in RuntimeAPIController
flowchart TD
Client[HTTP Client]
ReqDecode[Decode JSON Request]
ValidateSession[Validate Session Exists]
LoadAgent[Load Agent by AppName]
NewRunner[Create Runner]
RunAgent[Run Agent]
CollectEvents[Collect Session Events]
EventConvert[Convert to API Events]
Response[Send JSON or SSE Response]
Client --> ReqDecode --> ValidateSession --> LoadAgent --> NewRunner --> RunAgent --> CollectEvents --> EventConvert --> Response
References to Related Topics
The controller depends on the Agent Execution Runner ([80560]) for running agents within sessions.
Session validation and management use the Session Management service ([80559]).
Artifact handling integrates with the Artifact Management services ([80557]).
Agent loading interfaces are defined in the LLM Integration and Agents topic ([80562]).
The controller is part of the broader REST API Controllers subtopic ([80590]) and implemented within the REST API and Web Launchers domain ([80564]).
This file provides the essential HTTP bridging code for running AI agents with session context, supporting both batch and streaming interaction modes, and ensuring robust validation and error handling.