Gateway / gRPC

gRPC Transport

Open Astra includes an optional gRPC sidecar that runs alongside the main HTTP gateway on a separate port. It exposes the same agent loop, spawn, and health-check capabilities over gRPC — useful for inter-service communication in microservice deployments or when you need low-latency binary transport between services.

Opt-in. The gRPC server is disabled by default. Set GRPC_ENABLED=true to start it alongside the HTTP gateway.

Service definition

The AgentService is defined in src/grpc/protos/agent.proto and provides four RPCs.

protobuf
service AgentService {
  rpc RunAgentLoop (AgentRequest) returns (AgentResponse);
  rpc RunAgentLoopStream (AgentRequest) returns (stream StreamEvent);
  rpc SpawnAgent (SpawnRequest) returns (SpawnResponse);
  rpc HealthCheck (Empty) returns (HealthResponse);
}
RPCTypeDescription
RunAgentLoopUnaryRuns the full agent loop and returns the final response, session ID, and token usage
RunAgentLoopStreamServer streamingStreams events as the agent works — deltas, tool calls, tool results, and completion
SpawnAgentUnaryDelegates a task to a sub-agent and returns its response
HealthCheckUnaryReturns { status: "ok", timestamp }

Message types

protobuf
message AgentRequest {
  string uid = 1;
  string message = 2;
  string agent_id = 3;
  string surface = 4;
  string surface_id = 5;
  string session_id = 6;
}

message SpawnRequest {
  string uid = 1;
  string parent_agent_id = 2;
  string target_agent_id = 3;
  string task = 4;
  int32  depth = 5;
}

message AgentResponse {
  string content = 1;
  string session_id = 2;
  TokenUsage usage = 3;
}

message SpawnResponse {
  string task_id = 1;
  string target_agent_id = 2;
  string content = 3;
  bool   success = 4;
  int32  duration_ms = 5;
  string session_id = 6;
}

message StreamEvent {
  string type = 1;    // session_resolved | stream_delta | tool_call_start
  string data = 2;    //   tool_call_complete | tool_result | completed | error
}

Stream event types

RunAgentLoopStream emits the following event types in order.

TypeWhen
session_resolvedSession found or created
stream_deltaEach chunk of the agent's response text
tool_call_startAgent begins a tool call
tool_call_completeTool call arguments fully received
tool_resultTool execution finished (includes duration)
completedAgent loop finished — final content and usage
errorAn error occurred during the loop

Configuration

bash
# Enable the gRPC sidecar (default: false)
GRPC_ENABLED=true
GRPC_PORT=50051          # default: 50051

# mTLS — provide all three for mutual TLS
GRPC_TLS_CERT=/path/to/server.crt
GRPC_TLS_KEY=/path/to/server.key
GRPC_TLS_CA=/path/to/ca.crt
VariableDefaultPurpose
GRPC_ENABLEDfalseEnable the gRPC sidecar
GRPC_PORT50051Listen port
GRPC_TLS_CERTPath to TLS certificate chain
GRPC_TLS_KEYPath to TLS private key
GRPC_TLS_CAPath to CA certificate for mTLS

Mutual TLS (mTLS)

When all three TLS environment variables are set, the server starts with mutual TLS — both the server and client must present valid certificates signed by the same CA. If any variable is missing, the server falls back to insecure (plaintext) transport.

Production. Always enable mTLS in production. The gRPC sidecar has no JWT authentication layer — it trusts the network boundary. Without mTLS, any process that can reach the port can invoke agent loops.

Client usage

Open Astra exports a typed client for internal use (e.g., from agent spawn logic or external orchestrators).

typescript
import { createGrpcAgentClient } from './grpc/client.js'

const client = createGrpcAgentClient('localhost:50051')

// Unary call
const response = await client.runAgentLoop({
  uid: 'user-123',
  message: 'Summarize the latest research',
  agentId: 'researcher',
  surface: 'api',
  surfaceId: 'grpc-test'
})

// Server-streaming call
const stream = client.runAgentLoopStream({
  uid: 'user-123',
  message: 'Analyze this codebase',
  agentId: 'coder',
  surface: 'api',
  surfaceId: 'grpc-stream'
})

for await (const event of stream) {
  console.log(event.type, event.data)
}

How it integrates

The gRPC handlers call the same internal functions as the HTTP gateway — runAgentLoop, spawnAgent, getAgentConfig, and getInferenceClientForAgent. There is no separate code path. The gRPC layer is a thin transport wrapper.

  • The gateway starts the gRPC server after HTTP is listening (conditional on GRPC_ENABLED)
  • Graceful shutdown calls tryShutdown() with a forced fallback after timeout
  • Proto files are loaded at runtime relative to the source directory — works in both tsx (dev) and compiled dist/