diff --git a/apps/server/integration/orchestrationEngine.integration.test.ts b/apps/server/integration/orchestrationEngine.integration.test.ts index 3ccb19ebd34b04470643286af367cc010d234faa..5572b6e3eed925847c0617c0b96202262eb8c6b5 100644 --- a/apps/server/integration/orchestrationEngine.integration.test.ts +++ b/apps/server/integration/orchestrationEngine.integration.test.ts @@ -136,6 +136,8 @@ const startTurn = (input: { text: input.text, attachments: [], }, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: nowIso(), }); diff --git a/apps/server/src/orchestration/Layers/CheckpointReactor.test.ts b/apps/server/src/orchestration/Layers/CheckpointReactor.test.ts index 8be890c5998ecbfac02c5190f0edc44043a3a0fa..769310380cca8f73ee5c98ed2516568ea1de267f 100644 --- a/apps/server/src/orchestration/Layers/CheckpointReactor.test.ts +++ b/apps/server/src/orchestration/Layers/CheckpointReactor.test.ts @@ -317,6 +317,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, @@ -394,6 +396,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, @@ -445,6 +449,8 @@ describe("CheckpointReactor", () => { text: "start turn", attachments: [], }, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: new Date().toISOString(), }), ); @@ -481,6 +487,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-missing"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-missing"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: asTurnId("turn-missing-cwd"), lastError: null, updatedAt: createdAt, @@ -529,6 +537,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, @@ -580,6 +590,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, @@ -634,6 +646,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, @@ -713,6 +727,8 @@ describe("CheckpointReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: createdAt, diff --git a/apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts b/apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts index 6680402a8d639b4320e96ea0179176bb557a88ec..925826bb1b43cc00eca0efd4337f0c209dd9cc98 100644 --- a/apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts +++ b/apps/server/src/orchestration/Layers/OrchestrationEngine.test.ts @@ -92,6 +92,8 @@ describe("OrchestrationEngine", () => { text: "hello", attachments: [], }, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt, }), ); @@ -428,6 +430,8 @@ describe("OrchestrationEngine", () => { text: "hello", attachments: [], }, + approvalPolicy: "on-request" as const, + sandboxMode: "workspace-write" as const, createdAt, }; @@ -586,6 +590,8 @@ describe("OrchestrationEngine", () => { text: "hello", attachments: [], }, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: now(), }), ), diff --git a/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts b/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts index 9cc29bcd8eac19c723ad2340435803bb2165fafe..83fcb579579dbf1df400e70214f949db9761aaff 100644 --- a/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts +++ b/apps/server/src/orchestration/Layers/ProjectionPipeline.test.ts @@ -794,6 +794,8 @@ it.effect("restores pending turn-start metadata across projection pipeline resta payload: { threadId, messageId, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: turnStartedAt, }, }); @@ -827,6 +829,8 @@ it.effect("restores pending turn-start metadata across projection pipeline resta providerName: "codex", providerSessionId: ProviderSessionId.makeUnsafe("provider-session-restart"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-restart"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: turnId, lastError: null, updatedAt: sessionSetAt, diff --git a/apps/server/src/orchestration/Layers/ProjectionPipeline.ts b/apps/server/src/orchestration/Layers/ProjectionPipeline.ts index 71ad8db405d84d88fce91487012306125983500d..262d4545a4a1e0322e16a1a2a9a6fdb320558d61 100644 --- a/apps/server/src/orchestration/Layers/ProjectionPipeline.ts +++ b/apps/server/src/orchestration/Layers/ProjectionPipeline.ts @@ -473,6 +473,8 @@ const makeOrchestrationProjectionPipeline = Effect.gen(function* () { providerName: event.payload.session.providerName, providerSessionId: event.payload.session.providerSessionId, providerThreadId: event.payload.session.providerThreadId, + approvalPolicy: event.payload.session.approvalPolicy, + sandboxMode: event.payload.session.sandboxMode, activeTurnId: event.payload.session.activeTurnId, lastError: event.payload.session.lastError, updatedAt: event.payload.session.updatedAt, diff --git a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts index 824f9a7cfd67f272eec0a6d100c866cf1fc94042..97dadf01cb5a77e2e3ea4cd3f90fabdfedb5a31f 100644 --- a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts +++ b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.test.ts @@ -143,6 +143,8 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { provider_name, provider_session_id, provider_thread_id, + approval_policy, + sandbox_mode, active_turn_id, last_error, updated_at @@ -153,6 +155,8 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { 'codex', 'provider-session-1', 'provider-thread-1', + 'on-request', + 'workspace-write', 'turn-1', NULL, '2026-02-24T00:00:07.000Z' @@ -282,6 +286,8 @@ projectionSnapshotLayer("ProjectionSnapshotQuery", (it) => { providerName: "codex", providerSessionId: asProviderSessionId("provider-session-1"), providerThreadId: asProviderThreadId("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: asTurnId("turn-1"), lastError: null, updatedAt: "2026-02-24T00:00:07.000Z", diff --git a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts index babf83171a63d85cc8a9e38ca8de0fc91e19ed1e..fe2f96615cb1358d40db28288e80e60d56fc2d2c 100644 --- a/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts +++ b/apps/server/src/orchestration/Layers/ProjectionSnapshotQuery.ts @@ -196,6 +196,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () { provider_name AS "providerName", provider_session_id AS "providerSessionId", provider_thread_id AS "providerThreadId", + approval_policy AS "approvalPolicy", + sandbox_mode AS "sandboxMode", active_turn_id AS "activeTurnId", last_error AS "lastError", updated_at AS "updatedAt" @@ -378,6 +380,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () { providerName: row.providerName, providerSessionId: row.providerSessionId, providerThreadId: row.providerThreadId, + approvalPolicy: row.approvalPolicy, + sandboxMode: row.sandboxMode, activeTurnId: row.activeTurnId, lastError: row.lastError, updatedAt: row.updatedAt, diff --git a/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts b/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts index bacb78607b45b0c27eb67bf59a8c9c94e9071721..eba9836a3c503e496b67fc500495d21abf75da07 100644 --- a/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts +++ b/apps/server/src/orchestration/Layers/ProviderCommandReactor.test.ts @@ -319,6 +319,8 @@ describe("ProviderCommandReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: asTurnId("turn-1"), lastError: null, updatedAt: now, @@ -358,6 +360,8 @@ describe("ProviderCommandReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: now, @@ -400,6 +404,8 @@ describe("ProviderCommandReactor", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, lastError: null, updatedAt: now, diff --git a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts index bebd7b8202ddf2af6fdaeb113082753daf79e7ee..3ae4dc99b5f59695da16e22a2e656d67f428e386 100644 --- a/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts +++ b/apps/server/src/orchestration/Layers/ProviderCommandReactor.ts @@ -64,6 +64,8 @@ const serverCommandId = (tag: string): CommandId => const HANDLED_TURN_START_KEY_MAX = 10_000; const HANDLED_TURN_START_KEY_TTL = Duration.minutes(30); +const DEFAULT_APPROVAL_POLICY: ProviderApprovalPolicy = "never"; +const DEFAULT_SANDBOX_MODE: ProviderSandboxMode = "workspace-write"; const make = Effect.gen(function* () { const orchestrationEngine = yield* OrchestrationEngineService; @@ -143,8 +145,10 @@ const make = Effect.gen(function* () { return yield* Effect.die(new Error(`Thread '${threadId}' was not found in read model.`)); } - const desiredApprovalPolicy = options?.approvalPolicy ?? thread.session?.approvalPolicy; - const desiredSandboxMode = options?.sandboxMode ?? thread.session?.sandboxMode; + const desiredApprovalPolicy = + options?.approvalPolicy ?? thread.session?.approvalPolicy ?? DEFAULT_APPROVAL_POLICY; + const desiredSandboxMode = + options?.sandboxMode ?? thread.session?.sandboxMode ?? DEFAULT_SANDBOX_MODE; const preferredProvider: ProviderKind | undefined = thread.session?.providerName === "codex" || thread.session?.providerName === "claudeCode" ? thread.session.providerName @@ -160,8 +164,8 @@ const make = Effect.gen(function* () { ...(effectiveCwd ? { cwd: effectiveCwd } : {}), ...(thread.model ? { model: thread.model } : {}), ...(resumeThreadId ? { resumeThreadId } : {}), - ...(desiredApprovalPolicy !== undefined ? { approvalPolicy: desiredApprovalPolicy } : {}), - ...(desiredSandboxMode !== undefined ? { sandboxMode: desiredSandboxMode } : {}), + approvalPolicy: desiredApprovalPolicy, + sandboxMode: desiredSandboxMode, }); const bindSessionToThread = (session: ProviderSession) => @@ -173,8 +177,8 @@ const make = Effect.gen(function* () { providerName: session.provider, providerSessionId: session.sessionId, providerThreadId: session.threadId ?? null, - ...(desiredApprovalPolicy !== undefined ? { approvalPolicy: desiredApprovalPolicy } : {}), - ...(desiredSandboxMode !== undefined ? { sandboxMode: desiredSandboxMode } : {}), + approvalPolicy: desiredApprovalPolicy, + sandboxMode: desiredSandboxMode, // Provider turn ids are not orchestration turn ids. activeTurnId: null, lastError: session.lastError ?? null, @@ -211,8 +215,8 @@ const make = Effect.gen(function* () { readonly attachments?: ReadonlyArray; readonly model?: string; readonly effort?: string; - readonly approvalPolicy?: ProviderApprovalPolicy; - readonly sandboxMode?: ProviderSandboxMode; + readonly approvalPolicy: ProviderApprovalPolicy; + readonly sandboxMode: ProviderSandboxMode; readonly createdAt: string; }) { const thread = yield* resolveThread(input.threadId); @@ -220,8 +224,8 @@ const make = Effect.gen(function* () { return; } const sessionId = yield* ensureSessionForThread(input.threadId, input.createdAt, { - ...(input.approvalPolicy !== undefined ? { approvalPolicy: input.approvalPolicy } : {}), - ...(input.sandboxMode !== undefined ? { sandboxMode: input.sandboxMode } : {}), + approvalPolicy: input.approvalPolicy, + sandboxMode: input.sandboxMode, }); const normalizedInput = toNonEmptyProviderInput(input.messageText); const normalizedAttachments = input.attachments ?? []; @@ -267,10 +271,8 @@ const make = Effect.gen(function* () { ...(message.attachments !== undefined ? { attachments: message.attachments } : {}), ...(event.payload.model !== undefined ? { model: event.payload.model } : {}), ...(event.payload.effort !== undefined ? { effort: event.payload.effort } : {}), - ...(event.payload.approvalPolicy !== undefined - ? { approvalPolicy: event.payload.approvalPolicy } - : {}), - ...(event.payload.sandboxMode !== undefined ? { sandboxMode: event.payload.sandboxMode } : {}), + approvalPolicy: event.payload.approvalPolicy, + sandboxMode: event.payload.sandboxMode, createdAt: event.payload.createdAt, }); }); @@ -347,6 +349,8 @@ const make = Effect.gen(function* () { providerName: thread.session?.providerName ?? null, providerSessionId: null, providerThreadId: null, + approvalPolicy: thread.session?.approvalPolicy ?? DEFAULT_APPROVAL_POLICY, + sandboxMode: thread.session?.sandboxMode ?? DEFAULT_SANDBOX_MODE, activeTurnId: null, lastError: thread.session?.lastError ?? null, updatedAt: now, diff --git a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts index 42247506410b5b3fac0ac2a38930e9fa4862b7ca..7a3a029e89a0fccd7990a7601486acb5af722b06 100644 --- a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts +++ b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.test.ts @@ -164,6 +164,8 @@ describe("ProviderRuntimeIngestion", () => { providerName: "codex", providerSessionId: asSessionId("sess-1"), providerThreadId: ProviderThreadId.makeUnsafe("provider-thread-1"), + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: null, updatedAt: createdAt, lastError: null, @@ -332,6 +334,8 @@ describe("ProviderRuntimeIngestion", () => { attachments: [], }, assistantDeliveryMode: "streaming", + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: now, }), ); diff --git a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts index 889a8903e0a612ed439de2bebb5ea5da906c0606..8c763381cdd9843d3949e76d9f89eb29f507edb8 100644 --- a/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts +++ b/apps/server/src/orchestration/Layers/ProviderRuntimeIngestion.ts @@ -3,6 +3,8 @@ import { CommandId, MessageId, type OrchestrationEvent, + type ProviderApprovalPolicy, + type ProviderSandboxMode, ProviderThreadId, type ThreadId, TurnId, @@ -24,6 +26,8 @@ const providerCommandId = (event: ProviderRuntimeEvent, tag: string): CommandId CommandId.makeUnsafe(`provider:${event.eventId}:${tag}:${crypto.randomUUID()}`); const DEFAULT_ASSISTANT_DELIVERY_MODE: AssistantDeliveryMode = "buffered"; +const DEFAULT_APPROVAL_POLICY: ProviderApprovalPolicy = "never"; +const DEFAULT_SANDBOX_MODE: ProviderSandboxMode = "workspace-write"; const TURN_MESSAGE_IDS_BY_TURN_CACHE_CAPACITY = 10_000; const TURN_MESSAGE_IDS_BY_TURN_TTL = Duration.minutes(120); const BUFFERED_MESSAGE_TEXT_BY_MESSAGE_ID_CACHE_CAPACITY = 20_000; @@ -371,12 +375,8 @@ const make = Effect.gen(function* () { providerName: event.provider, providerSessionId: event.sessionId, providerThreadId, - ...(thread.session?.approvalPolicy !== undefined - ? { approvalPolicy: thread.session.approvalPolicy } - : {}), - ...(thread.session?.sandboxMode !== undefined - ? { sandboxMode: thread.session.sandboxMode } - : {}), + approvalPolicy: thread.session?.approvalPolicy ?? DEFAULT_APPROVAL_POLICY, + sandboxMode: thread.session?.sandboxMode ?? DEFAULT_SANDBOX_MODE, activeTurnId, lastError, updatedAt: now, @@ -485,12 +485,8 @@ const make = Effect.gen(function* () { providerName: event.provider, providerSessionId: event.sessionId, providerThreadId, - ...(thread.session?.approvalPolicy !== undefined - ? { approvalPolicy: thread.session.approvalPolicy } - : {}), - ...(thread.session?.sandboxMode !== undefined - ? { sandboxMode: thread.session.sandboxMode } - : {}), + approvalPolicy: thread.session?.approvalPolicy ?? DEFAULT_APPROVAL_POLICY, + sandboxMode: thread.session?.sandboxMode ?? DEFAULT_SANDBOX_MODE, activeTurnId: toTurnId(event.turnId) ?? null, lastError: event.message, updatedAt: now, diff --git a/apps/server/src/orchestration/commandInvariants.test.ts b/apps/server/src/orchestration/commandInvariants.test.ts index d02f80e300745f20db13c21d455814d264688e9a..9ad953d5b7fb341a831c67e709e6967e585ea475 100644 --- a/apps/server/src/orchestration/commandInvariants.test.ts +++ b/apps/server/src/orchestration/commandInvariants.test.ts @@ -90,6 +90,8 @@ const messageSendCommand: OrchestrationCommand = { text: "hello", attachments: [], }, + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: now, }; diff --git a/apps/server/src/orchestration/decider.ts b/apps/server/src/orchestration/decider.ts index 9599b4c05f80bec5dc74b5bf3f4dbccd8adfea92..45268a1132096afcdbd0e8a11b143044eac861f8 100644 --- a/apps/server/src/orchestration/decider.ts +++ b/apps/server/src/orchestration/decider.ts @@ -254,10 +254,8 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand" ...(command.model !== undefined ? { model: command.model } : {}), ...(command.effort !== undefined ? { effort: command.effort } : {}), assistantDeliveryMode: command.assistantDeliveryMode ?? DEFAULT_ASSISTANT_DELIVERY_MODE, - ...(command.approvalPolicy !== undefined - ? { approvalPolicy: command.approvalPolicy } - : {}), - ...(command.sandboxMode !== undefined ? { sandboxMode: command.sandboxMode } : {}), + approvalPolicy: command.approvalPolicy, + sandboxMode: command.sandboxMode, createdAt: command.createdAt, }, }; diff --git a/apps/server/src/orchestration/projector.test.ts b/apps/server/src/orchestration/projector.test.ts index ee4f7e872f9847d27db1f0a2af290671a5cec3df..56c0c0bed92a2e6a3fe3c1d5f21c2b9c0c85684b 100644 --- a/apps/server/src/orchestration/projector.test.ts +++ b/apps/server/src/orchestration/projector.test.ts @@ -135,6 +135,8 @@ describe("orchestration projector", () => { payload: { threadId: "thread-1", messageId: "message-1", + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt: "2026-01-01T00:00:00.000Z", }, }), @@ -193,6 +195,8 @@ describe("orchestration projector", () => { providerName: "codex", providerSessionId: "session-1", providerThreadId: "provider-thread-1", + approvalPolicy: "on-request", + sandboxMode: "workspace-write", activeTurnId: "turn-1", lastError: null, updatedAt: startedAt, diff --git a/apps/server/src/persistence/Layers/ProjectionThreadSessions.ts b/apps/server/src/persistence/Layers/ProjectionThreadSessions.ts index 2a3b0806ee33a4f933d62ea4047789bffbf8b4cc..0793ef388dba91098f37abec3ab2b25967bf2ce4 100644 --- a/apps/server/src/persistence/Layers/ProjectionThreadSessions.ts +++ b/apps/server/src/persistence/Layers/ProjectionThreadSessions.ts @@ -25,6 +25,8 @@ const makeProjectionThreadSessionRepository = Effect.gen(function* () { provider_name, provider_session_id, provider_thread_id, + approval_policy, + sandbox_mode, active_turn_id, last_error, updated_at @@ -35,6 +37,8 @@ const makeProjectionThreadSessionRepository = Effect.gen(function* () { ${row.providerName}, ${row.providerSessionId}, ${row.providerThreadId}, + ${row.approvalPolicy}, + ${row.sandboxMode}, ${row.activeTurnId}, ${row.lastError}, ${row.updatedAt} @@ -45,6 +49,8 @@ const makeProjectionThreadSessionRepository = Effect.gen(function* () { provider_name = excluded.provider_name, provider_session_id = excluded.provider_session_id, provider_thread_id = excluded.provider_thread_id, + approval_policy = excluded.approval_policy, + sandbox_mode = excluded.sandbox_mode, active_turn_id = excluded.active_turn_id, last_error = excluded.last_error, updated_at = excluded.updated_at @@ -62,6 +68,8 @@ const makeProjectionThreadSessionRepository = Effect.gen(function* () { provider_name AS "providerName", provider_session_id AS "providerSessionId", provider_thread_id AS "providerThreadId", + approval_policy AS "approvalPolicy", + sandbox_mode AS "sandboxMode", active_turn_id AS "activeTurnId", last_error AS "lastError", updated_at AS "updatedAt" diff --git a/apps/server/src/persistence/Migrations/005_Projections.ts b/apps/server/src/persistence/Migrations/005_Projections.ts index c950da76a18e2fd25609109764831ded8c84fbfe..ae5e7af07d2c1be71115897441470ec9b40f0efd 100644 --- a/apps/server/src/persistence/Migrations/005_Projections.ts +++ b/apps/server/src/persistence/Migrations/005_Projections.ts @@ -65,6 +65,8 @@ export default Effect.gen(function* () { provider_name TEXT, provider_session_id TEXT, provider_thread_id TEXT, + approval_policy TEXT NOT NULL, + sandbox_mode TEXT NOT NULL, active_turn_id TEXT, last_error TEXT, updated_at TEXT NOT NULL diff --git a/apps/server/src/persistence/Services/ProjectionThreadSessions.ts b/apps/server/src/persistence/Services/ProjectionThreadSessions.ts index a769cae896935503ecb6512666ca56c210b3ea0c..2789e2481e3b772d5b86eac5db1505495fd481b8 100644 --- a/apps/server/src/persistence/Services/ProjectionThreadSessions.ts +++ b/apps/server/src/persistence/Services/ProjectionThreadSessions.ts @@ -9,6 +9,8 @@ import { IsoDateTime, OrchestrationSessionStatus, + ProviderApprovalPolicy, + ProviderSandboxMode, ProviderSessionId, ProviderThreadId, ThreadId, @@ -25,6 +27,8 @@ export const ProjectionThreadSession = Schema.Struct({ providerName: Schema.NullOr(Schema.String), providerSessionId: Schema.NullOr(ProviderSessionId), providerThreadId: Schema.NullOr(ProviderThreadId), + approvalPolicy: ProviderApprovalPolicy, + sandboxMode: ProviderSandboxMode, activeTurnId: Schema.NullOr(TurnId), lastError: Schema.NullOr(Schema.String), updatedAt: IsoDateTime, diff --git a/apps/server/src/wsServer.test.ts b/apps/server/src/wsServer.test.ts index d6ba9229b58947cfb23699728fb14e6934b92f2c..494c455165bfe5651ed17ba9985d6edc32f4ce39 100644 --- a/apps/server/src/wsServer.test.ts +++ b/apps/server/src/wsServer.test.ts @@ -1055,6 +1055,8 @@ describe("WebSocket Server", () => { attachments: [], }, assistantDeliveryMode: "streaming", + approvalPolicy: "on-request", + sandboxMode: "workspace-write", createdAt, }); expect(startTurnResponse.error).toBeUndefined(); diff --git a/packages/contracts/src/orchestration.ts b/packages/contracts/src/orchestration.ts index cdf32a02f15741ea4c54f38dcf7e185a169e9406..619ea31bb4dbbb957eda22f740363bd4317192e2 100644 --- a/packages/contracts/src/orchestration.ts +++ b/packages/contracts/src/orchestration.ts @@ -142,8 +142,8 @@ export const OrchestrationSession = Schema.Struct({ providerName: Schema.NullOr(TrimmedNonEmptyString), providerSessionId: Schema.NullOr(ProviderSessionId), providerThreadId: Schema.NullOr(ProviderThreadId), - approvalPolicy: Schema.optional(ProviderApprovalPolicy), - sandboxMode: Schema.optional(ProviderSandboxMode), + approvalPolicy: ProviderApprovalPolicy, + sandboxMode: ProviderSandboxMode, activeTurnId: Schema.NullOr(TurnId), lastError: Schema.NullOr(TrimmedNonEmptyString), updatedAt: IsoDateTime, @@ -284,8 +284,8 @@ export const ThreadTurnStartCommand = Schema.Struct({ model: Schema.optional(TrimmedNonEmptyString), effort: Schema.optional(TrimmedNonEmptyString), assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), - approvalPolicy: Schema.optional(ProviderApprovalPolicy), - sandboxMode: Schema.optional(ProviderSandboxMode), + approvalPolicy: ProviderApprovalPolicy, + sandboxMode: ProviderSandboxMode, createdAt: IsoDateTime, }); @@ -500,8 +500,8 @@ export const ThreadTurnStartRequestedPayload = Schema.Struct({ model: Schema.optional(TrimmedNonEmptyString), effort: Schema.optional(TrimmedNonEmptyString), assistantDeliveryMode: Schema.optional(AssistantDeliveryMode), - approvalPolicy: Schema.optional(ProviderApprovalPolicy), - sandboxMode: Schema.optional(ProviderSandboxMode), + approvalPolicy: ProviderApprovalPolicy, + sandboxMode: ProviderSandboxMode, createdAt: IsoDateTime, });