Repository navigation
Propagate runtime approval policy and sandbox mode to thread turn startup #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
5d64138
6f2181d
454ddee
6158b2a
422160a
4d791fe
4b80ad2
caafd21
21c62c5
7d0226c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3,9 +3,13 @@ import { | |
| CommandId, | ||
| EventId, | ||
| type OrchestrationEvent, | ||
| type ProviderApprovalPolicy, | ||
| type ProviderKind, | ||
| type ProviderSandboxMode, | ||
| type OrchestrationSession, | ||
| type ThreadId, | ||
| type ProviderSession, | ||
| type ProviderThreadId, | ||
| type TurnId, | ||
| } from "@t3tools/contracts"; | ||
| import { Cache, Cause, Duration, Effect, Layer, Option, Queue, Stream } from "effect"; | ||
|
|
@@ -128,18 +132,19 @@ const make = Effect.gen(function* () { | |
| const ensureSessionForThread = Effect.fnUntraced(function* ( | ||
| threadId: ThreadId, | ||
| createdAt: string, | ||
| options?: { | ||
| readonly approvalPolicy?: ProviderApprovalPolicy; | ||
| readonly sandboxMode?: ProviderSandboxMode; | ||
| }, | ||
| ) { | ||
| const readModel = yield* orchestrationEngine.getReadModel(); | ||
| const thread = readModel.threads.find((entry) => entry.id === threadId); | ||
| if (!thread) { | ||
| return yield* Effect.die(new Error(`Thread '${threadId}' was not found in read model.`)); | ||
| } | ||
|
|
||
| const existingSessionId = thread.session?.providerSessionId; | ||
| if (existingSessionId) { | ||
| return existingSessionId; | ||
| } | ||
|
|
||
| const desiredApprovalPolicy = options?.approvalPolicy ?? thread.session?.approvalPolicy; | ||
| const desiredSandboxMode = options?.sandboxMode ?? thread.session?.sandboxMode; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fallback policy/mode continuity breaks after explicit session stops. Line 146 and Line 147 fall back to values on 馃挕 Suggested fix yield* setThreadSession({
threadId: thread.id,
session: {
threadId: thread.id,
status: "stopped",
providerName: thread.session?.providerName ?? null,
providerSessionId: null,
providerThreadId: null,
+ ...(thread.session?.approvalPolicy !== undefined
+ ? { approvalPolicy: thread.session.approvalPolicy }
+ : {}),
+ ...(thread.session?.sandboxMode !== undefined
+ ? { sandboxMode: thread.session.sandboxMode }
+ : {}),
activeTurnId: null,
lastError: thread.session?.lastError ?? null,
updatedAt: now,
},
createdAt: now,
});馃 Prompt for AI Agents |
||
| const preferredProvider: ProviderKind | undefined = | ||
| thread.session?.providerName === "codex" || thread.session?.providerName === "claudeCode" | ||
| ? thread.session.providerName | ||
|
|
@@ -149,28 +154,54 @@ const make = Effect.gen(function* () { | |
| projects: readModel.projects, | ||
| }); | ||
|
|
||
| const startedSession = yield* providerService.startSession(threadId, { | ||
| ...(preferredProvider ? { provider: preferredProvider } : {}), | ||
| ...(effectiveCwd ? { cwd: effectiveCwd } : {}), | ||
| ...(thread.model ? { model: thread.model } : {}), | ||
| }); | ||
| const startProviderSession = (resumeThreadId?: ProviderThreadId | null) => | ||
| providerService.startSession(threadId, { | ||
| ...(preferredProvider ? { provider: preferredProvider } : {}), | ||
| ...(effectiveCwd ? { cwd: effectiveCwd } : {}), | ||
| ...(thread.model ? { model: thread.model } : {}), | ||
| ...(resumeThreadId ? { resumeThreadId } : {}), | ||
| ...(desiredApprovalPolicy !== undefined ? { approvalPolicy: desiredApprovalPolicy } : {}), | ||
| ...(desiredSandboxMode !== undefined ? { sandboxMode: desiredSandboxMode } : {}), | ||
| }); | ||
|
|
||
| yield* setThreadSession({ | ||
| threadId, | ||
| session: { | ||
| const bindSessionToThread = (session: ProviderSession) => | ||
| setThreadSession({ | ||
| threadId, | ||
| status: mapProviderSessionStatusToOrchestrationStatus(startedSession.status), | ||
| providerName: startedSession.provider, | ||
| providerSessionId: startedSession.sessionId, | ||
| providerThreadId: startedSession.threadId ?? null, | ||
| // Provider turn ids are not orchestration turn ids. | ||
| activeTurnId: null, | ||
| lastError: startedSession.lastError ?? null, | ||
| updatedAt: startedSession.updatedAt, | ||
| }, | ||
| createdAt, | ||
| }); | ||
| session: { | ||
| threadId, | ||
| status: mapProviderSessionStatusToOrchestrationStatus(session.status), | ||
| providerName: session.provider, | ||
| providerSessionId: session.sessionId, | ||
| providerThreadId: session.threadId ?? null, | ||
| ...(desiredApprovalPolicy !== undefined ? { approvalPolicy: desiredApprovalPolicy } : {}), | ||
| ...(desiredSandboxMode !== undefined ? { sandboxMode: desiredSandboxMode } : {}), | ||
| // Provider turn ids are not orchestration turn ids. | ||
| activeTurnId: null, | ||
| lastError: session.lastError ?? null, | ||
| updatedAt: session.updatedAt, | ||
| }, | ||
| createdAt, | ||
| }); | ||
|
|
||
| const existingSessionId = thread.session?.providerSessionId; | ||
| if (existingSessionId) { | ||
| const approvalPolicyChanged = | ||
| options?.approvalPolicy !== undefined && options.approvalPolicy !== thread.session?.approvalPolicy; | ||
| const sandboxModeChanged = | ||
| options?.sandboxMode !== undefined && options.sandboxMode !== thread.session?.sandboxMode; | ||
|
|
||
| if (!approvalPolicyChanged && !sandboxModeChanged) { | ||
| return existingSessionId; | ||
| } | ||
|
|
||
| yield* providerService.stopSession({ sessionId: existingSessionId }); | ||
|
macroscopeapp[bot] marked this conversation as resolved.
Outdated
|
||
| const restartedSession = yield* startProviderSession(thread.session?.providerThreadId ?? null); | ||
| yield* bindSessionToThread(restartedSession); | ||
| return restartedSession.sessionId; | ||
|
cursor[bot] marked this conversation as resolved.
|
||
| } | ||
|
juliusmarminge marked this conversation as resolved.
Outdated
|
||
|
|
||
| const startedSession = yield* startProviderSession(); | ||
| yield* bindSessionToThread(startedSession); | ||
| return startedSession.sessionId; | ||
| }); | ||
|
|
||
|
|
@@ -180,13 +211,18 @@ const make = Effect.gen(function* () { | |
| readonly attachments?: ReadonlyArray<ChatAttachment>; | ||
| readonly model?: string; | ||
| readonly effort?: string; | ||
| readonly approvalPolicy?: ProviderApprovalPolicy; | ||
| readonly sandboxMode?: ProviderSandboxMode; | ||
| readonly createdAt: string; | ||
| }) { | ||
| const thread = yield* resolveThread(input.threadId); | ||
| if (!thread) { | ||
| return; | ||
| } | ||
| const sessionId = yield* ensureSessionForThread(input.threadId, input.createdAt); | ||
| const sessionId = yield* ensureSessionForThread(input.threadId, input.createdAt, { | ||
| ...(input.approvalPolicy !== undefined ? { approvalPolicy: input.approvalPolicy } : {}), | ||
| ...(input.sandboxMode !== undefined ? { sandboxMode: input.sandboxMode } : {}), | ||
| }); | ||
| const normalizedInput = toNonEmptyProviderInput(input.messageText); | ||
| const normalizedAttachments = input.attachments ?? []; | ||
|
|
||
|
|
@@ -231,6 +267,10 @@ 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 } : {}), | ||
| createdAt: event.payload.createdAt, | ||
| }); | ||
| }); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.