> ## 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",
  seedMaxChars: 24_000,
});

const opened: LiveOpenResult = await channel.open();
await channel.sendInputImage("turn-42-diagram", "image/png", imageDataBase64);
// Queue acceptance is not durability; wait for user_content_committed with
// idempotency_key === "turn-42-diagram" before sending dependent input.
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.

The direct helper has the same required identity:
`client.liveSendInputImage(channelId, idempotencyKey, mime, dataBase64)`.

`LiveChannelOptions.seedMaxChars` forwards as `LiveOpenParams.seed_max_chars`.
It must be positive, bounds serialized seed messages, and requests a
core-owned whole-turn suffix; omission preserves the complete canonical seed.
Every ordered System message must fit. Runtime context and complete image identity,
tombstone, and accounting sidecars remain outside the window. Any truncation
reports degraded continuity, and the server rejects zero.

### 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>;
}
```

### Peer content ingestion events

```typescript theme={null}
interface PeerContentIngestedEvent {
  type: "peer_content_ingested";
  kind: CommsNoticeKind;                       // message | request | response_* | lifecycle
  peer?: SystemNoticePeer | null;              // canonical peer id + display name, when resolved
  request_id?: string | null;                  // correlation id for request/response conventions
  sender_taint?: SenderContentTaint | null;    // "clean" | "tainted"; absent = no declaration
}
```

Emitted when inbound peer content is committed into the session's context
(both queued deliveries and steered mid-turn context). `sender_taint` is the
sender's own signed content-taint declaration; an absent value means the
sender made no declaration and must never be treated as `"clean"`. Host
taint trackers should consume this event instead of parsing rendered peer
message text.

### 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.8.22"
```

* 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
