> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rkat.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# TypeScript SDK reference

> Types, events, error classes, and version compatibility for the @rkat/sdk TypeScript SDK.

<Note>
  Public SDK interfaces use camelCase by default. Protocol-bound multimodal content keys (`media_type`, `blob_id`, `duration_ms`) intentionally remain wire-shaped.
</Note>

## Imports

Everything public is re-exported from the package root:

```typescript theme={null}
import {
  MeerkatClient,
  Session,
  LiveChannel,
  Mob,
  EventStream,
  EventSubscription,
  MeerkatError,
  CapabilityUnavailableError,
  SessionNotFoundError,
  SkillNotFoundError,
  CONTRACT_VERSION,
} from "@rkat/sdk";

import type {
  RunResult,
  Usage,
  SessionInfo,
  SessionOptions,
  LiveChannelOptions,
  LiveOpenResult,
  LiveStatusResult,
  LiveInputChunkWire,
  ContentBlock,
  Capability,
  SkillKey,
  SkillRef,
  SkillRuntimeDiagnostics,
  SchemaWarning,
  AgentEvent,
  AgentEventEnvelope,
  AttributedMobEvent,
  EventEnvelope,
  AttributedEvent,
  MobMember,
  MobStatus,
  MobSummary,
  SpawnSpec,
  MobFlowStatus,
  MobLifecycleAction,
  MobDefinition,
  TextDeltaEvent,
  TurnCompletedEvent,
  // ... all event types
} from "@rkat/sdk";
```

## Additional client wrappers

The package exports more than the core session lifecycle. The `MeerkatClient` also exposes:

* auth-profile helpers: `authProfileList`, `authProfileGet`, `authProfileCreate`, `authProfileDelete`
* auth-login helpers: `authLoginStart`, `authLoginComplete`, `authLoginDeviceStart`, `authLoginDeviceComplete`, `authLoginProvisionApiKey`, `authStatusGet`, `authLogout`
* realm helpers: `realmList`, `realmGet`
* typed ingress helper: `sendPeerResponseTerminal`
* MCP live-op helpers: `mcpAdd`, `mcpRemove`, `mcpReload`
* blob/skill helpers: `getBlob`, `listSkills`
* live-channel helpers: `liveOpen`, `liveStatus`, `liveClose`, `liveSendInput`,
  `liveSendInputImage`, `liveSendInputVideoFrame`, `liveCommitInput`,
  `liveInterrupt`, `liveTruncate`, `liveRefresh`, and
  `parseLiveObservation`

***

## Core types

### RunResult

The result returned by `session.turn()`, `session.invokeSkill()`, and `deferred.startTurn()`. Session creation returns runtime-backed `Session` or `DeferredSession` wrappers, and the latest `RunResult` remains available through `session.lastResult` or `stream.result` after an `EventStream` is fully consumed.

```typescript theme={null}
interface RunResult {
  readonly sessionId: string;
  readonly sessionRef?: string;
  readonly text: string;
  readonly turns: number;
  readonly toolCalls: number;
  readonly usage: Usage;
  readonly terminalCauseKind?: TurnTerminalCauseKind;
  readonly structuredOutput?: unknown;
  readonly extractionError?: ExtractionError;
  readonly schemaWarnings?: readonly SchemaWarning[];
  readonly skillDiagnostics?: SkillRuntimeDiagnostics;
}
```

| Field               | Type                                   | Description                                                                                                              |
| ------------------- | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `sessionId`         | `string`                               | Stable UUID for this session                                                                                             |
| `sessionRef`        | `string \| undefined`                  | Optional human-readable reference                                                                                        |
| `text`              | `string`                               | Full assistant text from the last LLM turn                                                                               |
| `turns`             | `number`                               | Number of LLM turns in this run                                                                                          |
| `toolCalls`         | `number`                               | Total tool calls executed in this run                                                                                    |
| `usage`             | `Usage`                                | Token usage for this run                                                                                                 |
| `terminalCauseKind` | `TurnTerminalCauseKind \| undefined`   | Machine-owned terminal cause when success carries a typed terminal condition (e.g. budget exhaustion)                    |
| `structuredOutput`  | `unknown \| undefined`                 | Parsed structured output when `outputSchema` was provided                                                                |
| `extractionError`   | `ExtractionError \| undefined`         | Extraction failure details (`lastOutput`, `attempts`, `reason`) when schema extraction failed after a completed main run |
| `schemaWarnings`    | `SchemaWarning[] \| undefined`         | Warnings emitted when structured output didn't fully match the schema                                                    |
| `skillDiagnostics`  | `SkillRuntimeDiagnostics \| undefined` | Runtime diagnostics from the skill subsystem                                                                             |

### Session

`client.createSession()` returns a runtime-backed `Session` wrapper.

```typescript theme={null}
class Session {
  readonly id: string;
  readonly ref?: string;
  readonly text: string;
  readonly usage: Usage;
  readonly turns: number;
  readonly toolCalls: number;
  readonly structuredOutput?: unknown;
  readonly lastResult: RunResult;
}
```

The `Session` methods are thin conveniences over canonical runtime calls:

* `await session.turn(...)`
* `session.stream(...)`
* `await session.history(...)`
* `await session.archive()`
* `await session.interrupt()`
* `await session.invokeSkill(...)`
* `await session.subscribeEvents()`

### DeferredSession

`client.createDeferredSession()` reserves session identity now and runs the first turn later through `await deferred.startTurn(...)`.

### LiveChannel

`LiveChannel` is the session-bound helper for the `live/*` RPC surface.
`RealtimeChannel` was removed with the live-adapter surface; use
`LiveChannel.session(client, sessionId, options?)` instead.

```typescript theme={null}
const channel = LiveChannel.session(client, session.id, {
  turningMode: "explicit_commit",
});

const opened: LiveOpenResult = await channel.open();
await channel.sendInputText("hello");
await channel.commitInput("text");
const status: LiveStatusResult = await channel.status();
const refresh = await channel.refresh();
await channel.close();
```

The helper stores the `channel_id` returned by `live/open`. It does not own the
WebSocket transport; connect to `opened.transport.url` with the returned token
using the transport appropriate for your app.

### Usage

Token usage for a single run. All fields are camelCase — there is no `total_tokens` field.

```typescript theme={null}
interface Usage {
  readonly inputTokens: number;
  readonly outputTokens: number;
  readonly cacheCreationTokens?: number;
  readonly cacheReadTokens?: number;
}
```

### SessionInfo

Summary returned by `client.listSessions()`.

```typescript theme={null}
interface SessionInfo {
  readonly sessionId: string;
  readonly sessionRef?: string;
  readonly createdAt: number;
  readonly updatedAt: number;
  readonly messageCount: number;
  readonly totalTokens?: number;
  readonly isActive: boolean;
  readonly model?: string;
  readonly provider?: string;
  readonly lastAssistantText?: string;
  readonly resolvedCapabilities?: ResolvedModelCapabilities;
  readonly labels: Readonly<Record<string, string>>;
}
```

### Capability

A single runtime capability entry, as returned by `client.capabilities`.

```typescript theme={null}
interface Capability {
  readonly id: string;
  readonly description: string;
  readonly status: string;  // "Available", "DisabledByPolicy", "NotCompiled", etc.
}
```

Status values may be emitted as externally-tagged Rust enum objects (e.g. `{ DisabledByPolicy: { ... } }`). The SDK normalizes these to the key string automatically.

### ContentBlock

Content blocks are used in multimodal prompts and tool results. Both `createSession()` and `session.turn()` accept `string | ContentBlock[]` as the prompt parameter.

```typescript theme={null}
type ContentBlock =
  | { type: "text"; text: string }
  | { type: "image"; media_type: string; data: string; source?: "inline" }
  | { type: "image"; media_type: string; source: "blob"; blob_id: string }
  | { type: "video"; media_type: string; duration_ms: number; data: string; source?: "inline" }
  | { type: "video"; media_type: string; duration_ms: number; source: "uri"; uri: string };
```

| Variant | Fields                               | Description                                              |
| ------- | ------------------------------------ | -------------------------------------------------------- |
| `text`  | `text: string`                       | Plain text content                                       |
| `image` | `media_type: string`, `data: string` | Base64-encoded image with MIME type (e.g. `"image/png"`) |

```typescript theme={null}
// Multimodal prompt example
const session = await client.createSession([
  { type: "text", text: "Describe this image" },
  { type: "image", media_type: "image/png", data: base64Data },
]);
```

### SchemaWarning

Emitted when a structured output response did not fully conform to the requested schema.

```typescript theme={null}
interface SchemaWarning {
  readonly provider: string;
  readonly path: string;
  readonly message: string;
}
```

***

## Skill types

### SkillKey

Structured skill identifier.

```typescript theme={null}
interface SkillKey {
  readonly sourceUuid: string;
  readonly skillName: string;
}
```

### SkillRef

A skill reference is a structured `SkillKey`.

```typescript theme={null}
type SkillRef = SkillKey;
```

### SkillRuntimeDiagnostics

Runtime diagnostics from the skill subsystem. Present on `RunResult.skillDiagnostics` when the server emits skill health data.

```typescript theme={null}
interface SkillRuntimeDiagnostics {
  readonly sourceHealth: SourceHealthSnapshot;
  readonly quarantined: readonly SkillQuarantineDiagnostic[];
}

interface SourceHealthSnapshot {
  readonly state: string;
  readonly invalidRatio: number;
  readonly invalidCount: number;
  readonly totalCount: number;
  readonly failureStreak: number;
  readonly handshakeFailed: boolean;
}

interface SkillQuarantineDiagnostic {
  readonly sourceUuid: string;
  readonly skillId: string;
  readonly location: string;
  readonly errorCode: string;
  readonly errorClass: string;
  readonly message: string;
  readonly firstSeenUnixSecs: number;
  readonly lastSeenUnixSecs: number;
}
```

***

## EventStream

`EventStream` is an `AsyncIterable<AgentEvent>` returned by `createSessionStreaming()` and `session.stream()`. It yields typed events as the agent runs, then makes the final `RunResult` available on `stream.result`.

```typescript theme={null}
class EventStream implements AsyncIterable<AgentEvent> {
  readonly sessionId: string;
  readonly result: RunResult;  // throws if accessed before iteration completes

  [Symbol.asyncIterator](): AsyncGenerator<AgentEvent>;

  /** Consume all events and return the final RunResult. */
  collect(): Promise<RunResult>;

  /** Consume events, accumulate text deltas, return [fullText, result]. */
  collectText(): Promise<[string, RunResult]>;
}
```

### Iterating

```typescript theme={null}
for await (const event of session.stream("Summarise this")) {
  if (event.type === "text_delta") {
    process.stdout.write(event.delta);
  }
}
const result = stream.result;
```

### collect()

Discards all events and returns the final result:

```typescript theme={null}
const result = await stream.collect();
```

### collectText()

Accumulates all `text_delta` events and returns the joined string alongside the result:

```typescript theme={null}
const [fullText, result] = await stream.collectText();
console.log(fullText);
console.log("Output tokens:", result.usage.outputTokens);
```

***

## Typed events

All events are discriminated on the `type` field (snake\_case, matching the wire protocol). All other fields are camelCase.

### AgentEvent union

```typescript theme={null}
type AgentEvent =
  | RunStartedEvent
  | RunCompletedEvent
  | ExtractionSucceededEvent
  | ExtractionFailedEvent
  | RunFailedEvent
  | TurnStartedEvent
  | TextDeltaEvent
  | TextCompleteEvent
  | ToolCallRequestedEvent
  | ToolResultReceivedEvent
  | TurnCompletedEvent
  | ToolExecutionStartedEvent
  | ToolExecutionCompletedEvent
  | ToolExecutionTimedOutEvent
  | CompactionStartedEvent
  | CompactionCompletedEvent
  | CompactionFailedEvent
  | BudgetWarningEvent
  | RetryingEvent
  | HookStartedEvent
  | HookCompletedEvent
  | HookFailedEvent
  | HookDeniedEvent
  | SkillsResolvedEvent
  | SkillResolutionFailedEvent
  | InteractionCompleteEvent
  | InteractionFailedEvent
  | StreamTruncatedEvent
  | ToolConfigChangedEvent
  | BackgroundJobCompletedEvent
  | TranscriptRewriteCommittedEvent
  | MalformedEvent
  | UnknownEvent;
```

Event parsing fails closed: a `type` outside the generated `KNOWN_AGENT_EVENT_TYPES` inventory throws a `MeerkatError` with code `UNKNOWN_EVENT_TYPE`. A known type without a parser case in this SDK version is surfaced as `UnknownEvent` for forward-compatibility, and a known type with a malformed payload is preserved as a `MalformedEvent` (`type: "malformed_event"`).

### Session lifecycle events

```typescript theme={null}
interface RunStartedEvent   { type: "run_started";   sessionId: string; prompt: ContentInput }
interface RunCompletedEvent {
  type: "run_completed";
  sessionId: string;
  result: string;
  structuredOutput?: unknown;
  extractionRequired?: boolean;
  usage: Usage;
  terminalCauseKind?: TurnTerminalCauseKind;
}
interface ExtractionSucceededEvent {
  type: "extraction_succeeded";
  sessionId: string;
  structuredOutput: unknown;
  schemaWarnings?: readonly SchemaWarning[];
}
interface ExtractionFailedEvent {
  type: "extraction_failed";
  sessionId: string;
  lastOutput: string;
  attempts: number;
  reason: string;
}
interface RunFailedEvent {
  type: "run_failed";
  sessionId: string;
  errorClass: string;
  error: string;
  terminalCauseKind?: TurnTerminalCauseKind;
  errorReport?: AgentErrorReport | null;
}
```

### Turn and LLM events

```typescript theme={null}
interface TurnStartedEvent        { type: "turn_started";         turnNumber: number }
interface TextDeltaEvent          { type: "text_delta";            delta: string }
interface TextCompleteEvent       { type: "text_complete";         content: string }
interface ToolCallRequestedEvent  { type: "tool_call_requested";   id: string; name: string; args: ToolCallArguments }
interface ToolResultReceivedEvent { type: "tool_result_received";  id: string; name: string; content: readonly ContentBlock[]; isError?: boolean }
interface TurnCompletedEvent      { type: "turn_completed";        stopReason?: StopReason; usage: Usage }
```

```typescript theme={null}
type StopReason =
  | "end_turn"
  | "tool_use"
  | "max_tokens"
  | "stop_sequence"
  | "content_filter"
  | "cancelled";
```

### Tool execution events

```typescript theme={null}
interface ToolExecutionStartedEvent   { type: "tool_execution_started";    id: string; name: string }
interface ToolExecutionCompletedEvent { type: "tool_execution_completed";   id: string; name: string; content: readonly ContentBlock[]; isError?: boolean; durationMs?: number }
interface ToolExecutionTimedOutEvent  { type: "tool_execution_timed_out";   id: string; name: string; timeoutMs: number }
```

### Compaction events

```typescript theme={null}
interface CompactionStartedEvent   { type: "compaction_started";   inputTokens: number; estimatedHistoryTokens: number; messageCount: number }
interface CompactionCompletedEvent { type: "compaction_completed";  summaryTokens: number; messagesBefore: number; messagesAfter: number }
// `reason` mirrors the Rust CompactionFailureReason tagged enum ({ kind, ... }).
interface CompactionFailedEvent    { type: "compaction_failed";     reason: Record<string, unknown> }
```

### Budget events

```typescript theme={null}
interface BudgetWarningEvent { type: "budget_warning"; budgetType: BudgetType; used: number; limit: number; percent: number }

type BudgetType = "tokens" | "time" | "tool_calls";
```

### Retry events

```typescript theme={null}
interface RetryingEvent { type: "retrying"; attempt: number; maxAttempts: number; error: string; delayMs: number }
```

### Hook events

```typescript theme={null}
type HookPoint =
  | "run_started" | "run_completed" | "run_failed"
  | "pre_llm_request" | "post_llm_response"
  | "pre_tool_execution" | "post_tool_execution"
  | "turn_boundary";

interface HookStartedEvent        { type: "hook_started";         hookId: string; point: HookPoint }
interface HookCompletedEvent      { type: "hook_completed";        hookId: string; point: HookPoint; durationMs: number }
interface HookFailedEvent         { type: "hook_failed";           hookId: string; point: HookPoint; error: string }
interface HookDeniedEvent         { type: "hook_denied";           hookId: string; point: HookPoint; reasonCode: string; message: string; payload?: unknown }
```

### Skill events

```typescript theme={null}
interface SkillsResolvedEvent       { type: "skills_resolved";         skills: readonly SkillKey[]; injectionBytes: number }
interface SkillResolutionFailedEvent { type: "skill_resolution_failed"; skillKey?: SkillKey; reason?: SkillResolutionFailureReason }
```

`SkillResolutionFailureReason` is a typed union discriminated on `reasonType`
(`not_found`, `capability_unavailable`, `load`, `parse`, `source_uuid_collision`,
`source_uuid_mutation_without_lineage`, `missing_skill_remaps`,
`remap_without_lineage`, `unknown_skill_alias`, `remap_cycle`, `unknown`).

### Comms events

```typescript theme={null}
interface InteractionCompleteEvent { type: "interaction_complete"; interactionId: string; result: string; structuredOutput?: unknown }
interface InteractionFailedEvent   { type: "interaction_failed";   interactionId: string; error: string }
```

### Tool config events

```typescript theme={null}
interface ToolConfigChangedEvent { type: "tool_config_changed"; payload: ToolConfigChangedPayload }

// Payload keys intentionally remain wire-shaped (snake_case).
interface ToolConfigChangedPayload {
  operation?: "add" | "remove" | "reload";
  target?: string;
  status_info?: ToolConfigChangeStatus;
  persisted?: boolean;
  applied_at_turn?: number;
}

type ToolConfigChangeStatus =
  | { kind: "boundary_applied"; base_changed: boolean; visible_changed: boolean; revision: number }
  | { kind: "deferred_catalog_delta"; added_hidden_count: number; removed_hidden_count: number; pending_source_count: number }
  | { kind: "warning_failed_closed"; error: string }
  | { kind: "external_tool_delta"; phase: "pending" | "applied" | "draining" | "forced" | "failed"; detail?: string };
```

### Background job events

```typescript theme={null}
type BackgroundJobTerminalStatus =
  | "completed"
  | "failed"
  | "aborted"
  | "cancelled"
  | "retired"
  | "terminated";

interface BackgroundJobCompletedEvent {
  type: "background_job_completed";
  jobId: string;
  displayName: string;
  terminalStatus: BackgroundJobTerminalStatus;
  detail: string;
}
```

`terminalStatus` is the typed semantic status; `detail` is the human-readable description.

### Stream management

```typescript theme={null}
interface StreamTruncatedEvent { type: "stream_truncated"; reason: string }
```

### Transcript rewrite events

```typescript theme={null}
interface TranscriptRewriteCommittedEvent {
  type: "transcript_rewrite_committed";
  sessionId: string;
  record: Record<string, unknown>;
}
```

### Type guard utilities

The SDK exports type guards for the most commonly used events:

```typescript theme={null}
import {
  isTextDelta,
  isTextComplete,
  isTurnCompleted,
  isToolCallRequested,
  isRunCompleted,
  isRunFailed,
} from "@rkat/sdk";

for await (const event of session.stream("prompt")) {
  if (isTextDelta(event)) {
    process.stdout.write(event.delta);  // TypeScript knows event.delta exists
  }
  if (isTurnCompleted(event)) {
    console.log(event.stopReason, event.usage.inputTokens);
  }
}
```

***

## Error handling

All errors extend `MeerkatError`. Catch it as a base class or use the specific subclasses for targeted handling.

```typescript theme={null}
import { MeerkatError, CapabilityUnavailableError } from "@rkat/sdk";

try {
  await client.connect();
  const session = await client.createSession("Hello");
  await session.turn("Next");
} catch (err) {
  if (err instanceof CapabilityUnavailableError) {
    console.error("Missing capability:", err.message, err.capabilityHint);
  } else if (err instanceof MeerkatError) {
    console.error(`[${err.code}] ${err.message}`);
  }
} finally {
  await client.close();
}
```

### Error classes

```typescript theme={null}
class MeerkatError extends Error {
  readonly code: string;
  readonly details?: unknown;
  readonly capabilityHint?: { capability_id: string; message: string };
}

class CapabilityUnavailableError extends MeerkatError {}
class SessionNotFoundError extends MeerkatError {}
class SkillNotFoundError extends MeerkatError {}
```

| Class                        | When thrown                                                                                           |
| ---------------------------- | ----------------------------------------------------------------------------------------------------- |
| `MeerkatError`               | Base class for all SDK errors                                                                         |
| `CapabilityUnavailableError` | `client.requireCapability()` or `session.invokeSkill()` when the required capability is not available |
| `SessionNotFoundError`       | Server reports that the requested session does not exist                                              |
| `SkillNotFoundError`         | Server reports that a skill reference cannot be resolved                                              |

### Common error codes

| Code                     | Cause                                                            |
| ------------------------ | ---------------------------------------------------------------- |
| `NOT_CONNECTED`          | Method called before `connect()`                                 |
| `VERSION_MISMATCH`       | Server contract version incompatible with SDK                    |
| `CAPABILITY_UNAVAILABLE` | Required capability not enabled in this build                    |
| `CLIENT_CLOSED`          | Method called after `close()`                                    |
| `STREAM_NOT_CONSUMED`    | `stream.result` accessed before iteration completed              |
| `BINARY_NOT_FOUND`       | `rkat-rpc` not found and auto-download failed                    |
| `UNKNOWN_EVENT_TYPE`     | Streamed event `type` not in the generated known-event inventory |

***

## Skills

Both `createSession()` and `session.turn()` accept structured skill parameters.

```typescript theme={null}
// Preload skills into the system prompt at session creation
const session = await client.createSession("Hello!", {
  preloadSkills: [
    { sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f", skillName: "extraction-email" },
    { sourceUuid: "dc256086-0d2f-4f61-a307-320d4148107f", skillName: "formatting-markdown" },
  ],
});

// Inject a skill for a specific turn via session.turn()
const result = await session.turn("Extract emails from this text", {
  skillRefs: [{ sourceUuid: "abc123", skillName: "extraction-email" }],
});

// Convenience method on Session — wraps turn() with requireCapability check
const result2 = await session.invokeSkill(
  { sourceUuid: "abc123", skillName: "extraction-email" },
  "Extract emails from this text",
);
```

***

## Version compatibility

```typescript theme={null}
import { CONTRACT_VERSION } from "@rkat/sdk";
console.log(CONTRACT_VERSION);  // "0.7.11"
```

* While the major version is `0`, minor versions must match exactly between SDK and server.
* From `1.0.0` onwards, standard semver applies: major versions must match.

Version checking happens automatically during `connect()`. A `MeerkatError` with code `VERSION_MISMATCH` is thrown if versions are incompatible.

***

## See also

* [TypeScript SDK overview](/sdks/typescript/overview) - getting started, client and session API
* [Python SDK](/sdks/python/overview) - Python SDK
* [RPC reference](/api/rpc) - JSON-RPC protocol specification
