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.
Unique project identifier
Absolute path to the workspace root directory
Default AI model for new threads in this project
Configured project scripts (build, test, lint, etc.)
Project creation timestamp
deletedAt
IsoDateTime | null
required
Soft deletion timestamp
ProjectScript
Configurable script that can be run in the project context.
icon
ProjectScriptIcon
required
Icon identifier: "play" | "test" | "lint" | "configure" | "build" | "debug"
Whether to automatically run when creating a new worktree
OrchestrationThread
A conversation thread with an AI provider.
AI model slug for this thread
Runtime mode: "approval-required" | "full-access"
interactionMode
ProviderInteractionMode
required
Interaction mode: "default" | "plan"
Git branch associated with this thread
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
Thread creation timestamp
deletedAt
IsoDateTime | null
required
Soft deletion timestamp
OrchestrationMessage
A single message in a thread conversation.
Unique message identifier
role
OrchestrationMessageRole
required
Message role: "user" | "assistant" | "system"
Whether the message is currently streaming
Message creation timestamp
OrchestrationSession
Active provider session state.
status
OrchestrationSessionStatus
required
Session status: "idle" | "starting" | "running" | "ready" | "interrupted" | "stopped" | "error"
Provider name (e.g., “codex”)
Last error message if status is “error”
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
Unique command identifier
User input text (max 120,000 characters)
Attached images (max 8 attachments)
Override model for this turn
Service tier for the turn
How to deliver assistant responses
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:
Global event sequence number
aggregateKind
'project' | 'thread'
required
Type of aggregate this event belongs to
aggregateId
ProjectId | ThreadId
required
Aggregate root ID
Event occurrence timestamp
Command that caused this event
Event that caused this event
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: