Engine Client API
Complete reference for the EngineClient interface that all QuantumReef engines implement. Use this reference when building custom engine adapters or when integrating QuantumReef's engine layer into your own tooling.
Overview
The EngineClient interface is the contract between QuantumReef's UI layer and individual engine adapters. It is defined in TypeScript and implemented once per engine. Every method is async; the interface is designed to support both HTTP-based engines (like OpenCode) and subprocess-based engines (like Claude Code and Aider).
import type { EngineClient } from "@quantumreef/engine-client";global.health()
Returns the health status of the engine process.
health(): Promise<HealthStatus>
interface HealthStatus {
ok: boolean; // true if the engine is reachable and responsive
latencyMs: number; // round-trip time in milliseconds
error?: string; // present only when ok is false
}Example
const status = await client.health();
if (!status.ok) {
console.error("Engine unavailable:", status.error);
}session.list()
Returns all sessions managed by the engine, ordered by updatedAt descending.
session.list(): Promise<Session[]>
interface Session {
id: string;
title: string;
engineId: string;
createdAt: number; // Unix milliseconds
updatedAt: number;
status: "idle" | "running" | "completed" | "error";
model?: string;
workingDirectory?: string;
starred?: boolean;
archived?: boolean;
}Example
const sessions = await client.session.list();
const active = sessions.filter(s => s.status === "running");session.create()
Creates a new session and returns it.
session.create(opts: CreateSessionOpts): Promise<Session>
interface CreateSessionOpts {
title?: string; // Human-readable session name
model?: string; // Override the engine's default model
workingDirectory?: string; // Filesystem root for this session
systemPrompt?: string; // Injected as the first system message
}Example
const session = await client.session.create({
title: "Refactor auth module",
workingDirectory: "/home/user/my-project",
model: "claude-opus-4-5",
});
console.log("Created session:", session.id);session.get()
Fetches a single session by ID.
session.get(id: string): Promise<Session>Example
const session = await client.session.get("sess_01abc");
console.log(session.status); // "idle"session.messages()
Returns the full message history for a session, ordered chronologically.
session.messages(id: string): Promise<Message[]>
interface Message {
id: string;
sessionId: string;
role: "user" | "assistant" | "tool";
content: MessageContent;
createdAt: number;
toolCalls?: ToolCall[];
toolResults?: ToolResult[];
}
interface MessageContent {
type: "text" | "image" | "file";
text?: string;
url?: string;
mimeType?: string;
}session.prompt()
Sends a user prompt to a session and returns an AsyncIterable of streaming events. This is the primary method for interacting with an engine.
session.prompt(
id: string,
prompt: string,
opts?: PromptOpts
): Promise<AsyncIterable<MessageEvent>>
interface PromptOpts {
model?: string;
maxTokens?: number;
temperature?: number;
}
type MessageEvent =
| { type: "text_delta"; delta: string }
| { type: "tool_call_start"; toolCall: ToolCall }
| { type: "tool_call_result"; toolCallId: string; result: unknown }
| { type: "message_done"; message: Message }
| { type: "error"; error: string };Example — streaming to console
const stream = await client.session.prompt(
session.id,
"Add input validation to the login form"
);
for await (const event of stream) {
if (event.type === "text_delta") {
process.stdout.write(event.delta);
} else if (event.type === "tool_call_start") {
console.log("\nTool:", event.toolCall.name, event.toolCall.input);
} else if (event.type === "message_done") {
console.log("\nDone.");
} else if (event.type === "error") {
console.error("Error:", event.error);
}
}session.abort()
Aborts a running session. Pending tool calls are cancelled. The session status becomes idle.
session.abort(id: string): Promise<void>Example
// Abort after 30 seconds
const timer = setTimeout(() => client.session.abort(session.id), 30_000);
for await (const event of stream) { /* ... */ }
clearTimeout(timer);session.summarize()
Requests a text summary of the session's conversation history. Used internally by QuantumReef for context handoff during engine switching.
session.summarize(id: string): Promise<string>message.create()
Creates a message in a session without triggering an AI response. Useful for injecting context, notes, or tool results manually.
message.create(
sessionId: string,
content: MessageContent
): Promise<Message>Example
await client.message.create(session.id, {
type: "text",
text: "Context note: the team uses pnpm, not npm.",
});events.subscribe()
Subscribes to the engine's global event bus. Returns an unsubscribe function. Events fire for all sessions managed by the engine process.
events.subscribe(
handler: (event: EngineEvent) => void
): Unsubscribe
type EngineEvent =
| { type: "session_created"; session: Session }
| { type: "session_updated"; session: Session }
| { type: "message_created"; message: Message }
| { type: "permission_requested";
permissionId: string;
description: string;
sessionId: string };
type Unsubscribe = () => void;Example
const unsubscribe = client.events.subscribe((event) => {
if (event.type === "permission_requested") {
console.log("Permission needed:", event.description);
client.permissions.reply(event.permissionId, "allow");
}
});
// Later, clean up
unsubscribe();permissions.reply()
Responds to a pending permission request from the engine.
permissions.reply(
permissionId: string,
decision: PermissionDecision
): Promise<void>
type PermissionDecision = "allow" | "deny" | "allow_session";
// "allow_session" approves this and all future identical requests in the sessionError Handling
All methods throw a typed EngineError on failure:
class EngineError extends Error {
code: EngineErrorCode;
engineId: string;
sessionId?: string;
}
type EngineErrorCode =
| "ENGINE_UNAVAILABLE" // health check failed
| "SESSION_NOT_FOUND" // invalid session ID
| "SESSION_RUNNING" // tried to create while another runs (some engines)
| "PROMPT_ABORTED" // session.abort() was called mid-stream
| "PERMISSION_DENIED" // tool call was denied
| "RATE_LIMITED" // engine or provider rate limit hit
| "CONTEXT_OVERFLOW" // prompt exceeds model context window
| "UNKNOWN";Retry on RATE_LIMITED
RATE_LIMITED errors. QuantumReef's built-in retry logic handles this automatically for sessions initiated from the UI, but custom integrations should handle it explicitly.