import * as Effect from "effect/Effect";import * as Option from "effect/Option";import * as Schema from "effect/Schema";import * as SchemaIssue from "effect/SchemaIssue";import * as SchemaTransformation from "effect/SchemaTransformation";import * as Struct from "effect/Struct";import { ProviderOptionSelections } from "./model.ts";import { RepositoryIdentity } from "./environment.ts";import { ApprovalRequestId, CheckpointRef, CommandId, EventId, IsoDateTime, MessageId, NonNegativeInt, ProjectId, ProviderItemId, ThreadId, TrimmedNonEmptyString, TurnId,} from "./baseSchemas.ts";import { ProviderInstanceId } from "./providerInstance.ts"; export const ORCHESTRATION_WS_METHODS = { dispatchCommand: "orchestration.dispatchCommand", getTurnDiff: "orchestration.getTurnDiff", getFullThreadDiff: "orchestration.getFullThreadDiff", replayEvents: "orchestration.replayEvents", getArchivedShellSnapshot: "orchestration.getArchivedShellSnapshot", subscribeShell: "orchestration.subscribeShell", subscribeThread: "orchestration.subscribeThread",} as const; export const ProviderApprovalPolicy = Schema.Literals([ "untrusted", "on-failure", "on-request", "never",]);export type ProviderApprovalPolicy = typeof ProviderApprovalPolicy.Type;export const ProviderSandboxMode = Schema.Literals([ "read-only", "workspace-write", "danger-full-access",]);export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; /** * `ModelSelection` — selection of a model on a configured provider instance. * * The routing key is `instanceId` (a user-defined slug identifying one * configured provider instance). Drivers, credentials, working-directory * bindings, and any other per-instance state are recovered from the * runtime registry via the instance id. * * Wire legacy: persisted selections produced before the driver/instance * split carried a `provider: <driver-id>` field instead. The schema absorbs * that shape via a pre-decoding transform — `{provider, model}` is promoted * to `{instanceId: defaultInstanceIdForDriver(provider), model}`. No * post-decode compatibility code lives in the runtime; the transform is the * only compat surface. */const ModelSelectionWire = Schema.Struct({ instanceId: ProviderInstanceId, model: TrimmedNonEmptyString, options: Schema.optionalKey(ProviderOptionSelections),}); // Source shape for persisted legacy payloads. Fields are typed as// `Schema.Unknown` so malformed drafts still make it into the transform and// fail validation through the target schema (with proper error messages)// rather than at the source-struct layer where the error is less actionable.const ModelSelectionSource = Schema.Struct({ provider: Schema.optional(Schema.Unknown), instanceId: Schema.optional(Schema.Unknown), model: Schema.Unknown, options: Schema.optional(Schema.Unknown),}); export const ModelSelection = ModelSelectionSource.pipe( Schema.decodeTo( ModelSelectionWire, SchemaTransformation.transformOrFail({ decode: (raw) => { // Resolve the routing key: prefer an explicit `instanceId`; fall // back to promoting the legacy `provider` slug (the canonical // `defaultInstanceIdForDriver` mapping) so persisted rollout-era // payloads decode without data loss. The target schema brands the // string as `ProviderInstanceId`. const instanceIdSource = raw.instanceId !== undefined ? raw.instanceId : typeof raw.provider === "string" ? raw.provider : undefined; const base: Record<string, unknown> = { instanceId: instanceIdSource, model: raw.model, }; if (raw.options !== undefined) base.options = raw.options; return Effect.succeed(base as typeof ModelSelectionWire.Encoded); }, encode: (value) => { const base: Record<string, unknown> = { model: value.model, instanceId: value.instanceId, }; if (value.options !== undefined) base.options = value.options; return Effect.succeed(base as typeof ModelSelectionSource.Encoded); }, }), ),);export type ModelSelection = typeof ModelSelection.Type; export const RuntimeMode = Schema.Literals([ "approval-required", "auto-accept-edits", "full-access",]);export type RuntimeMode = typeof RuntimeMode.Type;export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access";export const ProviderInteractionMode = Schema.Literals(["default", "plan"]);export type ProviderInteractionMode = typeof ProviderInteractionMode.Type;export const DEFAULT_PROVIDER_INTERACTION_MODE: ProviderInteractionMode = "default";export const ProviderRequestKind = Schema.Literals(["command", "file-read", "file-change"]);export type ProviderRequestKind = typeof ProviderRequestKind.Type;export const AssistantDeliveryMode = Schema.Literals(["buffered", "streaming"]);export type AssistantDeliveryMode = typeof AssistantDeliveryMode.Type;export const ProviderApprovalDecision = Schema.Literals([ "accept", "acceptForSession", "decline", "cancel",]);export type ProviderApprovalDecision = typeof ProviderApprovalDecision.Type;export const ProviderUserInputAnswers = Schema.Record(Schema.String, Schema.Unknown);export type ProviderUserInputAnswers = typeof ProviderUserInputAnswers.Type; 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;const PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS = 14_000_000;const CHAT_ATTACHMENT_ID_MAX_CHARS = 128;// Correlation id is command id by design in this model.export const CorrelationId = CommandId;export type CorrelationId = typeof CorrelationId.Type; const ChatAttachmentId = TrimmedNonEmptyString.check( Schema.isMaxLength(CHAT_ATTACHMENT_ID_MAX_CHARS), Schema.isPattern(/^[a-z0-9_-]+$/i),);export type ChatAttachmentId = typeof ChatAttachmentId.Type; export const ChatImageAttachment = Schema.Struct({ type: Schema.Literal("image"), id: ChatAttachmentId, name: TrimmedNonEmptyString.check(Schema.isMaxLength(255)), mimeType: TrimmedNonEmptyString.check(Schema.isMaxLength(100), Schema.isPattern(/^image\//i)), sizeBytes: NonNegativeInt.check(Schema.isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)),});export type ChatImageAttachment = typeof ChatImageAttachment.Type; const UploadChatImageAttachment = Schema.Struct({ type: Schema.Literal("image"), name: TrimmedNonEmptyString.check(Schema.isMaxLength(255)), mimeType: TrimmedNonEmptyString.check(Schema.isMaxLength(100), Schema.isPattern(/^image\//i)), sizeBytes: NonNegativeInt.check(Schema.isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)), dataUrl: TrimmedNonEmptyString.check( Schema.isMaxLength(PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS), ),});export type UploadChatImageAttachment = typeof UploadChatImageAttachment.Type; export const ChatAttachment = Schema.Union([ChatImageAttachment]);export type ChatAttachment = typeof ChatAttachment.Type;const UploadChatAttachment = Schema.Union([UploadChatImageAttachment]);export type UploadChatAttachment = typeof UploadChatAttachment.Type; export const ProjectScriptIcon = Schema.Literals([ "play", "test", "lint", "configure", "build", "debug",]);export type ProjectScriptIcon = typeof ProjectScriptIcon.Type; export const ProjectScript = Schema.Struct({ id: TrimmedNonEmptyString, name: TrimmedNonEmptyString, command: TrimmedNonEmptyString, icon: ProjectScriptIcon, runOnWorktreeCreate: Schema.Boolean,});export type ProjectScript = typeof ProjectScript.Type; export const OrchestrationProject = Schema.Struct({ id: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, repositoryIdentity: Schema.optional(Schema.NullOr(RepositoryIdentity)), defaultModelSelection: Schema.NullOr(ModelSelection), scripts: Schema.Array(ProjectScript), createdAt: IsoDateTime, updatedAt: IsoDateTime, deletedAt: Schema.NullOr(IsoDateTime),});export type OrchestrationProject = typeof OrchestrationProject.Type; export const OrchestrationMessageRole = Schema.Literals(["user", "assistant", "system"]);export type OrchestrationMessageRole = typeof OrchestrationMessageRole.Type; export const OrchestrationMessage = Schema.Struct({ id: MessageId, role: OrchestrationMessageRole, text: Schema.String, attachments: Schema.optional(Schema.Array(ChatAttachment)), turnId: Schema.NullOr(TurnId), streaming: Schema.Boolean, createdAt: IsoDateTime, updatedAt: IsoDateTime,});export type OrchestrationMessage = typeof OrchestrationMessage.Type; export const OrchestrationProposedPlanId = TrimmedNonEmptyString;export type OrchestrationProposedPlanId = typeof OrchestrationProposedPlanId.Type; export const OrchestrationProposedPlan = Schema.Struct({ id: OrchestrationProposedPlanId, turnId: Schema.NullOr(TurnId), planMarkdown: TrimmedNonEmptyString, implementedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), implementationThreadId: Schema.NullOr(ThreadId).pipe( Schema.withDecodingDefault(Effect.succeed(null)), ), createdAt: IsoDateTime, updatedAt: IsoDateTime,});export type OrchestrationProposedPlan = typeof OrchestrationProposedPlan.Type; const SourceProposedPlanReference = Schema.Struct({ threadId: ThreadId, planId: OrchestrationProposedPlanId,}); export const OrchestrationSessionStatus = Schema.Literals([ "idle", "starting", "running", "ready", "interrupted", "stopped", "error",]);export type OrchestrationSessionStatus = typeof OrchestrationSessionStatus.Type; export const OrchestrationSession = Schema.Struct({ threadId: ThreadId, status: OrchestrationSessionStatus, providerName: Schema.NullOr(TrimmedNonEmptyString), providerInstanceId: Schema.optional(ProviderInstanceId), runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), activeTurnId: Schema.NullOr(TurnId), lastError: Schema.NullOr(TrimmedNonEmptyString), updatedAt: IsoDateTime,});export type OrchestrationSession = typeof OrchestrationSession.Type; export const OrchestrationCheckpointFile = Schema.Struct({ path: TrimmedNonEmptyString, kind: TrimmedNonEmptyString, additions: NonNegativeInt, deletions: NonNegativeInt,});export type OrchestrationCheckpointFile = typeof OrchestrationCheckpointFile.Type; export const OrchestrationCheckpointStatus = Schema.Literals(["ready", "missing", "error"]);export type OrchestrationCheckpointStatus = typeof OrchestrationCheckpointStatus.Type; export const OrchestrationCheckpointSummary = Schema.Struct({ turnId: TurnId, checkpointTurnCount: NonNegativeInt, checkpointRef: CheckpointRef, status: OrchestrationCheckpointStatus, files: Schema.Array(OrchestrationCheckpointFile), assistantMessageId: Schema.NullOr(MessageId), completedAt: IsoDateTime,});export type OrchestrationCheckpointSummary = typeof OrchestrationCheckpointSummary.Type; export const OrchestrationThreadActivityTone = Schema.Literals([ "info", "tool", "approval", "error",]);export type OrchestrationThreadActivityTone = typeof OrchestrationThreadActivityTone.Type; export const OrchestrationThreadActivity = Schema.Struct({ id: EventId, tone: OrchestrationThreadActivityTone, kind: TrimmedNonEmptyString, summary: TrimmedNonEmptyString, payload: Schema.Unknown, turnId: Schema.NullOr(TurnId), sequence: Schema.optional(NonNegativeInt), createdAt: IsoDateTime,});export type OrchestrationThreadActivity = typeof OrchestrationThreadActivity.Type; const OrchestrationLatestTurnState = Schema.Literals([ "running", "interrupted", "completed", "error",]);export type OrchestrationLatestTurnState = typeof OrchestrationLatestTurnState.Type; export const OrchestrationLatestTurn = Schema.Struct({ turnId: TurnId, state: OrchestrationLatestTurnState, requestedAt: IsoDateTime, startedAt: Schema.NullOr(IsoDateTime), completedAt: Schema.NullOr(IsoDateTime), assistantMessageId: Schema.NullOr(MessageId), sourceProposedPlan: Schema.optional(SourceProposedPlanReference),});export type OrchestrationLatestTurn = typeof OrchestrationLatestTurn.Type; export const OrchestrationThread = Schema.Struct({ id: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), latestTurn: Schema.NullOr(OrchestrationLatestTurn), createdAt: IsoDateTime, updatedAt: IsoDateTime, archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), deletedAt: Schema.NullOr(IsoDateTime), messages: Schema.Array(OrchestrationMessage), proposedPlans: Schema.Array(OrchestrationProposedPlan).pipe( Schema.withDecodingDefault(Effect.succeed([])), ), activities: Schema.Array(OrchestrationThreadActivity), checkpoints: Schema.Array(OrchestrationCheckpointSummary), session: Schema.NullOr(OrchestrationSession),});export type OrchestrationThread = typeof OrchestrationThread.Type; export const OrchestrationReadModel = Schema.Struct({ snapshotSequence: NonNegativeInt, projects: Schema.Array(OrchestrationProject), threads: Schema.Array(OrchestrationThread), updatedAt: IsoDateTime,});export type OrchestrationReadModel = typeof OrchestrationReadModel.Type; export const OrchestrationProjectShell = Schema.Struct({ id: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, repositoryIdentity: Schema.optional(Schema.NullOr(RepositoryIdentity)), defaultModelSelection: Schema.NullOr(ModelSelection), scripts: Schema.Array(ProjectScript), createdAt: IsoDateTime, updatedAt: IsoDateTime,});export type OrchestrationProjectShell = typeof OrchestrationProjectShell.Type; export const OrchestrationThreadShell = Schema.Struct({ id: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), latestTurn: Schema.NullOr(OrchestrationLatestTurn), createdAt: IsoDateTime, updatedAt: IsoDateTime, archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), session: Schema.NullOr(OrchestrationSession), latestUserMessageAt: Schema.NullOr(IsoDateTime), hasPendingApprovals: Schema.Boolean, hasPendingUserInput: Schema.Boolean, hasActionableProposedPlan: Schema.Boolean,});export type OrchestrationThreadShell = typeof OrchestrationThreadShell.Type; export const OrchestrationShellSnapshot = Schema.Struct({ snapshotSequence: NonNegativeInt, projects: Schema.Array(OrchestrationProjectShell), threads: Schema.Array(OrchestrationThreadShell), updatedAt: IsoDateTime,});export type OrchestrationShellSnapshot = typeof OrchestrationShellSnapshot.Type; export const OrchestrationShellStreamEvent = Schema.Union([ Schema.Struct({ kind: Schema.Literal("project-upserted"), sequence: NonNegativeInt, project: OrchestrationProjectShell, }), Schema.Struct({ kind: Schema.Literal("project-removed"), sequence: NonNegativeInt, projectId: ProjectId, }), Schema.Struct({ kind: Schema.Literal("thread-upserted"), sequence: NonNegativeInt, thread: OrchestrationThreadShell, }), Schema.Struct({ kind: Schema.Literal("thread-removed"), sequence: NonNegativeInt, threadId: ThreadId, }),]);export type OrchestrationShellStreamEvent = typeof OrchestrationShellStreamEvent.Type; export const OrchestrationShellStreamItem = Schema.Union([ Schema.Struct({ kind: Schema.Literal("snapshot"), snapshot: OrchestrationShellSnapshot, }), OrchestrationShellStreamEvent,]);export type OrchestrationShellStreamItem = typeof OrchestrationShellStreamItem.Type; export const OrchestrationSubscribeThreadInput = Schema.Struct({ threadId: ThreadId,});export type OrchestrationSubscribeThreadInput = typeof OrchestrationSubscribeThreadInput.Type; export const OrchestrationThreadDetailSnapshot = Schema.Struct({ snapshotSequence: NonNegativeInt, thread: OrchestrationThread,});export type OrchestrationThreadDetailSnapshot = typeof OrchestrationThreadDetailSnapshot.Type; export const ProjectCreateCommand = Schema.Struct({ type: Schema.Literal("project.create"), commandId: CommandId, projectId: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, createWorkspaceRootIfMissing: Schema.optional(Schema.Boolean), defaultModelSelection: Schema.optional(Schema.NullOr(ModelSelection)), createdAt: IsoDateTime,}); const ProjectMetaUpdateCommand = Schema.Struct({ type: Schema.Literal("project.meta.update"), commandId: CommandId, projectId: ProjectId, title: Schema.optional(TrimmedNonEmptyString), workspaceRoot: Schema.optional(TrimmedNonEmptyString), defaultModelSelection: Schema.optional(Schema.NullOr(ModelSelection)), scripts: Schema.optional(Schema.Array(ProjectScript)),}); const ProjectDeleteCommand = Schema.Struct({ type: Schema.Literal("project.delete"), commandId: CommandId, projectId: ProjectId, force: Schema.optional(Schema.Boolean),}); const ThreadCreateCommand = Schema.Struct({ type: Schema.Literal("thread.create"), commandId: CommandId, threadId: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), createdAt: IsoDateTime,}); const ThreadDeleteCommand = Schema.Struct({ type: Schema.Literal("thread.delete"), commandId: CommandId,Lines 1–500 of 1278. Load more
import * as Effect from "effect/Effect"; import * as Option from "effect/Option"; import * as Schema from "effect/Schema"; import * as SchemaIssue from "effect/SchemaIssue"; import * as SchemaTransformation from "effect/SchemaTransformation"; import * as Struct from "effect/Struct"; import { ProviderOptionSelections } from "./model.ts"; import { RepositoryIdentity } from "./environment.ts"; import { ApprovalRequestId, CheckpointRef, CommandId, EventId, IsoDateTime, MessageId, NonNegativeInt, ProjectId, ProviderItemId, ThreadId, TrimmedNonEmptyString, TurnId, } from "./baseSchemas.ts"; import { ProviderInstanceId } from "./providerInstance.ts"; export const ORCHESTRATION_WS_METHODS = { dispatchCommand: "orchestration.dispatchCommand", getTurnDiff: "orchestration.getTurnDiff", getFullThreadDiff: "orchestration.getFullThreadDiff", replayEvents: "orchestration.replayEvents", getArchivedShellSnapshot: "orchestration.getArchivedShellSnapshot", subscribeShell: "orchestration.subscribeShell", subscribeThread: "orchestration.subscribeThread", } as const; export const ProviderApprovalPolicy = Schema.Literals([ "untrusted", "on-failure", "on-request", "never", ]); export type ProviderApprovalPolicy = typeof ProviderApprovalPolicy.Type; export const ProviderSandboxMode = Schema.Literals([ "read-only", "workspace-write", "danger-full-access", ]); export type ProviderSandboxMode = typeof ProviderSandboxMode.Type; /** * `ModelSelection` — selection of a model on a configured provider instance. * * The routing key is `instanceId` (a user-defined slug identifying one * configured provider instance). Drivers, credentials, working-directory * bindings, and any other per-instance state are recovered from the * runtime registry via the instance id. * * Wire legacy: persisted selections produced before the driver/instance * split carried a `provider: <driver-id>` field instead. The schema absorbs * that shape via a pre-decoding transform — `{provider, model}` is promoted * to `{instanceId: defaultInstanceIdForDriver(provider), model}`. No * post-decode compatibility code lives in the runtime; the transform is the * only compat surface. */ const ModelSelectionWire = Schema.Struct({ instanceId: ProviderInstanceId, model: TrimmedNonEmptyString, options: Schema.optionalKey(ProviderOptionSelections), }); // Source shape for persisted legacy payloads. Fields are typed as // `Schema.Unknown` so malformed drafts still make it into the transform and // fail validation through the target schema (with proper error messages) // rather than at the source-struct layer where the error is less actionable. const ModelSelectionSource = Schema.Struct({ provider: Schema.optional(Schema.Unknown), instanceId: Schema.optional(Schema.Unknown), model: Schema.Unknown, options: Schema.optional(Schema.Unknown), }); export const ModelSelection = ModelSelectionSource.pipe( Schema.decodeTo( ModelSelectionWire, SchemaTransformation.transformOrFail({ decode: (raw) => { // Resolve the routing key: prefer an explicit `instanceId`; fall // back to promoting the legacy `provider` slug (the canonical // `defaultInstanceIdForDriver` mapping) so persisted rollout-era // payloads decode without data loss. The target schema brands the // string as `ProviderInstanceId`. const instanceIdSource = raw.instanceId !== undefined ? raw.instanceId : typeof raw.provider === "string" ? raw.provider : undefined; const base: Record<string, unknown> = { instanceId: instanceIdSource, model: raw.model, }; if (raw.options !== undefined) base.options = raw.options; return Effect.succeed(base as typeof ModelSelectionWire.Encoded); }, encode: (value) => { const base: Record<string, unknown> = { model: value.model, instanceId: value.instanceId, }; if (value.options !== undefined) base.options = value.options; return Effect.succeed(base as typeof ModelSelectionSource.Encoded); }, }), ), ); export type ModelSelection = typeof ModelSelection.Type; export const RuntimeMode = Schema.Literals([ "approval-required", "auto-accept-edits", "full-access", ]); export type RuntimeMode = typeof RuntimeMode.Type; export const DEFAULT_RUNTIME_MODE: RuntimeMode = "full-access"; export const ProviderInteractionMode = Schema.Literals(["default", "plan"]); export type ProviderInteractionMode = typeof ProviderInteractionMode.Type; export const DEFAULT_PROVIDER_INTERACTION_MODE: ProviderInteractionMode = "default"; export const ProviderRequestKind = Schema.Literals(["command", "file-read", "file-change"]); export type ProviderRequestKind = typeof ProviderRequestKind.Type; export const AssistantDeliveryMode = Schema.Literals(["buffered", "streaming"]); export type AssistantDeliveryMode = typeof AssistantDeliveryMode.Type; export const ProviderApprovalDecision = Schema.Literals([ "accept", "acceptForSession", "decline", "cancel", ]); export type ProviderApprovalDecision = typeof ProviderApprovalDecision.Type; export const ProviderUserInputAnswers = Schema.Record(Schema.String, Schema.Unknown); export type ProviderUserInputAnswers = typeof ProviderUserInputAnswers.Type; 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; const PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS = 14_000_000; const CHAT_ATTACHMENT_ID_MAX_CHARS = 128; // Correlation id is command id by design in this model. export const CorrelationId = CommandId; export type CorrelationId = typeof CorrelationId.Type; const ChatAttachmentId = TrimmedNonEmptyString.check( Schema.isMaxLength(CHAT_ATTACHMENT_ID_MAX_CHARS), Schema.isPattern(/^[a-z0-9_-]+$/i), ); export type ChatAttachmentId = typeof ChatAttachmentId.Type; export const ChatImageAttachment = Schema.Struct({ type: Schema.Literal("image"), id: ChatAttachmentId, name: TrimmedNonEmptyString.check(Schema.isMaxLength(255)), mimeType: TrimmedNonEmptyString.check(Schema.isMaxLength(100), Schema.isPattern(/^image\//i)), sizeBytes: NonNegativeInt.check(Schema.isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)), }); export type ChatImageAttachment = typeof ChatImageAttachment.Type; const UploadChatImageAttachment = Schema.Struct({ type: Schema.Literal("image"), name: TrimmedNonEmptyString.check(Schema.isMaxLength(255)), mimeType: TrimmedNonEmptyString.check(Schema.isMaxLength(100), Schema.isPattern(/^image\//i)), sizeBytes: NonNegativeInt.check(Schema.isLessThanOrEqualTo(PROVIDER_SEND_TURN_MAX_IMAGE_BYTES)), dataUrl: TrimmedNonEmptyString.check( Schema.isMaxLength(PROVIDER_SEND_TURN_MAX_IMAGE_DATA_URL_CHARS), ), }); export type UploadChatImageAttachment = typeof UploadChatImageAttachment.Type; export const ChatAttachment = Schema.Union([ChatImageAttachment]); export type ChatAttachment = typeof ChatAttachment.Type; const UploadChatAttachment = Schema.Union([UploadChatImageAttachment]); export type UploadChatAttachment = typeof UploadChatAttachment.Type; export const ProjectScriptIcon = Schema.Literals([ "play", "test", "lint", "configure", "build", "debug", ]); export type ProjectScriptIcon = typeof ProjectScriptIcon.Type; export const ProjectScript = Schema.Struct({ id: TrimmedNonEmptyString, name: TrimmedNonEmptyString, command: TrimmedNonEmptyString, icon: ProjectScriptIcon, runOnWorktreeCreate: Schema.Boolean, }); export type ProjectScript = typeof ProjectScript.Type; export const OrchestrationProject = Schema.Struct({ id: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, repositoryIdentity: Schema.optional(Schema.NullOr(RepositoryIdentity)), defaultModelSelection: Schema.NullOr(ModelSelection), scripts: Schema.Array(ProjectScript), createdAt: IsoDateTime, updatedAt: IsoDateTime, deletedAt: Schema.NullOr(IsoDateTime), }); export type OrchestrationProject = typeof OrchestrationProject.Type; export const OrchestrationMessageRole = Schema.Literals(["user", "assistant", "system"]); export type OrchestrationMessageRole = typeof OrchestrationMessageRole.Type; export const OrchestrationMessage = Schema.Struct({ id: MessageId, role: OrchestrationMessageRole, text: Schema.String, attachments: Schema.optional(Schema.Array(ChatAttachment)), turnId: Schema.NullOr(TurnId), streaming: Schema.Boolean, createdAt: IsoDateTime, updatedAt: IsoDateTime, }); export type OrchestrationMessage = typeof OrchestrationMessage.Type; export const OrchestrationProposedPlanId = TrimmedNonEmptyString; export type OrchestrationProposedPlanId = typeof OrchestrationProposedPlanId.Type; export const OrchestrationProposedPlan = Schema.Struct({ id: OrchestrationProposedPlanId, turnId: Schema.NullOr(TurnId), planMarkdown: TrimmedNonEmptyString, implementedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), implementationThreadId: Schema.NullOr(ThreadId).pipe( Schema.withDecodingDefault(Effect.succeed(null)), ), createdAt: IsoDateTime, updatedAt: IsoDateTime, }); export type OrchestrationProposedPlan = typeof OrchestrationProposedPlan.Type; const SourceProposedPlanReference = Schema.Struct({ threadId: ThreadId, planId: OrchestrationProposedPlanId, }); export const OrchestrationSessionStatus = Schema.Literals([ "idle", "starting", "running", "ready", "interrupted", "stopped", "error", ]); export type OrchestrationSessionStatus = typeof OrchestrationSessionStatus.Type; export const OrchestrationSession = Schema.Struct({ threadId: ThreadId, status: OrchestrationSessionStatus, providerName: Schema.NullOr(TrimmedNonEmptyString), providerInstanceId: Schema.optional(ProviderInstanceId), runtimeMode: RuntimeMode.pipe(Schema.withDecodingDefault(Effect.succeed(DEFAULT_RUNTIME_MODE))), activeTurnId: Schema.NullOr(TurnId), lastError: Schema.NullOr(TrimmedNonEmptyString), updatedAt: IsoDateTime, }); export type OrchestrationSession = typeof OrchestrationSession.Type; export const OrchestrationCheckpointFile = Schema.Struct({ path: TrimmedNonEmptyString, kind: TrimmedNonEmptyString, additions: NonNegativeInt, deletions: NonNegativeInt, }); export type OrchestrationCheckpointFile = typeof OrchestrationCheckpointFile.Type; export const OrchestrationCheckpointStatus = Schema.Literals(["ready", "missing", "error"]); export type OrchestrationCheckpointStatus = typeof OrchestrationCheckpointStatus.Type; export const OrchestrationCheckpointSummary = Schema.Struct({ turnId: TurnId, checkpointTurnCount: NonNegativeInt, checkpointRef: CheckpointRef, status: OrchestrationCheckpointStatus, files: Schema.Array(OrchestrationCheckpointFile), assistantMessageId: Schema.NullOr(MessageId), completedAt: IsoDateTime, }); export type OrchestrationCheckpointSummary = typeof OrchestrationCheckpointSummary.Type; export const OrchestrationThreadActivityTone = Schema.Literals([ "info", "tool", "approval", "error", ]); export type OrchestrationThreadActivityTone = typeof OrchestrationThreadActivityTone.Type; export const OrchestrationThreadActivity = Schema.Struct({ id: EventId, tone: OrchestrationThreadActivityTone, kind: TrimmedNonEmptyString, summary: TrimmedNonEmptyString, payload: Schema.Unknown, turnId: Schema.NullOr(TurnId), sequence: Schema.optional(NonNegativeInt), createdAt: IsoDateTime, }); export type OrchestrationThreadActivity = typeof OrchestrationThreadActivity.Type; const OrchestrationLatestTurnState = Schema.Literals([ "running", "interrupted", "completed", "error", ]); export type OrchestrationLatestTurnState = typeof OrchestrationLatestTurnState.Type; export const OrchestrationLatestTurn = Schema.Struct({ turnId: TurnId, state: OrchestrationLatestTurnState, requestedAt: IsoDateTime, startedAt: Schema.NullOr(IsoDateTime), completedAt: Schema.NullOr(IsoDateTime), assistantMessageId: Schema.NullOr(MessageId), sourceProposedPlan: Schema.optional(SourceProposedPlanReference), }); export type OrchestrationLatestTurn = typeof OrchestrationLatestTurn.Type; export const OrchestrationThread = Schema.Struct({ id: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), latestTurn: Schema.NullOr(OrchestrationLatestTurn), createdAt: IsoDateTime, updatedAt: IsoDateTime, archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), deletedAt: Schema.NullOr(IsoDateTime), messages: Schema.Array(OrchestrationMessage), proposedPlans: Schema.Array(OrchestrationProposedPlan).pipe( Schema.withDecodingDefault(Effect.succeed([])), ), activities: Schema.Array(OrchestrationThreadActivity), checkpoints: Schema.Array(OrchestrationCheckpointSummary), session: Schema.NullOr(OrchestrationSession), }); export type OrchestrationThread = typeof OrchestrationThread.Type; export const OrchestrationReadModel = Schema.Struct({ snapshotSequence: NonNegativeInt, projects: Schema.Array(OrchestrationProject), threads: Schema.Array(OrchestrationThread), updatedAt: IsoDateTime, }); export type OrchestrationReadModel = typeof OrchestrationReadModel.Type; export const OrchestrationProjectShell = Schema.Struct({ id: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, repositoryIdentity: Schema.optional(Schema.NullOr(RepositoryIdentity)), defaultModelSelection: Schema.NullOr(ModelSelection), scripts: Schema.Array(ProjectScript), createdAt: IsoDateTime, updatedAt: IsoDateTime, }); export type OrchestrationProjectShell = typeof OrchestrationProjectShell.Type; export const OrchestrationThreadShell = Schema.Struct({ id: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), latestTurn: Schema.NullOr(OrchestrationLatestTurn), createdAt: IsoDateTime, updatedAt: IsoDateTime, archivedAt: Schema.NullOr(IsoDateTime).pipe(Schema.withDecodingDefault(Effect.succeed(null))), session: Schema.NullOr(OrchestrationSession), latestUserMessageAt: Schema.NullOr(IsoDateTime), hasPendingApprovals: Schema.Boolean, hasPendingUserInput: Schema.Boolean, hasActionableProposedPlan: Schema.Boolean, }); export type OrchestrationThreadShell = typeof OrchestrationThreadShell.Type; export const OrchestrationShellSnapshot = Schema.Struct({ snapshotSequence: NonNegativeInt, projects: Schema.Array(OrchestrationProjectShell), threads: Schema.Array(OrchestrationThreadShell), updatedAt: IsoDateTime, }); export type OrchestrationShellSnapshot = typeof OrchestrationShellSnapshot.Type; export const OrchestrationShellStreamEvent = Schema.Union([ Schema.Struct({ kind: Schema.Literal("project-upserted"), sequence: NonNegativeInt, project: OrchestrationProjectShell, }), Schema.Struct({ kind: Schema.Literal("project-removed"), sequence: NonNegativeInt, projectId: ProjectId, }), Schema.Struct({ kind: Schema.Literal("thread-upserted"), sequence: NonNegativeInt, thread: OrchestrationThreadShell, }), Schema.Struct({ kind: Schema.Literal("thread-removed"), sequence: NonNegativeInt, threadId: ThreadId, }), ]); export type OrchestrationShellStreamEvent = typeof OrchestrationShellStreamEvent.Type; export const OrchestrationShellStreamItem = Schema.Union([ Schema.Struct({ kind: Schema.Literal("snapshot"), snapshot: OrchestrationShellSnapshot, }), OrchestrationShellStreamEvent, ]); export type OrchestrationShellStreamItem = typeof OrchestrationShellStreamItem.Type; export const OrchestrationSubscribeThreadInput = Schema.Struct({ threadId: ThreadId, }); export type OrchestrationSubscribeThreadInput = typeof OrchestrationSubscribeThreadInput.Type; export const OrchestrationThreadDetailSnapshot = Schema.Struct({ snapshotSequence: NonNegativeInt, thread: OrchestrationThread, }); export type OrchestrationThreadDetailSnapshot = typeof OrchestrationThreadDetailSnapshot.Type; export const ProjectCreateCommand = Schema.Struct({ type: Schema.Literal("project.create"), commandId: CommandId, projectId: ProjectId, title: TrimmedNonEmptyString, workspaceRoot: TrimmedNonEmptyString, createWorkspaceRootIfMissing: Schema.optional(Schema.Boolean), defaultModelSelection: Schema.optional(Schema.NullOr(ModelSelection)), createdAt: IsoDateTime, }); const ProjectMetaUpdateCommand = Schema.Struct({ type: Schema.Literal("project.meta.update"), commandId: CommandId, projectId: ProjectId, title: Schema.optional(TrimmedNonEmptyString), workspaceRoot: Schema.optional(TrimmedNonEmptyString), defaultModelSelection: Schema.optional(Schema.NullOr(ModelSelection)), scripts: Schema.optional(Schema.Array(ProjectScript)), }); const ProjectDeleteCommand = Schema.Struct({ type: Schema.Literal("project.delete"), commandId: CommandId, projectId: ProjectId, force: Schema.optional(Schema.Boolean), }); const ThreadCreateCommand = Schema.Struct({ type: Schema.Literal("thread.create"), commandId: CommandId, threadId: ThreadId, projectId: ProjectId, title: TrimmedNonEmptyString, modelSelection: ModelSelection, runtimeMode: RuntimeMode, interactionMode: ProviderInteractionMode.pipe( Schema.withDecodingDefault(Effect.succeed(DEFAULT_PROVIDER_INTERACTION_MODE)), ), branch: Schema.NullOr(TrimmedNonEmptyString), worktreePath: Schema.NullOr(TrimmedNonEmptyString), createdAt: IsoDateTime, }); const ThreadDeleteCommand = Schema.Struct({ type: Schema.Literal("thread.delete"), commandId: CommandId,