Skip to main content

Overview

The orchestration schemas define the core domain model for T3 Code’s event-sourced architecture. These schemas handle projects, threads, messages, turns, and provider sessions using Effect Schema for validation and type safety.

Core Domain Models

OrchestrationProject

Represents a workspace project with configuration and scripts.
id
ProjectId
required
Unique project identifier
title
string
required
Project display name
workspaceRoot
string
required
Absolute path to the workspace root directory
defaultModel
string | null
required
Default AI model for new threads in this project
scripts
ProjectScript[]
required
Configured project scripts (build, test, lint, etc.)
createdAt
IsoDateTime
required
Project creation timestamp
updatedAt
IsoDateTime
required
Last update timestamp
deletedAt
IsoDateTime | null
required
Soft deletion timestamp

ProjectScript

Configurable script that can be run in the project context.
id
string
required
Script identifier
name
string
required
Display name
command
string
required
Shell command to execute
icon
ProjectScriptIcon
required
Icon identifier: "play" | "test" | "lint" | "configure" | "build" | "debug"
runOnWorktreeCreate
boolean
required
Whether to automatically run when creating a new worktree

OrchestrationThread

A conversation thread with an AI provider.
id
ThreadId
required
Unique thread identifier
projectId
ProjectId
required
Parent project ID
title
string
required
Thread title
model
string
required
AI model slug for this thread
runtimeMode
RuntimeMode
required
Runtime mode: "approval-required" | "full-access"
interactionMode
ProviderInteractionMode
required
Interaction mode: "default" | "plan"
branch
string | null
required
Git branch associated with this thread
worktreePath
string | null
required
Git worktree path if using worktrees
latestTurn
OrchestrationLatestTurn | null
required
Current or most recent turn state
messages
OrchestrationMessage[]
required
All messages in the thread
proposedPlans
OrchestrationProposedPlan[]
required
Plans proposed by the assistant (when in plan mode)
activities
OrchestrationThreadActivity[]
required
Activity log (tool calls, approvals, errors)
checkpoints
OrchestrationCheckpointSummary[]
required
Git checkpoints for rollback
session
OrchestrationSession | null
required
Active provider session
createdAt
IsoDateTime
required
Thread creation timestamp
updatedAt
IsoDateTime
required
Last update timestamp
deletedAt
IsoDateTime | null
required
Soft deletion timestamp

OrchestrationMessage

A single message in a thread conversation.
id
MessageId
required
Unique message identifier
role
OrchestrationMessageRole
required
Message role: "user" | "assistant" | "system"
text
string
required
Message content
attachments
ChatAttachment[]
Attached images or files
turnId
TurnId | null
required
Associated turn ID
streaming
boolean
required
Whether the message is currently streaming
createdAt
IsoDateTime
required
Message creation timestamp
updatedAt
IsoDateTime
required
Last update timestamp

OrchestrationSession

Active provider session state.
threadId
ThreadId
required
Associated thread ID
status
OrchestrationSessionStatus
required
Session status: "idle" | "starting" | "running" | "ready" | "interrupted" | "stopped" | "error"
providerName
string | null
required
Provider name (e.g., “codex”)
runtimeMode
RuntimeMode
required
Current runtime mode
activeTurnId
TurnId | null
required
Currently active turn ID
lastError
string | null
required
Last error message if status is “error”
updatedAt
IsoDateTime
required
Last update timestamp

Commands

Thread Commands

Commands for managing threads and turns.

ThreadTurnStartCommand

Starts a new turn in a thread.
export const ThreadTurnStartCommand = Schema.Struct({
  type: Schema.Literal("thread.turn.start"),
  commandId: CommandId,
  threadId: ThreadId,
  message: Schema.Struct({
    messageId: MessageId,
    role: Schema.Literal("user"),
    text: Schema.String,
    attachments: Schema.Array(ChatAttachment),
  }),
  provider: Schema.optional(ProviderKind),
  model: Schema.optional(TrimmedNonEmptyString),
  serviceTier: Schema.optional(Schema.NullOr(ProviderServiceTier)),
  modelOptions: Schema.optional(ProviderModelOptions),
  assistantDeliveryMode: Schema.optional(AssistantDeliveryMode),
  runtimeMode: RuntimeMode,
  interactionMode: ProviderInteractionMode,
  createdAt: IsoDateTime,
});
type
'thread.turn.start'
required
Command type discriminator
commandId
CommandId
required
Unique command identifier
threadId
ThreadId
required
Target thread ID
message.messageId
MessageId
required
ID for the user message
message.text
string
required
User input text (max 120,000 characters)
message.attachments
ChatAttachment[]
required
Attached images (max 8 attachments)
model
string
Override model for this turn
serviceTier
'fast' | 'flex' | null
Service tier for the turn
modelOptions
ProviderModelOptions
Model-specific options
assistantDeliveryMode
'buffered' | 'streaming'
How to deliver assistant responses
runtimeMode
RuntimeMode
required
Runtime mode for this turn
interactionMode
ProviderInteractionMode
required
Interaction mode for this turn

ThreadTurnInterruptCommand

Interrupts an active turn.
const ThreadTurnInterruptCommand = Schema.Struct({
  type: Schema.Literal("thread.turn.interrupt"),
  commandId: CommandId,
  threadId: ThreadId,
  turnId: Schema.optional(TurnId),
  createdAt: IsoDateTime,
});

ThreadApprovalRespondCommand

Responds to an approval request from the provider.
const ThreadApprovalRespondCommand = Schema.Struct({
  type: Schema.Literal("thread.approval.respond"),
  commandId: CommandId,
  threadId: ThreadId,
  requestId: ApprovalRequestId,
  decision: ProviderApprovalDecision,
  createdAt: IsoDateTime,
});
decision
ProviderApprovalDecision
required
Approval decision: "accept" | "acceptForSession" | "decline" | "cancel"

Project Commands

ProjectCreateCommand

Creates a new project.
export const ProjectCreateCommand = Schema.Struct({
  type: Schema.Literal("project.create"),
  commandId: CommandId,
  projectId: ProjectId,
  title: TrimmedNonEmptyString,
  workspaceRoot: TrimmedNonEmptyString,
  defaultModel: Schema.optional(TrimmedNonEmptyString),
  createdAt: IsoDateTime,
});

Events

Event Types

All orchestration events:
export const OrchestrationEventType = Schema.Literals([
  "project.created",
  "project.meta-updated",
  "project.deleted",
  "thread.created",
  "thread.deleted",
  "thread.meta-updated",
  "thread.runtime-mode-set",
  "thread.interaction-mode-set",
  "thread.message-sent",
  "thread.turn-start-requested",
  "thread.turn-interrupt-requested",
  "thread.approval-response-requested",
  "thread.user-input-response-requested",
  "thread.checkpoint-revert-requested",
  "thread.reverted",
  "thread.session-stop-requested",
  "thread.session-set",
  "thread.proposed-plan-upserted",
  "thread.turn-diff-completed",
  "thread.activity-appended",
]);

Event Structure

All events share these base fields:
sequence
number
required
Global event sequence number
eventId
EventId
required
Unique event identifier
aggregateKind
'project' | 'thread'
required
Type of aggregate this event belongs to
aggregateId
ProjectId | ThreadId
required
Aggregate root ID
occurredAt
IsoDateTime
required
Event occurrence timestamp
commandId
CommandId | null
required
Command that caused this event
causationEventId
EventId | null
required
Event that caused this event
correlationId
CommandId | null
required
Correlation ID for event chain (equals commandId)
metadata
OrchestrationEventMetadata
required
Additional metadata (provider turn ID, adapter key, etc.)

Event Payloads

ThreadCreatedPayload

export const ThreadCreatedPayload = Schema.Struct({
  threadId: ThreadId,
  projectId: ProjectId,
  title: TrimmedNonEmptyString,
  model: TrimmedNonEmptyString,
  runtimeMode: RuntimeMode,
  interactionMode: ProviderInteractionMode,
  branch: Schema.NullOr(TrimmedNonEmptyString),
  worktreePath: Schema.NullOr(TrimmedNonEmptyString),
  createdAt: IsoDateTime,
  updatedAt: IsoDateTime,
});

ThreadMessageSentPayload

export const ThreadMessageSentPayload = Schema.Struct({
  threadId: ThreadId,
  messageId: MessageId,
  role: OrchestrationMessageRole,
  text: Schema.String,
  attachments: Schema.optional(Schema.Array(ChatAttachment)),
  turnId: Schema.NullOr(TurnId),
  streaming: Schema.Boolean,
  createdAt: IsoDateTime,
  updatedAt: IsoDateTime,
});

Read Model

OrchestrationReadModel

The current state projection of all projects and threads.
export const OrchestrationReadModel = Schema.Struct({
  snapshotSequence: NonNegativeInt,
  projects: Schema.Array(OrchestrationProject),
  threads: Schema.Array(OrchestrationThread),
  updatedAt: IsoDateTime,
});
export type OrchestrationReadModel = typeof OrchestrationReadModel.Type;

RPC Schemas

WebSocket Methods

export const ORCHESTRATION_WS_METHODS = {
  getSnapshot: "orchestration.getSnapshot",
  dispatchCommand: "orchestration.dispatchCommand",
  getTurnDiff: "orchestration.getTurnDiff",
  getFullThreadDiff: "orchestration.getFullThreadDiff",
  replayEvents: "orchestration.replayEvents",
} as const;

Method Schemas

export const OrchestrationRpcSchemas = {
  getSnapshot: {
    input: OrchestrationGetSnapshotInput,
    output: OrchestrationGetSnapshotResult,
  },
  dispatchCommand: {
    input: ClientOrchestrationCommand,
    output: DispatchResult,
  },
  getTurnDiff: {
    input: OrchestrationGetTurnDiffInput,
    output: OrchestrationGetTurnDiffResult,
  },
  getFullThreadDiff: {
    input: OrchestrationGetFullThreadDiffInput,
    output: OrchestrationGetFullThreadDiffResult,
  },
  replayEvents: {
    input: OrchestrationReplayEventsInput,
    output: OrchestrationReplayEventsResult,
  },
} as const;

Usage Examples

Dispatching a Command

import { ThreadTurnStartCommand } from "@t3tools/contracts";
import { nanoid } from "nanoid";

const command: typeof ThreadTurnStartCommand.Type = {
  type: "thread.turn.start",
  commandId: nanoid(),
  threadId: "thread_abc123",
  message: {
    messageId: nanoid(),
    role: "user",
    text: "Help me implement a new feature",
    attachments: [],
  },
  runtimeMode: "full-access",
  interactionMode: "default",
  createdAt: new Date().toISOString(),
};

// Validate with Effect Schema
import { Schema } from "effect";
const validated = Schema.decodeUnknownSync(ThreadTurnStartCommand)(command);

Reading the Snapshot

import { OrchestrationReadModel } from "@t3tools/contracts";

const snapshot: typeof OrchestrationReadModel.Type = await rpc.call(
  "orchestration.getSnapshot",
  {}
);

const activeThreads = snapshot.threads.filter(
  (t) => t.session?.status === "running"
);

Handling Events

import { OrchestrationEvent } from "@t3tools/contracts";

function handleEvent(event: typeof OrchestrationEvent.Type) {
  switch (event.type) {
    case "thread.message-sent":
      console.log(`Message: ${event.payload.text}`);
      break;
    case "thread.activity-appended":
      console.log(`Activity: ${event.payload.activity.summary}`);
      break;
  }
}

Constants

Validation Limits

export const PROVIDER_SEND_TURN_MAX_INPUT_CHARS = 120_000;
export const PROVIDER_SEND_TURN_MAX_ATTACHMENTS = 8;
export const PROVIDER_SEND_TURN_MAX_IMAGE_BYTES = 10 * 1024 * 1024; // 10MB

Default Values

export const DEFAULT_PROVIDER_KIND: ProviderKind = "codex";
export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access";
export const DEFAULT_PROVIDER_INTERACTION_MODE: ProviderInteractionMode = "default";
See also: