| author | |
| committer | |
| log | b66dd402e86899c3fb4341d46c32d0d69df1eefc |
| tree | 932594fff9ca5cd68ebd5cc0d7bad7ea5fb58677 |
| parent | 2c1915b3193f16e2493709b480e6622645d0ca4e |
| signature | Signed by PGP key B5690EEEBB952194 |
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>110 files changed, 2281 insertions(+), 2257 deletions(-)
apps/server/scripts/record-claude-agent-sdk-replay-fixture.ts+3-6| ... | @@ -10,10 +10,7 @@ import { | ... | @@ -10,10 +10,7 @@ import { |
| 10 | CLAUDE_AGENT_SDK_REPLAY_PROTOCOL, | 10 | CLAUDE_AGENT_SDK_REPLAY_PROTOCOL, |
| 11 | } from "../src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts"; | 11 | } from "../src/orchestration-v2/Adapters/ClaudeAdapterV2.testkit.ts"; |
| 12 | import { claudeRuntimeQueryPolicyForRuntimePolicy } from "../src/orchestration-v2/Adapters/ClaudeAdapterV2.ts"; | 12 | import { claudeRuntimeQueryPolicyForRuntimePolicy } from "../src/orchestration-v2/Adapters/ClaudeAdapterV2.ts"; |
| 13 | import { | 13 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 14 | ProviderAdapterV2RuntimePolicy, | ||
| 15 | type ProviderAdapterV2RuntimePolicy as ProviderAdapterV2RuntimePolicyType, | ||
| 16 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 17 | import type { RuntimePolicyV2Override } from "../src/orchestration-v2/RuntimePolicy.ts"; | 14 | import type { RuntimePolicyV2Override } from "../src/orchestration-v2/RuntimePolicy.ts"; |
| 18 | import { makeCheckpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 15 | import { makeCheckpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 19 | import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts"; | 16 | import { CLAUDE_MODEL_SELECTION } from "../src/orchestration-v2/testkit/fixtures/shared.ts"; |
| ... | @@ -440,8 +437,8 @@ validateClaudeReplayRecordingSelection({ | ... | @@ -440,8 +437,8 @@ validateClaudeReplayRecordingSelection({ |
| 440 | function runtimePolicyForRecording(input: { | 437 | function runtimePolicyForRecording(input: { |
| 441 | readonly cwd: string; | 438 | readonly cwd: string; |
| 442 | readonly override?: RuntimePolicyV2Override; | 439 | readonly override?: RuntimePolicyV2Override; |
| 443 | }): ProviderAdapterV2RuntimePolicyType { | 440 | }): ProviderAdapter.ProviderAdapterV2RuntimePolicy { |
| 444 | return ProviderAdapterV2RuntimePolicy.make({ | 441 | return ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 445 | runtimeMode: "full-access", | 442 | runtimeMode: "full-access", |
| 446 | interactionMode: "default", | 443 | interactionMode: "default", |
| 447 | cwd: input.override?.cwd ?? input.cwd, | 444 | cwd: input.override?.cwd ?? input.cwd, |
apps/server/scripts/record-grok-acp-replay-fixture.ts+3-3| ... | @@ -33,8 +33,8 @@ import { | ... | @@ -33,8 +33,8 @@ import { |
| 33 | } from "@t3tools/provider-grok/testing"; | 33 | } from "@t3tools/provider-grok/testing"; |
| 34 | import { ACP_PROTOCOL } from "@t3tools/provider-acp/server/adapter"; | 34 | import { ACP_PROTOCOL } from "@t3tools/provider-acp/server/adapter"; |
| 35 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 35 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 36 | import type { ProviderAdapterV2SessionRuntime } from "@t3tools/provider-core/server/ProviderAdapter"; | 36 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 37 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 37 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 38 | import * as ProviderAdapterRegistry from "../src/orchestration-v2/ProviderAdapterRegistry.ts"; | 38 | import * as ProviderAdapterRegistry from "../src/orchestration-v2/ProviderAdapterRegistry.ts"; |
| 39 | import { provideDeterministicTestRuntime } from "../src/orchestration-v2/testkit/DeterministicRuntime.ts"; | 39 | import { provideDeterministicTestRuntime } from "../src/orchestration-v2/testkit/DeterministicRuntime.ts"; |
| 40 | import { ORCHESTRATOR_REPLAY_FIXTURES } from "../src/orchestration-v2/testkit/fixtures/index.ts"; | 40 | import { ORCHESTRATOR_REPLAY_FIXTURES } from "../src/orchestration-v2/testkit/fixtures/index.ts"; |
| ... | @@ -474,7 +474,7 @@ const recordScenario = Effect.fn("recordGrokScenario")(function* (fixtureName: s | ... | @@ -474,7 +474,7 @@ const recordScenario = Effect.fn("recordGrokScenario")(function* (fixtureName: s |
| 474 | ...adapter, | 474 | ...adapter, |
| 475 | openSession: (input) => | 475 | openSession: (input) => |
| 476 | adapter.openSession(input).pipe( | 476 | adapter.openSession(input).pipe( |
| 477 | Effect.map((session): ProviderAdapterV2SessionRuntime => ({ | 477 | Effect.map((session): ProviderAdapter.ProviderAdapterV2SessionRuntime => ({ |
| 478 | ...session, | 478 | ...session, |
| 479 | startTurn: (turnInput) => onWallClock(session.startTurn(turnInput)), | 479 | startTurn: (turnInput) => onWallClock(session.startTurn(turnInput)), |
| 480 | steerTurn: (turnInput) => onWallClock(session.steerTurn(turnInput)), | 480 | steerTurn: (turnInput) => onWallClock(session.steerTurn(turnInput)), |
apps/server/src/mcp/McpToolAccess.race.test.ts+2-2| ... | @@ -19,13 +19,13 @@ import { DispatchModeLimit } from "../orchestration-v2/DispatchModeLimit.ts"; | ... | @@ -19,13 +19,13 @@ import { DispatchModeLimit } from "../orchestration-v2/DispatchModeLimit.ts"; |
| 19 | import { CodexProviderCapabilitiesV2 } from "../orchestration-v2/Adapters/CodexAdapterV2.ts"; | 19 | import { CodexProviderCapabilitiesV2 } from "../orchestration-v2/Adapters/CodexAdapterV2.ts"; |
| 20 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; | 20 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; |
| 21 | import * as ProjectionStore from "../orchestration-v2/ProjectionStore.ts"; | 21 | import * as ProjectionStore from "../orchestration-v2/ProjectionStore.ts"; |
| 22 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 23 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; | 22 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; |
| 24 | import * as ThreadManagement from "../orchestration-v2/ThreadManagementService.ts"; | 23 | import * as ThreadManagement from "../orchestration-v2/ThreadManagementService.ts"; |
| 25 | import * as ProviderReplayHarness from "../orchestration-v2/testkit/ProviderReplayHarness.ts"; | 24 | import * as ProviderReplayHarness from "../orchestration-v2/testkit/ProviderReplayHarness.ts"; |
| 26 | import * as McpHttpServer from "./McpHttpServer.ts"; | 25 | import * as McpHttpServer from "./McpHttpServer.ts"; |
| 27 | import * as McpInvocationContext from "./McpInvocationContext.ts"; | 26 | import * as McpInvocationContext from "./McpInvocationContext.ts"; |
| 28 | import * as McpToolAccess from "./McpToolAccess.ts"; | 27 | import * as McpToolAccess from "./McpToolAccess.ts"; |
| 28 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 29 | 29 | ||
| 30 | // A Supervised outside agent renames a thread through a `writesThreads` tool. | 30 | // A Supervised outside agent renames a thread through a `writesThreads` tool. |
| 31 | // The thread's user raises it to full access after the tool's check but | 31 | // The thread's user raises it to full access after the tool's check but |
| ... | @@ -38,7 +38,7 @@ const adapter = { | ... | @@ -38,7 +38,7 @@ const adapter = { |
| 38 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 38 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 39 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 39 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 40 | openSession: () => Effect.die("No provider process needed for metadata commands"), | 40 | openSession: () => Effect.die("No provider process needed for metadata commands"), |
| 41 | } as ProviderAdapterV2Shape; | 41 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 42 | const layerDatabase = SqlitePersistence.layerMemory; | 42 | const layerDatabase = SqlitePersistence.layerMemory; |
| 43 | const layerOrchestrator = Layer.mergeAll( | 43 | const layerOrchestrator = Layer.mergeAll( |
| 44 | layerDatabase, | 44 | layerDatabase, |
apps/server/src/mcp/OrchestratorMcpService.test.ts+4-2| ... | @@ -28,7 +28,6 @@ import { | ... | @@ -28,7 +28,6 @@ import { |
| 28 | OrchestratorProjectionError, | 28 | OrchestratorProjectionError, |
| 29 | OrchestratorThreadAboveModeLimitError, | 29 | OrchestratorThreadAboveModeLimitError, |
| 30 | } from "../orchestration-v2/Orchestrator.ts"; | 30 | } from "../orchestration-v2/Orchestrator.ts"; |
| 31 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 32 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; | 31 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; |
| 33 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; | 32 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; |
| 34 | import * as ProviderRegistry from "../provider/ProviderRegistry.ts"; | 33 | import * as ProviderRegistry from "../provider/ProviderRegistry.ts"; |
| ... | @@ -39,6 +38,7 @@ import * as SecretRequests from "../secrets/SecretRequests.ts"; | ... | @@ -39,6 +38,7 @@ import * as SecretRequests from "../secrets/SecretRequests.ts"; |
| 39 | import type { McpInvocationScope } from "./McpInvocationContext.ts"; | 38 | import type { McpInvocationScope } from "./McpInvocationContext.ts"; |
| 40 | import { idleThreadProjection, liveThreadShell } from "./McpToolAccess.testkit.ts"; | 39 | import { idleThreadProjection, liveThreadShell } from "./McpToolAccess.testkit.ts"; |
| 41 | import * as OrchestratorMcpService from "./OrchestratorMcpService.ts"; | 40 | import * as OrchestratorMcpService from "./OrchestratorMcpService.ts"; |
| 41 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 42 | 42 | ||
| 43 | describe("OrchestratorMcpService", () => { | 43 | describe("OrchestratorMcpService", () => { |
| 44 | it.effect("retries terminal acknowledgement with a fresh command id", () => | 44 | it.effect("retries terminal acknowledgement with a fresh command id", () => |
| ... | @@ -810,7 +810,9 @@ describe("OrchestratorMcpService provider resolution", () => { | ... | @@ -810,7 +810,9 @@ describe("OrchestratorMcpService provider resolution", () => { |
| 810 | list: () => Effect.succeed(instanceIds), | 810 | list: () => Effect.succeed(instanceIds), |
| 811 | get: (instanceId) => | 811 | get: (instanceId) => |
| 812 | instanceIds.includes(instanceId) | 812 | instanceIds.includes(instanceId) |
| 813 | ? Effect.succeed({ instanceId } as unknown as ProviderAdapterV2Shape) | 813 | ? Effect.succeed({ |
| 814 | instanceId, | ||
| 815 | } as unknown as ProviderAdapter.ProviderAdapterV2["Service"]) | ||
| 814 | : Effect.fail( | 816 | : Effect.fail( |
| 815 | new ProviderAdapterRegistry.ProviderAdapterRegistryLookupError({ instanceId }), | 817 | new ProviderAdapterRegistry.ProviderAdapterRegistryLookupError({ instanceId }), |
| 816 | ), | 818 | ), |
apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts+12-15| ... | @@ -57,14 +57,8 @@ import { threadShellFromProjection } from "../orchestration-v2/ProjectionStore.t | ... | @@ -57,14 +57,8 @@ import { threadShellFromProjection } from "../orchestration-v2/ProjectionStore.t |
| 57 | import * as EventSink from "../orchestration-v2/EventSink.ts"; | 57 | import * as EventSink from "../orchestration-v2/EventSink.ts"; |
| 58 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; | 58 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; |
| 59 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; | 59 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; |
| 60 | import { | ||
| 61 | type ProviderAdapterV2Event, | ||
| 62 | ProviderAdapterProtocolError, | ||
| 63 | type ProviderAdapterV2Shape, | ||
| 64 | type ProviderAdapterV2TurnInput, | ||
| 65 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 66 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; | 60 | import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; |
| 67 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 61 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 68 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 62 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 69 | import * as ProviderReplayHarness from "../orchestration-v2/testkit/ProviderReplayHarness.ts"; | 63 | import * as ProviderReplayHarness from "../orchestration-v2/testkit/ProviderReplayHarness.ts"; |
| 70 | import { | 64 | import { |
| ... | @@ -79,6 +73,7 @@ import * as ServerSecretStore from "../auth/ServerSecretStore.ts"; | ... | @@ -79,6 +73,7 @@ import * as ServerSecretStore from "../auth/ServerSecretStore.ts"; |
| 79 | import * as McpHttpServer from "./McpHttpServer.ts"; | 73 | import * as McpHttpServer from "./McpHttpServer.ts"; |
| 80 | import * as McpInvocationContext from "./McpInvocationContext.ts"; | 74 | import * as McpInvocationContext from "./McpInvocationContext.ts"; |
| 81 | import { delegatedTaskRun, hasPendingChildRuns } from "./OrchestratorMcpService.ts"; | 75 | import { delegatedTaskRun, hasPendingChildRuns } from "./OrchestratorMcpService.ts"; |
| 76 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 82 | 77 | ||
| 83 | // Effect returns a declared tool failure as `isError` with its encoded payload | 78 | // Effect returns a declared tool failure as `isError` with its encoded payload |
| 84 | // as JSON text, never as `structuredContent`. | 79 | // as JSON text, never as `structuredContent`. |
| ... | @@ -146,7 +141,7 @@ interface CapturedTurn { | ... | @@ -146,7 +141,7 @@ interface CapturedTurn { |
| 146 | } | 141 | } |
| 147 | 142 | ||
| 148 | function unsupported(driver: ProviderDriverKind, detail: string) { | 143 | function unsupported(driver: ProviderDriverKind, detail: string) { |
| 149 | return Effect.fail(new ProviderAdapterProtocolError({ driver, detail })); | 144 | return Effect.fail(new ProviderAdapter.ProviderAdapterProtocolError({ driver, detail })); |
| 150 | } | 145 | } |
| 151 | 146 | ||
| 152 | function makeProviderSnapshot(input: { | 147 | function makeProviderSnapshot(input: { |
| ... | @@ -185,10 +180,12 @@ function makeDeterministicAdapter(input: { | ... | @@ -185,10 +180,12 @@ function makeDeterministicAdapter(input: { |
| 185 | readonly driver: ProviderDriverKind; | 180 | readonly driver: ProviderDriverKind; |
| 186 | readonly capabilities: OrchestrationV2ProviderCapabilities; | 181 | readonly capabilities: OrchestrationV2ProviderCapabilities; |
| 187 | readonly capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>; | 182 | readonly capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>; |
| 188 | readonly shouldComplete: (turn: ProviderAdapterV2TurnInput) => boolean; | 183 | readonly shouldComplete: (turn: ProviderAdapter.ProviderAdapterV2TurnInput) => boolean; |
| 189 | readonly terminalGate?: (turn: ProviderAdapterV2TurnInput) => Deferred.Deferred<void> | undefined; | 184 | readonly terminalGate?: ( |
| 190 | readonly response: (turn: ProviderAdapterV2TurnInput) => string; | 185 | turn: ProviderAdapter.ProviderAdapterV2TurnInput, |
| 191 | }): ProviderAdapterV2Shape { | 186 | ) => Deferred.Deferred<void> | undefined; |
| 187 | readonly response: (turn: ProviderAdapter.ProviderAdapterV2TurnInput) => string; | ||
| 188 | }): ProviderAdapter.ProviderAdapterV2["Service"] { | ||
| 192 | return { | 189 | return { |
| 193 | instanceId: input.instanceId, | 190 | instanceId: input.instanceId, |
| 194 | driver: input.driver, | 191 | driver: input.driver, |
| ... | @@ -196,7 +193,7 @@ function makeDeterministicAdapter(input: { | ... | @@ -196,7 +193,7 @@ function makeDeterministicAdapter(input: { |
| 196 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 193 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 197 | openSession: (sessionInput) => | 194 | openSession: (sessionInput) => |
| 198 | Effect.gen(function* () { | 195 | Effect.gen(function* () { |
| 199 | const events = yield* PubSub.unbounded<ProviderAdapterV2Event>(); | 196 | const events = yield* PubSub.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 200 | const now = yield* DateTime.now; | 197 | const now = yield* DateTime.now; |
| 201 | const providerSession: OrchestrationV2ProviderSession = { | 198 | const providerSession: OrchestrationV2ProviderSession = { |
| 202 | id: sessionInput.providerSessionId, | 199 | id: sessionInput.providerSessionId, |
| ... | @@ -211,12 +208,12 @@ function makeDeterministicAdapter(input: { | ... | @@ -211,12 +208,12 @@ function makeDeterministicAdapter(input: { |
| 211 | lastError: null, | 208 | lastError: null, |
| 212 | }; | 209 | }; |
| 213 | 210 | ||
| 214 | const publish = (providerEvents: ReadonlyArray<ProviderAdapterV2Event>) => | 211 | const publish = (providerEvents: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 215 | Effect.forEach(providerEvents, (event) => PubSub.publish(events, event), { | 212 | Effect.forEach(providerEvents, (event) => PubSub.publish(events, event), { |
| 216 | discard: true, | 213 | discard: true, |
| 217 | }); | 214 | }); |
| 218 | const runOrdinals = new Map<ProviderTurnId, number>(); | 215 | const runOrdinals = new Map<ProviderTurnId, number>(); |
| 219 | const turnInputs = new Map<ProviderTurnId, ProviderAdapterV2TurnInput>(); | 216 | const turnInputs = new Map<ProviderTurnId, ProviderAdapter.ProviderAdapterV2TurnInput>(); |
| 220 | 217 | ||
| 221 | return { | 218 | return { |
| 222 | instanceId: input.instanceId, | 219 | instanceId: input.instanceId, |
apps/server/src/mcpApps/McpAppRequests.test.ts+6-7| ... | @@ -14,10 +14,7 @@ import * as Layer from "effect/Layer"; | ... | @@ -14,10 +14,7 @@ import * as Layer from "effect/Layer"; |
| 14 | import * as Option from "effect/Option"; | 14 | import * as Option from "effect/Option"; |
| 15 | 15 | ||
| 16 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; | 16 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; |
| 17 | import type { | 17 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 18 | ProviderAdapterV2McpApps, | ||
| 19 | ProviderAdapterV2SessionRuntime, | ||
| 20 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 21 | import * as ProviderSessionManager from "../orchestration-v2/ProviderSessionManager.ts"; | 18 | import * as ProviderSessionManager from "../orchestration-v2/ProviderSessionManager.ts"; |
| 22 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; | 19 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; |
| 23 | import * as McpAppModelContext from "./McpAppModelContext.ts"; | 20 | import * as McpAppModelContext from "./McpAppModelContext.ts"; |
| ... | @@ -71,7 +68,7 @@ const storedContext = new Map<string, string>(); | ... | @@ -71,7 +68,7 @@ const storedContext = new Map<string, string>(); |
| 71 | 68 | ||
| 72 | function makeLayer(input: { | 69 | function makeLayer(input: { |
| 73 | readonly item: OrchestrationV2TurnItem | null; | 70 | readonly item: OrchestrationV2TurnItem | null; |
| 74 | readonly mcpApps?: ProviderAdapterV2McpApps; | 71 | readonly mcpApps?: ProviderAdapter.ProviderAdapterV2McpApps; |
| 75 | readonly live?: boolean; | 72 | readonly live?: boolean; |
| 76 | }) { | 73 | }) { |
| 77 | return McpAppRequests.layer.pipe( | 74 | return McpAppRequests.layer.pipe( |
| ... | @@ -121,7 +118,9 @@ function makeLayer(input: { | ... | @@ -121,7 +118,9 @@ function makeLayer(input: { |
| 121 | : Option.some( | 118 | : Option.some( |
| 122 | (input.mcpApps === undefined | 119 | (input.mcpApps === undefined |
| 123 | ? {} | 120 | ? {} |
| 124 | : { mcpApps: input.mcpApps }) as ProviderAdapterV2SessionRuntime, | 121 | : { |
| 122 | mcpApps: input.mcpApps, | ||
| 123 | }) as ProviderAdapter.ProviderAdapterV2SessionRuntime, | ||
| 125 | ), | 124 | ), |
| 126 | ), | 125 | ), |
| 127 | }), | 126 | }), |
| ... | @@ -138,7 +137,7 @@ const reason = <A, R>(effect: Effect.Effect<A, McpAppRequestError, R>) => | ... | @@ -138,7 +137,7 @@ const reason = <A, R>(effect: Effect.Effect<A, McpAppRequestError, R>) => |
| 138 | 137 | ||
| 139 | describe("McpAppRequests", () => { | 138 | describe("McpAppRequests", () => { |
| 140 | const calls: Array<{ server: string; tool: string }> = []; | 139 | const calls: Array<{ server: string; tool: string }> = []; |
| 141 | const mcpApps: ProviderAdapterV2McpApps = { | 140 | const mcpApps: ProviderAdapter.ProviderAdapterV2McpApps = { |
| 142 | listTools: () => | 141 | listTools: () => |
| 143 | Effect.succeed([ | 142 | Effect.succeed([ |
| 144 | { name: "refresh", annotations: { readOnlyHint: true } }, | 143 | { name: "refresh", annotations: { readOnlyHint: true } }, |
apps/server/src/mcpApps/McpAppRequests.ts+4-7| ... | @@ -21,10 +21,7 @@ import * as Predicate from "effect/Predicate"; | ... | @@ -21,10 +21,7 @@ import * as Predicate from "effect/Predicate"; |
| 21 | import * as Schema from "effect/Schema"; | 21 | import * as Schema from "effect/Schema"; |
| 22 | 22 | ||
| 23 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; | 23 | import * as Orchestrator from "../orchestration-v2/Orchestrator.ts"; |
| 24 | import type { | 24 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 25 | ProviderAdapterV2McpApps, | ||
| 26 | ProviderAdapterV2McpTool, | ||
| 27 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 28 | import * as ProviderSessionManager from "../orchestration-v2/ProviderSessionManager.ts"; | 25 | import * as ProviderSessionManager from "../orchestration-v2/ProviderSessionManager.ts"; |
| 29 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; | 26 | import * as ThreadManagementService from "../orchestration-v2/ThreadManagementService.ts"; |
| 30 | import * as McpAppModelContext from "./McpAppModelContext.ts"; | 27 | import * as McpAppModelContext from "./McpAppModelContext.ts"; |
| ... | @@ -57,10 +54,10 @@ export class McpAppRequests extends Context.Service< | ... | @@ -57,10 +54,10 @@ export class McpAppRequests extends Context.Service< |
| 57 | const encodeJson = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown)); | 54 | const encodeJson = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown)); |
| 58 | const utf8 = new TextEncoder(); | 55 | const utf8 = new TextEncoder(); |
| 59 | 56 | ||
| 60 | const readOnlyHint = (tool: ProviderAdapterV2McpTool) => | 57 | const readOnlyHint = (tool: ProviderAdapter.ProviderAdapterV2McpTool) => |
| 61 | Predicate.isObject(tool.annotations) && tool.annotations.readOnlyHint === true; | 58 | Predicate.isObject(tool.annotations) && tool.annotations.readOnlyHint === true; |
| 62 | 59 | ||
| 63 | const toolTitle = (tool: ProviderAdapterV2McpTool) => | 60 | const toolTitle = (tool: ProviderAdapter.ProviderAdapterV2McpTool) => |
| 64 | Predicate.isObject(tool.annotations) && typeof tool.annotations.title === "string" | 61 | Predicate.isObject(tool.annotations) && typeof tool.annotations.title === "string" |
| 65 | ? tool.annotations.title | 62 | ? tool.annotations.title |
| 66 | : undefined; | 63 | : undefined; |
| ... | @@ -112,7 +109,7 @@ const make = Effect.gen(function* () { | ... | @@ -112,7 +109,7 @@ const make = Effect.gen(function* () { |
| 112 | .pipe(Effect.mapError((cause) => fail(input.threadId, "request-failed", cause))), | 109 | .pipe(Effect.mapError((cause) => fail(input.threadId, "request-failed", cause))), |
| 113 | ); | 110 | ); |
| 114 | if (runtime === undefined) return yield* fail(input.threadId, "session-stopped"); | 111 | if (runtime === undefined) return yield* fail(input.threadId, "session-stopped"); |
| 115 | const mcpApps: ProviderAdapterV2McpApps | undefined = runtime.mcpApps; | 112 | const mcpApps: ProviderAdapter.ProviderAdapterV2McpApps | undefined = runtime.mcpApps; |
| 116 | if (mcpApps === undefined) return yield* fail(input.threadId, "provider-unsupported"); | 113 | if (mcpApps === undefined) return yield* fail(input.threadId, "provider-unsupported"); |
| 117 | return { app, providerThread, mcpApps }; | 114 | return { app, providerThread, mcpApps }; |
| 118 | }); | 115 | }); |
apps/server/src/orchestration-v2/AcpRegistryOrchestratorV2.live.test.ts+1-1| ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; | ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; |
| 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; | 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; |
| 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; | 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; |
| 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; | 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; |
| 32 | import * as ProviderEventLoggers from "../provider/ProviderEventLoggers.ts"; | 32 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 35 | import * as ServerSettings from "../serverSettings.ts"; | 35 | import * as ServerSettings from "../serverSettings.ts"; |
apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts+189-171| ... | @@ -64,13 +64,8 @@ import { | ... | @@ -64,13 +64,8 @@ import { |
| 64 | registerXAiBackgroundTaskTracking, | 64 | registerXAiBackgroundTaskTracking, |
| 65 | } from "@t3tools/provider-grok/testing"; | 65 | } from "@t3tools/provider-grok/testing"; |
| 66 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 66 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 67 | import { | 67 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 68 | ProviderAdapterProtocolError, | 68 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 69 | ProviderAdapterV2RuntimePolicy, | ||
| 70 | type ProviderAdapterV2Event, | ||
| 71 | type ProviderAdapterV2TurnInput, | ||
| 72 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 73 | import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | ||
| 74 | import { | 69 | import { |
| 75 | AcpProviderCapabilitiesV2, | 70 | AcpProviderCapabilitiesV2, |
| 76 | acpProviderItemNativeId, | 71 | acpProviderItemNativeId, |
| ... | @@ -540,7 +535,7 @@ function makeTurnInput(input: { | ... | @@ -540,7 +535,7 @@ function makeTurnInput(input: { |
| 540 | readonly threadId: ThreadId; | 535 | readonly threadId: ThreadId; |
| 541 | readonly providerThread: OrchestrationV2ProviderThread; | 536 | readonly providerThread: OrchestrationV2ProviderThread; |
| 542 | readonly instanceId: ProviderInstanceId; | 537 | readonly instanceId: ProviderInstanceId; |
| 543 | readonly runtimePolicy: ProviderAdapterV2RuntimePolicy; | 538 | readonly runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 544 | readonly now: DateTime.Utc; | 539 | readonly now: DateTime.Utc; |
| 545 | readonly ordinal?: number; | 540 | readonly ordinal?: number; |
| 546 | readonly modelSelection?: ModelSelection; | 541 | readonly modelSelection?: ModelSelection; |
| ... | @@ -548,7 +543,7 @@ function makeTurnInput(input: { | ... | @@ -548,7 +543,7 @@ function makeTurnInput(input: { |
| 548 | readonly messageCreatedBy?: "user" | "agent"; | 543 | readonly messageCreatedBy?: "user" | "agent"; |
| 549 | readonly messageCreationSource?: "web" | "mobile" | "mcp" | "provider" | "server"; | 544 | readonly messageCreationSource?: "web" | "mobile" | "mcp" | "provider" | "server"; |
| 550 | readonly messageText?: string; | 545 | readonly messageText?: string; |
| 551 | }): ProviderAdapterV2TurnInput { | 546 | }): ProviderAdapter.ProviderAdapterV2TurnInput { |
| 552 | const ordinal = input.ordinal ?? 1; | 547 | const ordinal = input.ordinal ?? 1; |
| 553 | const suffix = `${input.threadId}:${ordinal}`; | 548 | const suffix = `${input.threadId}:${ordinal}`; |
| 554 | const modelSelection = | 549 | const modelSelection = |
| ... | @@ -625,7 +620,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -625,7 +620,7 @@ describe("AcpAdapterV2", () => { |
| 625 | }), | 620 | }), |
| 626 | }, | 621 | }, |
| 627 | }); | 622 | }); |
| 628 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 623 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 629 | runtimeMode: "full-access", | 624 | runtimeMode: "full-access", |
| 630 | interactionMode: "default", | 625 | interactionMode: "default", |
| 631 | cwd: process.cwd(), | 626 | cwd: process.cwd(), |
| ... | @@ -742,7 +737,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -742,7 +737,7 @@ describe("AcpAdapterV2", () => { |
| 742 | }, | 737 | }, |
| 743 | selfInvocation, | 738 | selfInvocation, |
| 744 | }); | 739 | }); |
| 745 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 740 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 746 | runtimeMode: "full-access", | 741 | runtimeMode: "full-access", |
| 747 | interactionMode: "default", | 742 | interactionMode: "default", |
| 748 | cwd: process.cwd(), | 743 | cwd: process.cwd(), |
| ... | @@ -799,7 +794,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -799,7 +794,7 @@ describe("AcpAdapterV2", () => { |
| 799 | selfInvocation, | 794 | selfInvocation, |
| 800 | }); | 795 | }); |
| 801 | const policy = (interactionMode: "default" | "plan") => | 796 | const policy = (interactionMode: "default" | "plan") => |
| 802 | ProviderAdapterV2RuntimePolicy.make({ | 797 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 803 | runtimeMode: "full-access", | 798 | runtimeMode: "full-access", |
| 804 | interactionMode, | 799 | interactionMode, |
| 805 | cwd: process.cwd(), | 800 | cwd: process.cwd(), |
| ... | @@ -820,7 +815,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -820,7 +815,7 @@ describe("AcpAdapterV2", () => { |
| 820 | const now = yield* DateTime.now; | 815 | const now = yield* DateTime.now; |
| 821 | const runTurn = Effect.fnUntraced(function* ( | 816 | const runTurn = Effect.fnUntraced(function* ( |
| 822 | ordinal: number, | 817 | ordinal: number, |
| 823 | runtimePolicy: ProviderAdapterV2RuntimePolicy, | 818 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy, |
| 824 | messageText: string, | 819 | messageText: string, |
| 825 | ) { | 820 | ) { |
| 826 | yield* runtime.startTurn( | 821 | yield* runtime.startTurn( |
| ... | @@ -917,7 +912,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -917,7 +912,7 @@ describe("AcpAdapterV2", () => { |
| 917 | selfInvocation, | 912 | selfInvocation, |
| 918 | }); | 913 | }); |
| 919 | const threadId = ThreadId.make("thread-acp-v2-plan-replay-boundary"); | 914 | const threadId = ThreadId.make("thread-acp-v2-plan-replay-boundary"); |
| 920 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 915 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 921 | runtimeMode: "full-access", | 916 | runtimeMode: "full-access", |
| 922 | interactionMode: "default", | 917 | interactionMode: "default", |
| 923 | cwd: process.cwd(), | 918 | cwd: process.cwd(), |
| ... | @@ -1091,7 +1086,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1091,7 +1086,7 @@ describe("AcpAdapterV2", () => { |
| 1091 | }); | 1086 | }); |
| 1092 | const threadId = ThreadId.make("devin-streamed-write"); | 1087 | const threadId = ThreadId.make("devin-streamed-write"); |
| 1093 | const modelSelection = { instanceId, model: "default" }; | 1088 | const modelSelection = { instanceId, model: "default" }; |
| 1094 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1089 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1095 | runtimeMode: "full-access", | 1090 | runtimeMode: "full-access", |
| 1096 | interactionMode: "default", | 1091 | interactionMode: "default", |
| 1097 | cwd: process.cwd(), | 1092 | cwd: process.cwd(), |
| ... | @@ -1342,7 +1337,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1342,7 +1337,7 @@ describe("AcpAdapterV2", () => { |
| 1342 | }); | 1337 | }); |
| 1343 | const threadId = ThreadId.make("devin-replay-parent"); | 1338 | const threadId = ThreadId.make("devin-replay-parent"); |
| 1344 | const modelSelection = { instanceId, model: "default" }; | 1339 | const modelSelection = { instanceId, model: "default" }; |
| 1345 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1340 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1346 | runtimeMode: "full-access", | 1341 | runtimeMode: "full-access", |
| 1347 | interactionMode: "default", | 1342 | interactionMode: "default", |
| 1348 | cwd: process.cwd(), | 1343 | cwd: process.cwd(), |
| ... | @@ -1504,7 +1499,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1504,7 +1499,7 @@ describe("AcpAdapterV2", () => { |
| 1504 | selfInvocation, | 1499 | selfInvocation, |
| 1505 | }); | 1500 | }); |
| 1506 | const threadId = ThreadId.make("thread-acp-v2-fidelity"); | 1501 | const threadId = ThreadId.make("thread-acp-v2-fidelity"); |
| 1507 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1502 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1508 | runtimeMode: "full-access", | 1503 | runtimeMode: "full-access", |
| 1509 | interactionMode: "default", | 1504 | interactionMode: "default", |
| 1510 | cwd: process.cwd(), | 1505 | cwd: process.cwd(), |
| ... | @@ -1684,7 +1679,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1684,7 +1679,7 @@ describe("AcpAdapterV2", () => { |
| 1684 | selfInvocation, | 1679 | selfInvocation, |
| 1685 | }); | 1680 | }); |
| 1686 | const threadId = ThreadId.make("thread-acp-eager-resume"); | 1681 | const threadId = ThreadId.make("thread-acp-eager-resume"); |
| 1687 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1682 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1688 | runtimeMode: "full-access", | 1683 | runtimeMode: "full-access", |
| 1689 | interactionMode: "default", | 1684 | interactionMode: "default", |
| 1690 | cwd: process.cwd(), | 1685 | cwd: process.cwd(), |
| ... | @@ -1765,7 +1760,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1765,7 +1760,7 @@ describe("AcpAdapterV2", () => { |
| 1765 | selfInvocation, | 1760 | selfInvocation, |
| 1766 | }); | 1761 | }); |
| 1767 | const threadId = ThreadId.make("thread-acp-stale-eager-resume"); | 1762 | const threadId = ThreadId.make("thread-acp-stale-eager-resume"); |
| 1768 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1763 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1769 | runtimeMode: "full-access", | 1764 | runtimeMode: "full-access", |
| 1770 | interactionMode: "default", | 1765 | interactionMode: "default", |
| 1771 | cwd: process.cwd(), | 1766 | cwd: process.cwd(), |
| ... | @@ -1910,7 +1905,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1910,7 +1905,7 @@ describe("AcpAdapterV2", () => { |
| 1910 | selfInvocation, | 1905 | selfInvocation, |
| 1911 | }); | 1906 | }); |
| 1912 | const threadId = ThreadId.make("thread-acp-unexpected-termination"); | 1907 | const threadId = ThreadId.make("thread-acp-unexpected-termination"); |
| 1913 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1908 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1914 | runtimeMode: "full-access", | 1909 | runtimeMode: "full-access", |
| 1915 | interactionMode: "default", | 1910 | interactionMode: "default", |
| 1916 | cwd: process.cwd(), | 1911 | cwd: process.cwd(), |
| ... | @@ -1993,7 +1988,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -1993,7 +1988,7 @@ describe("AcpAdapterV2", () => { |
| 1993 | selfInvocation, | 1988 | selfInvocation, |
| 1994 | }); | 1989 | }); |
| 1995 | const threadId = ThreadId.make("thread-acp-provider-exit-running-command"); | 1990 | const threadId = ThreadId.make("thread-acp-provider-exit-running-command"); |
| 1996 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 1991 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1997 | runtimeMode: "full-access", | 1992 | runtimeMode: "full-access", |
| 1998 | interactionMode: "default", | 1993 | interactionMode: "default", |
| 1999 | cwd: process.cwd(), | 1994 | cwd: process.cwd(), |
| ... | @@ -2065,7 +2060,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2065,7 +2060,7 @@ describe("AcpAdapterV2", () => { |
| 2065 | selfInvocation, | 2060 | selfInvocation, |
| 2066 | }); | 2061 | }); |
| 2067 | const threadId = ThreadId.make("thread-acp-cgroup-unavailable"); | 2062 | const threadId = ThreadId.make("thread-acp-cgroup-unavailable"); |
| 2068 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2063 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2069 | runtimeMode: "full-access", | 2064 | runtimeMode: "full-access", |
| 2070 | interactionMode: "default", | 2065 | interactionMode: "default", |
| 2071 | cwd: process.cwd(), | 2066 | cwd: process.cwd(), |
| ... | @@ -2130,7 +2125,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2130,7 +2125,7 @@ describe("AcpAdapterV2", () => { |
| 2130 | selfInvocation, | 2125 | selfInvocation, |
| 2131 | }); | 2126 | }); |
| 2132 | const threadId = ThreadId.make("thread-acp-cgroup-join-failure"); | 2127 | const threadId = ThreadId.make("thread-acp-cgroup-join-failure"); |
| 2133 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2128 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2134 | runtimeMode: "full-access", | 2129 | runtimeMode: "full-access", |
| 2135 | interactionMode: "default", | 2130 | interactionMode: "default", |
| 2136 | cwd: process.cwd(), | 2131 | cwd: process.cwd(), |
| ... | @@ -2226,7 +2221,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2226,7 +2221,7 @@ describe("AcpAdapterV2", () => { |
| 2226 | McpProviderSession.clearMcpProviderSession(targetThreadId); | 2221 | McpProviderSession.clearMcpProviderSession(targetThreadId); |
| 2227 | }), | 2222 | }), |
| 2228 | ); | 2223 | ); |
| 2229 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2224 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2230 | runtimeMode: "full-access", | 2225 | runtimeMode: "full-access", |
| 2231 | interactionMode: "default", | 2226 | interactionMode: "default", |
| 2232 | cwd: process.cwd(), | 2227 | cwd: process.cwd(), |
| ... | @@ -2392,7 +2387,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2392,7 +2387,7 @@ describe("AcpAdapterV2", () => { |
| 2392 | selfInvocation, | 2387 | selfInvocation, |
| 2393 | }); | 2388 | }); |
| 2394 | const threadId = ThreadId.make("thread-acp-no-client-fs"); | 2389 | const threadId = ThreadId.make("thread-acp-no-client-fs"); |
| 2395 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2390 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2396 | runtimeMode: "full-access", | 2391 | runtimeMode: "full-access", |
| 2397 | interactionMode: "default", | 2392 | interactionMode: "default", |
| 2398 | cwd: workspace, | 2393 | cwd: workspace, |
| ... | @@ -2493,7 +2488,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2493,7 +2488,7 @@ describe("AcpAdapterV2", () => { |
| 2493 | clientTerminals: { childProcessSpawner }, | 2488 | clientTerminals: { childProcessSpawner }, |
| 2494 | }); | 2489 | }); |
| 2495 | const threadId = ThreadId.make("thread-acp-unknown-permission-grant"); | 2490 | const threadId = ThreadId.make("thread-acp-unknown-permission-grant"); |
| 2496 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2491 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2497 | runtimeMode: "approval-required", | 2492 | runtimeMode: "approval-required", |
| 2498 | interactionMode: "default", | 2493 | interactionMode: "default", |
| 2499 | cwd: process.cwd(), | 2494 | cwd: process.cwd(), |
| ... | @@ -2598,7 +2593,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2598,7 +2593,7 @@ describe("AcpAdapterV2", () => { |
| 2598 | selfInvocation, | 2593 | selfInvocation, |
| 2599 | }); | 2594 | }); |
| 2600 | const threadId = ThreadId.make("thread-acp-missing-native-thread"); | 2595 | const threadId = ThreadId.make("thread-acp-missing-native-thread"); |
| 2601 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2596 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2602 | runtimeMode: "full-access", | 2597 | runtimeMode: "full-access", |
| 2603 | interactionMode: "default", | 2598 | interactionMode: "default", |
| 2604 | cwd: process.cwd(), | 2599 | cwd: process.cwd(), |
| ... | @@ -2629,7 +2624,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2629,7 +2624,7 @@ describe("AcpAdapterV2", () => { |
| 2629 | .pipe(Effect.flip); | 2624 | .pipe(Effect.flip); |
| 2630 | 2625 | ||
| 2631 | assert.equal(error._tag, "ProviderAdapterTurnStartError"); | 2626 | assert.equal(error._tag, "ProviderAdapterTurnStartError"); |
| 2632 | assert.instanceOf(error.cause, ProviderAdapterProtocolError); | 2627 | assert.instanceOf(error.cause, ProviderAdapter.ProviderAdapterProtocolError); |
| 2633 | assert.include(String(error.cause), "missing its ACP session id"); | 2628 | assert.include(String(error.cause), "missing its ACP session id"); |
| 2634 | }).pipe(Effect.provide(layerTest), Effect.scoped), | 2629 | }).pipe(Effect.provide(layerTest), Effect.scoped), |
| 2635 | ); | 2630 | ); |
| ... | @@ -2676,7 +2671,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2676,7 +2671,7 @@ describe("AcpAdapterV2", () => { |
| 2676 | selfInvocation, | 2671 | selfInvocation, |
| 2677 | }); | 2672 | }); |
| 2678 | const threadId = ThreadId.make("thread-acp-rollback-session"); | 2673 | const threadId = ThreadId.make("thread-acp-rollback-session"); |
| 2679 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2674 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2680 | runtimeMode: "full-access", | 2675 | runtimeMode: "full-access", |
| 2681 | interactionMode: "default", | 2676 | interactionMode: "default", |
| 2682 | cwd: process.cwd(), | 2677 | cwd: process.cwd(), |
| ... | @@ -2689,7 +2684,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2689,7 +2684,7 @@ describe("AcpAdapterV2", () => { |
| 2689 | runtimePolicy, | 2684 | runtimePolicy, |
| 2690 | }); | 2685 | }); |
| 2691 | assert.isTrue(runtime.providerSession.capabilities.threads.canRollbackThread); | 2686 | assert.isTrue(runtime.providerSession.capabilities.threads.canRollbackThread); |
| 2692 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 2687 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 2693 | yield* runtime.events.pipe( | 2688 | yield* runtime.events.pipe( |
| 2694 | Stream.runForEach((event) => Queue.offer(events, event)), | 2689 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 2695 | Effect.forkScoped, | 2690 | Effect.forkScoped, |
| ... | @@ -2883,7 +2878,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2883,7 +2878,7 @@ describe("AcpAdapterV2", () => { |
| 2883 | continuationRequests: { offer: () => Effect.void }, | 2878 | continuationRequests: { offer: () => Effect.void }, |
| 2884 | }); | 2879 | }); |
| 2885 | const threadId = ThreadId.make("thread-acp-rollback-retry-generation"); | 2880 | const threadId = ThreadId.make("thread-acp-rollback-retry-generation"); |
| 2886 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2881 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2887 | runtimeMode: "full-access", | 2882 | runtimeMode: "full-access", |
| 2888 | interactionMode: "default", | 2883 | interactionMode: "default", |
| 2889 | cwd: process.cwd(), | 2884 | cwd: process.cwd(), |
| ... | @@ -2899,7 +2894,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2899,7 +2894,7 @@ describe("AcpAdapterV2", () => { |
| 2899 | return yield* Effect.die("ACP runtime must expose background work state"); | 2894 | return yield* Effect.die("ACP runtime must expose background work state"); |
| 2900 | } | 2895 | } |
| 2901 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 2896 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 2902 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 2897 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 2903 | yield* runtime.events.pipe( | 2898 | yield* runtime.events.pipe( |
| 2904 | Stream.runForEach((event) => Queue.offer(events, event)), | 2899 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 2905 | Effect.forkScoped, | 2900 | Effect.forkScoped, |
| ... | @@ -2995,7 +2990,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -2995,7 +2990,7 @@ describe("AcpAdapterV2", () => { |
| 2995 | selfInvocation, | 2990 | selfInvocation, |
| 2996 | }); | 2991 | }); |
| 2997 | const threadId = ThreadId.make("thread-acp-rollback-failure-compensation"); | 2992 | const threadId = ThreadId.make("thread-acp-rollback-failure-compensation"); |
| 2998 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 2993 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2999 | runtimeMode: "full-access", | 2994 | runtimeMode: "full-access", |
| 3000 | interactionMode: "default", | 2995 | interactionMode: "default", |
| 3001 | cwd: process.cwd(), | 2996 | cwd: process.cwd(), |
| ... | @@ -3009,7 +3004,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3009,7 +3004,7 @@ describe("AcpAdapterV2", () => { |
| 3009 | modelSelection, | 3004 | modelSelection, |
| 3010 | runtimePolicy, | 3005 | runtimePolicy, |
| 3011 | }); | 3006 | }); |
| 3012 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 3007 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 3013 | yield* runtime.events.pipe( | 3008 | yield* runtime.events.pipe( |
| 3014 | Stream.runForEach((event) => Queue.offer(events, event)), | 3009 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 3015 | Effect.forkScoped, | 3010 | Effect.forkScoped, |
| ... | @@ -3079,7 +3074,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3079,7 +3074,7 @@ describe("AcpAdapterV2", () => { |
| 3079 | selfInvocation, | 3074 | selfInvocation, |
| 3080 | }); | 3075 | }); |
| 3081 | const threadId = ThreadId.make("thread-acp-idle-finalizer"); | 3076 | const threadId = ThreadId.make("thread-acp-idle-finalizer"); |
| 3082 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3077 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3083 | runtimeMode: "full-access", | 3078 | runtimeMode: "full-access", |
| 3084 | interactionMode: "default", | 3079 | interactionMode: "default", |
| 3085 | cwd: process.cwd(), | 3080 | cwd: process.cwd(), |
| ... | @@ -3129,7 +3124,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3129,7 +3124,7 @@ describe("AcpAdapterV2", () => { |
| 3129 | threadId: ThreadId.make(`grok-model-${model}`), | 3124 | threadId: ThreadId.make(`grok-model-${model}`), |
| 3130 | providerSessionId: ProviderSessionId.make(`grok-model-${model}`), | 3125 | providerSessionId: ProviderSessionId.make(`grok-model-${model}`), |
| 3131 | modelSelection: { instanceId, model }, | 3126 | modelSelection: { instanceId, model }, |
| 3132 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 3127 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3133 | runtimeMode: "full-access", | 3128 | runtimeMode: "full-access", |
| 3134 | interactionMode: "default", | 3129 | interactionMode: "default", |
| 3135 | cwd: process.cwd(), | 3130 | cwd: process.cwd(), |
| ... | @@ -3173,7 +3168,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3173,7 +3168,7 @@ describe("AcpAdapterV2", () => { |
| 3173 | ), | 3168 | ), |
| 3174 | }); | 3169 | }); |
| 3175 | const threadId = ThreadId.make("grok-model-switch-back"); | 3170 | const threadId = ThreadId.make("grok-model-switch-back"); |
| 3176 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3171 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3177 | runtimeMode: "full-access", | 3172 | runtimeMode: "full-access", |
| 3178 | interactionMode: "default", | 3173 | interactionMode: "default", |
| 3179 | cwd: process.cwd(), | 3174 | cwd: process.cwd(), |
| ... | @@ -3242,7 +3237,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3242,7 +3237,7 @@ describe("AcpAdapterV2", () => { |
| 3242 | selfInvocation, | 3237 | selfInvocation, |
| 3243 | }); | 3238 | }); |
| 3244 | const threadId = ThreadId.make("thread-acp-unsupported-option"); | 3239 | const threadId = ThreadId.make("thread-acp-unsupported-option"); |
| 3245 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3240 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3246 | runtimeMode: "full-access", | 3241 | runtimeMode: "full-access", |
| 3247 | interactionMode: "default", | 3242 | interactionMode: "default", |
| 3248 | cwd: process.cwd(), | 3243 | cwd: process.cwd(), |
| ... | @@ -3286,7 +3281,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3286,7 +3281,7 @@ describe("AcpAdapterV2", () => { |
| 3286 | }); | 3281 | }); |
| 3287 | const firstThreadId = ThreadId.make("thread-acp-active-setup:first"); | 3282 | const firstThreadId = ThreadId.make("thread-acp-active-setup:first"); |
| 3288 | const secondThreadId = ThreadId.make("thread-acp-active-setup:second"); | 3283 | const secondThreadId = ThreadId.make("thread-acp-active-setup:second"); |
| 3289 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3284 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3290 | runtimeMode: "full-access", | 3285 | runtimeMode: "full-access", |
| 3291 | interactionMode: "default", | 3286 | interactionMode: "default", |
| 3292 | cwd: process.cwd(), | 3287 | cwd: process.cwd(), |
| ... | @@ -3400,7 +3395,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3400,7 +3395,7 @@ describe("AcpAdapterV2", () => { |
| 3400 | selfInvocation, | 3395 | selfInvocation, |
| 3401 | }); | 3396 | }); |
| 3402 | const threadId = ThreadId.make("thread-acp-empty-successful-bash"); | 3397 | const threadId = ThreadId.make("thread-acp-empty-successful-bash"); |
| 3403 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3398 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3404 | runtimeMode: "full-access", | 3399 | runtimeMode: "full-access", |
| 3405 | interactionMode: "default", | 3400 | interactionMode: "default", |
| 3406 | cwd: process.cwd(), | 3401 | cwd: process.cwd(), |
| ... | @@ -3412,7 +3407,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3412,7 +3407,7 @@ describe("AcpAdapterV2", () => { |
| 3412 | modelSelection, | 3407 | modelSelection, |
| 3413 | runtimePolicy, | 3408 | runtimePolicy, |
| 3414 | }); | 3409 | }); |
| 3415 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 3410 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 3416 | yield* runtime.events.pipe( | 3411 | yield* runtime.events.pipe( |
| 3417 | Stream.runForEach((event) => Queue.offer(events, event)), | 3412 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 3418 | Effect.forkScoped, | 3413 | Effect.forkScoped, |
| ... | @@ -3540,7 +3535,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3540,7 +3535,7 @@ describe("AcpAdapterV2", () => { |
| 3540 | selfInvocation, | 3535 | selfInvocation, |
| 3541 | }); | 3536 | }); |
| 3542 | const threadId = ThreadId.make("thread-acp-native-cancel"); | 3537 | const threadId = ThreadId.make("thread-acp-native-cancel"); |
| 3543 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3538 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3544 | runtimeMode: "full-access", | 3539 | runtimeMode: "full-access", |
| 3545 | interactionMode: "default", | 3540 | interactionMode: "default", |
| 3546 | cwd: process.cwd(), | 3541 | cwd: process.cwd(), |
| ... | @@ -3642,7 +3637,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3642,7 +3637,7 @@ describe("AcpAdapterV2", () => { |
| 3642 | selfInvocation, | 3637 | selfInvocation, |
| 3643 | }); | 3638 | }); |
| 3644 | const threadId = ThreadId.make("thread-acp-cancel-permission"); | 3639 | const threadId = ThreadId.make("thread-acp-cancel-permission"); |
| 3645 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3640 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3646 | runtimeMode: "approval-required", | 3641 | runtimeMode: "approval-required", |
| 3647 | interactionMode: "default", | 3642 | interactionMode: "default", |
| 3648 | cwd: process.cwd(), | 3643 | cwd: process.cwd(), |
| ... | @@ -3741,7 +3736,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3741,7 +3736,7 @@ describe("AcpAdapterV2", () => { |
| 3741 | selfInvocation, | 3736 | selfInvocation, |
| 3742 | }); | 3737 | }); |
| 3743 | const threadId = ThreadId.make("thread-acp-response-wins-permission"); | 3738 | const threadId = ThreadId.make("thread-acp-response-wins-permission"); |
| 3744 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3739 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3745 | runtimeMode: "approval-required", | 3740 | runtimeMode: "approval-required", |
| 3746 | interactionMode: "default", | 3741 | interactionMode: "default", |
| 3747 | cwd: process.cwd(), | 3742 | cwd: process.cwd(), |
| ... | @@ -3833,7 +3828,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3833,7 +3828,7 @@ describe("AcpAdapterV2", () => { |
| 3833 | selfInvocation, | 3828 | selfInvocation, |
| 3834 | }); | 3829 | }); |
| 3835 | const threadId = ThreadId.make("thread-acp-reordered-elicitation"); | 3830 | const threadId = ThreadId.make("thread-acp-reordered-elicitation"); |
| 3836 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3831 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3837 | runtimeMode: "approval-required", | 3832 | runtimeMode: "approval-required", |
| 3838 | interactionMode: "default", | 3833 | interactionMode: "default", |
| 3839 | cwd: process.cwd(), | 3834 | cwd: process.cwd(), |
| ... | @@ -3908,7 +3903,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3908,7 +3903,7 @@ describe("AcpAdapterV2", () => { |
| 3908 | selfInvocation, | 3903 | selfInvocation, |
| 3909 | }); | 3904 | }); |
| 3910 | const threadId = ThreadId.make("thread-acp-mcp-approval-elicitation"); | 3905 | const threadId = ThreadId.make("thread-acp-mcp-approval-elicitation"); |
| 3911 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3906 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3912 | runtimeMode: "full-access", | 3907 | runtimeMode: "full-access", |
| 3913 | interactionMode: "default", | 3908 | interactionMode: "default", |
| 3914 | cwd: process.cwd(), | 3909 | cwd: process.cwd(), |
| ... | @@ -3983,7 +3978,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -3983,7 +3978,7 @@ describe("AcpAdapterV2", () => { |
| 3983 | }, | 3978 | }, |
| 3984 | }); | 3979 | }); |
| 3985 | const threadId = ThreadId.make("thread-acp-normal-close-held-response"); | 3980 | const threadId = ThreadId.make("thread-acp-normal-close-held-response"); |
| 3986 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 3981 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 3987 | runtimeMode: "approval-required", | 3982 | runtimeMode: "approval-required", |
| 3988 | interactionMode: "default", | 3983 | interactionMode: "default", |
| 3989 | cwd: process.cwd(), | 3984 | cwd: process.cwd(), |
| ... | @@ -4089,7 +4084,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4089,7 +4084,7 @@ describe("AcpAdapterV2", () => { |
| 4089 | }, | 4084 | }, |
| 4090 | }); | 4085 | }); |
| 4091 | const threadId = ThreadId.make("thread-acp-close-wins-registration"); | 4086 | const threadId = ThreadId.make("thread-acp-close-wins-registration"); |
| 4092 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4087 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4093 | runtimeMode: "approval-required", | 4088 | runtimeMode: "approval-required", |
| 4094 | interactionMode: "default", | 4089 | interactionMode: "default", |
| 4095 | cwd: process.cwd(), | 4090 | cwd: process.cwd(), |
| ... | @@ -4208,7 +4203,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4208,7 +4203,7 @@ describe("AcpAdapterV2", () => { |
| 4208 | }, | 4203 | }, |
| 4209 | }); | 4204 | }); |
| 4210 | const threadId = ThreadId.make("thread-acp-pending-response-timeout"); | 4205 | const threadId = ThreadId.make("thread-acp-pending-response-timeout"); |
| 4211 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4206 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4212 | runtimeMode: "approval-required", | 4207 | runtimeMode: "approval-required", |
| 4213 | interactionMode: "default", | 4208 | interactionMode: "default", |
| 4214 | cwd: process.cwd(), | 4209 | cwd: process.cwd(), |
| ... | @@ -4333,7 +4328,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4333,7 +4328,7 @@ describe("AcpAdapterV2", () => { |
| 4333 | selfInvocation, | 4328 | selfInvocation, |
| 4334 | }); | 4329 | }); |
| 4335 | const threadId = ThreadId.make("thread-acp-pending-response-cancel"); | 4330 | const threadId = ThreadId.make("thread-acp-pending-response-cancel"); |
| 4336 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4331 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4337 | runtimeMode: "approval-required", | 4332 | runtimeMode: "approval-required", |
| 4338 | interactionMode: "default", | 4333 | interactionMode: "default", |
| 4339 | cwd: process.cwd(), | 4334 | cwd: process.cwd(), |
| ... | @@ -4442,7 +4437,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4442,7 +4437,7 @@ describe("AcpAdapterV2", () => { |
| 4442 | selfInvocation, | 4437 | selfInvocation, |
| 4443 | }); | 4438 | }); |
| 4444 | const threadId = ThreadId.make(`thread-acp-immediate-permission-${name}`); | 4439 | const threadId = ThreadId.make(`thread-acp-immediate-permission-${name}`); |
| 4445 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4440 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4446 | runtimeMode: "full-access", | 4441 | runtimeMode: "full-access", |
| 4447 | interactionMode: "default", | 4442 | interactionMode: "default", |
| 4448 | approvalPolicy: "never", | 4443 | approvalPolicy: "never", |
| ... | @@ -4535,7 +4530,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4535,7 +4530,7 @@ describe("AcpAdapterV2", () => { |
| 4535 | selfInvocation, | 4530 | selfInvocation, |
| 4536 | }); | 4531 | }); |
| 4537 | const threadId = ThreadId.make("thread-acp-immediate-url-elicitation"); | 4532 | const threadId = ThreadId.make("thread-acp-immediate-url-elicitation"); |
| 4538 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4533 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4539 | runtimeMode: "full-access", | 4534 | runtimeMode: "full-access", |
| 4540 | interactionMode: "default", | 4535 | interactionMode: "default", |
| 4541 | cwd: process.cwd(), | 4536 | cwd: process.cwd(), |
| ... | @@ -4626,7 +4621,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4626,7 +4621,7 @@ describe("AcpAdapterV2", () => { |
| 4626 | selfInvocation, | 4621 | selfInvocation, |
| 4627 | }); | 4622 | }); |
| 4628 | const threadId = ThreadId.make("thread-acp-missing-response-ack"); | 4623 | const threadId = ThreadId.make("thread-acp-missing-response-ack"); |
| 4629 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4624 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4630 | runtimeMode: "full-access", | 4625 | runtimeMode: "full-access", |
| 4631 | interactionMode: "default", | 4626 | interactionMode: "default", |
| 4632 | approvalPolicy: "never", | 4627 | approvalPolicy: "never", |
| ... | @@ -4708,7 +4703,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4708,7 +4703,7 @@ describe("AcpAdapterV2", () => { |
| 4708 | selfInvocation, | 4703 | selfInvocation, |
| 4709 | }); | 4704 | }); |
| 4710 | const threadId = ThreadId.make("thread-acp-teardown-wins-elicitation"); | 4705 | const threadId = ThreadId.make("thread-acp-teardown-wins-elicitation"); |
| 4711 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4706 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4712 | runtimeMode: "approval-required", | 4707 | runtimeMode: "approval-required", |
| 4713 | interactionMode: "default", | 4708 | interactionMode: "default", |
| 4714 | cwd: process.cwd(), | 4709 | cwd: process.cwd(), |
| ... | @@ -4802,7 +4797,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4802,7 +4797,7 @@ describe("AcpAdapterV2", () => { |
| 4802 | selfInvocation, | 4797 | selfInvocation, |
| 4803 | }); | 4798 | }); |
| 4804 | const threadId = ThreadId.make("thread-acp-cancel-timeout"); | 4799 | const threadId = ThreadId.make("thread-acp-cancel-timeout"); |
| 4805 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4800 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4806 | runtimeMode: "full-access", | 4801 | runtimeMode: "full-access", |
| 4807 | interactionMode: "default", | 4802 | interactionMode: "default", |
| 4808 | cwd: process.cwd(), | 4803 | cwd: process.cwd(), |
| ... | @@ -4903,7 +4898,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4903,7 +4898,7 @@ describe("AcpAdapterV2", () => { |
| 4903 | selfInvocation, | 4898 | selfInvocation, |
| 4904 | }); | 4899 | }); |
| 4905 | const threadId = ThreadId.make("thread-acp-double-stop"); | 4900 | const threadId = ThreadId.make("thread-acp-double-stop"); |
| 4906 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4901 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4907 | runtimeMode: "full-access", | 4902 | runtimeMode: "full-access", |
| 4908 | interactionMode: "default", | 4903 | interactionMode: "default", |
| 4909 | cwd: process.cwd(), | 4904 | cwd: process.cwd(), |
| ... | @@ -4915,7 +4910,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -4915,7 +4910,7 @@ describe("AcpAdapterV2", () => { |
| 4915 | modelSelection, | 4910 | modelSelection, |
| 4916 | runtimePolicy, | 4911 | runtimePolicy, |
| 4917 | }); | 4912 | }); |
| 4918 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 4913 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 4919 | yield* runtime.events.pipe( | 4914 | yield* runtime.events.pipe( |
| 4920 | Stream.runForEach((event) => Queue.offer(events, event)), | 4915 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 4921 | Effect.forkScoped, | 4916 | Effect.forkScoped, |
| ... | @@ -5007,7 +5002,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5007,7 +5002,7 @@ describe("AcpAdapterV2", () => { |
| 5007 | selfInvocation, | 5002 | selfInvocation, |
| 5008 | }); | 5003 | }); |
| 5009 | const threadId = ThreadId.make("thread-acp-interrupt-background-hold"); | 5004 | const threadId = ThreadId.make("thread-acp-interrupt-background-hold"); |
| 5010 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5005 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5011 | runtimeMode: "full-access", | 5006 | runtimeMode: "full-access", |
| 5012 | interactionMode: "default", | 5007 | interactionMode: "default", |
| 5013 | cwd: process.cwd(), | 5008 | cwd: process.cwd(), |
| ... | @@ -5019,7 +5014,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5019,7 +5014,7 @@ describe("AcpAdapterV2", () => { |
| 5019 | modelSelection, | 5014 | modelSelection, |
| 5020 | runtimePolicy, | 5015 | runtimePolicy, |
| 5021 | }); | 5016 | }); |
| 5022 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5017 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5023 | yield* runtime.events.pipe( | 5018 | yield* runtime.events.pipe( |
| 5024 | Stream.runForEach((event) => Queue.offer(events, event)), | 5019 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5025 | Effect.forkScoped, | 5020 | Effect.forkScoped, |
| ... | @@ -5111,7 +5106,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5111,7 +5106,7 @@ describe("AcpAdapterV2", () => { |
| 5111 | selfInvocation, | 5106 | selfInvocation, |
| 5112 | }); | 5107 | }); |
| 5113 | const threadId = ThreadId.make("thread-acp-subagent-carryover"); | 5108 | const threadId = ThreadId.make("thread-acp-subagent-carryover"); |
| 5114 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5109 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5115 | runtimeMode: "full-access", | 5110 | runtimeMode: "full-access", |
| 5116 | interactionMode: "default", | 5111 | interactionMode: "default", |
| 5117 | cwd: process.cwd(), | 5112 | cwd: process.cwd(), |
| ... | @@ -5123,7 +5118,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5123,7 +5118,7 @@ describe("AcpAdapterV2", () => { |
| 5123 | modelSelection, | 5118 | modelSelection, |
| 5124 | runtimePolicy, | 5119 | runtimePolicy, |
| 5125 | }); | 5120 | }); |
| 5126 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5121 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5127 | yield* runtime.events.pipe( | 5122 | yield* runtime.events.pipe( |
| 5128 | Stream.runForEach((event) => Queue.offer(events, event)), | 5123 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5129 | Effect.forkScoped, | 5124 | Effect.forkScoped, |
| ... | @@ -5252,7 +5247,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5252,7 +5247,7 @@ describe("AcpAdapterV2", () => { |
| 5252 | continuationRequests: { offer: () => Effect.void }, | 5247 | continuationRequests: { offer: () => Effect.void }, |
| 5253 | }); | 5248 | }); |
| 5254 | const threadId = ThreadId.make("thread-acp-carryover-pending-pin"); | 5249 | const threadId = ThreadId.make("thread-acp-carryover-pending-pin"); |
| 5255 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5250 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5256 | runtimeMode: "full-access", | 5251 | runtimeMode: "full-access", |
| 5257 | interactionMode: "default", | 5252 | interactionMode: "default", |
| 5258 | cwd: process.cwd(), | 5253 | cwd: process.cwd(), |
| ... | @@ -5270,7 +5265,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5270,7 +5265,7 @@ describe("AcpAdapterV2", () => { |
| 5270 | ); | 5265 | ); |
| 5271 | } | 5266 | } |
| 5272 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 5267 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 5273 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5268 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5274 | yield* runtime.events.pipe( | 5269 | yield* runtime.events.pipe( |
| 5275 | Stream.runForEach((event) => Queue.offer(events, event)), | 5270 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5276 | Effect.forkScoped, | 5271 | Effect.forkScoped, |
| ... | @@ -5416,7 +5411,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5416,7 +5411,7 @@ describe("AcpAdapterV2", () => { |
| 5416 | continuationRequests: { offer: () => Effect.void }, | 5411 | continuationRequests: { offer: () => Effect.void }, |
| 5417 | }); | 5412 | }); |
| 5418 | const threadId = ThreadId.make("thread-acp-active-carryover-pending-pin"); | 5413 | const threadId = ThreadId.make("thread-acp-active-carryover-pending-pin"); |
| 5419 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5414 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5420 | runtimeMode: "full-access", | 5415 | runtimeMode: "full-access", |
| 5421 | interactionMode: "default", | 5416 | interactionMode: "default", |
| 5422 | cwd: process.cwd(), | 5417 | cwd: process.cwd(), |
| ... | @@ -5436,7 +5431,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5436,7 +5431,7 @@ describe("AcpAdapterV2", () => { |
| 5436 | ); | 5431 | ); |
| 5437 | } | 5432 | } |
| 5438 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 5433 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 5439 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5434 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5440 | yield* runtime.events.pipe( | 5435 | yield* runtime.events.pipe( |
| 5441 | Stream.runForEach((event) => Queue.offer(events, event)), | 5436 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5442 | Effect.forkScoped, | 5437 | Effect.forkScoped, |
| ... | @@ -5661,7 +5656,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5661,7 +5656,7 @@ describe("AcpAdapterV2", () => { |
| 5661 | continuationRequests: { offer: () => Effect.void }, | 5656 | continuationRequests: { offer: () => Effect.void }, |
| 5662 | }); | 5657 | }); |
| 5663 | const threadId = ThreadId.make("thread-acp-subagent-finalize-window"); | 5658 | const threadId = ThreadId.make("thread-acp-subagent-finalize-window"); |
| 5664 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5659 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5665 | runtimeMode: "full-access", | 5660 | runtimeMode: "full-access", |
| 5666 | interactionMode: "default", | 5661 | interactionMode: "default", |
| 5667 | cwd: process.cwd(), | 5662 | cwd: process.cwd(), |
| ... | @@ -5681,7 +5676,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5681,7 +5676,7 @@ describe("AcpAdapterV2", () => { |
| 5681 | ); | 5676 | ); |
| 5682 | } | 5677 | } |
| 5683 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 5678 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 5684 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5679 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5685 | yield* runtime.events.pipe( | 5680 | yield* runtime.events.pipe( |
| 5686 | Stream.runForEach((event) => Queue.offer(events, event)), | 5681 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5687 | Effect.forkScoped, | 5682 | Effect.forkScoped, |
| ... | @@ -5796,7 +5791,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -5796,7 +5791,8 @@ describe("AcpAdapterV2", () => { |
| 5796 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 5791 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 5797 | ); | 5792 | ); |
| 5798 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 5793 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 5799 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 5794 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 5795 | []; | ||
| 5800 | const promptSettled = yield* Deferred.make<void>(); | 5796 | const promptSettled = yield* Deferred.make<void>(); |
| 5801 | const instanceId = ProviderInstanceId.make("acp-test"); | 5797 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 5802 | const childSessionId = "mock-child-session-post-settle"; | 5798 | const childSessionId = "mock-child-session-post-settle"; |
| ... | @@ -5859,7 +5855,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5859,7 +5855,7 @@ describe("AcpAdapterV2", () => { |
| 5859 | }, | 5855 | }, |
| 5860 | }); | 5856 | }); |
| 5861 | const threadId = ThreadId.make("thread-acp-carryover-child-session-post-settle"); | 5857 | const threadId = ThreadId.make("thread-acp-carryover-child-session-post-settle"); |
| 5862 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 5858 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 5863 | runtimeMode: "full-access", | 5859 | runtimeMode: "full-access", |
| 5864 | interactionMode: "default", | 5860 | interactionMode: "default", |
| 5865 | cwd: process.cwd(), | 5861 | cwd: process.cwd(), |
| ... | @@ -5879,7 +5875,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -5879,7 +5875,7 @@ describe("AcpAdapterV2", () => { |
| 5879 | ); | 5875 | ); |
| 5880 | } | 5876 | } |
| 5881 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 5877 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 5882 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 5878 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 5883 | yield* runtime.events.pipe( | 5879 | yield* runtime.events.pipe( |
| 5884 | Stream.runForEach((event) => Queue.offer(events, event)), | 5880 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 5885 | Effect.forkScoped, | 5881 | Effect.forkScoped, |
| ... | @@ -6046,7 +6042,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6046,7 +6042,7 @@ describe("AcpAdapterV2", () => { |
| 6046 | continuationRequests: { offer: () => Effect.void }, | 6042 | continuationRequests: { offer: () => Effect.void }, |
| 6047 | }); | 6043 | }); |
| 6048 | const threadId = ThreadId.make("thread-acp-carryover-subagent-finished"); | 6044 | const threadId = ThreadId.make("thread-acp-carryover-subagent-finished"); |
| 6049 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 6045 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 6050 | runtimeMode: "full-access", | 6046 | runtimeMode: "full-access", |
| 6051 | interactionMode: "default", | 6047 | interactionMode: "default", |
| 6052 | cwd: process.cwd(), | 6048 | cwd: process.cwd(), |
| ... | @@ -6062,7 +6058,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6062,7 +6058,7 @@ describe("AcpAdapterV2", () => { |
| 6062 | return yield* Effect.die("post-settle continuation must expose hasPendingBackgroundWork"); | 6058 | return yield* Effect.die("post-settle continuation must expose hasPendingBackgroundWork"); |
| 6063 | } | 6059 | } |
| 6064 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 6060 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 6065 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 6061 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 6066 | yield* runtime.events.pipe( | 6062 | yield* runtime.events.pipe( |
| 6067 | Stream.runForEach((event) => Queue.offer(events, event)), | 6063 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 6068 | Effect.forkScoped, | 6064 | Effect.forkScoped, |
| ... | @@ -6151,7 +6147,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -6151,7 +6147,8 @@ describe("AcpAdapterV2", () => { |
| 6151 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 6147 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 6152 | ); | 6148 | ); |
| 6153 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 6149 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 6154 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 6150 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 6151 | []; | ||
| 6155 | const instanceId = ProviderInstanceId.make("acp-test"); | 6152 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 6156 | const childSessionId = "019f44a6-4820-7402-925d-bc862ee711dd"; | 6153 | const childSessionId = "019f44a6-4820-7402-925d-bc862ee711dd"; |
| 6157 | let subagentPhase: "spawn" | "complete" = "spawn"; | 6154 | let subagentPhase: "spawn" | "complete" = "spawn"; |
| ... | @@ -6210,7 +6207,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6210,7 +6207,7 @@ describe("AcpAdapterV2", () => { |
| 6210 | }, | 6207 | }, |
| 6211 | }); | 6208 | }); |
| 6212 | const threadId = ThreadId.make("thread-acp-completed-root-eager-carryover"); | 6209 | const threadId = ThreadId.make("thread-acp-completed-root-eager-carryover"); |
| 6213 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 6210 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 6214 | runtimeMode: "full-access", | 6211 | runtimeMode: "full-access", |
| 6215 | interactionMode: "default", | 6212 | interactionMode: "default", |
| 6216 | cwd: process.cwd(), | 6213 | cwd: process.cwd(), |
| ... | @@ -6230,7 +6227,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6230,7 +6227,7 @@ describe("AcpAdapterV2", () => { |
| 6230 | ); | 6227 | ); |
| 6231 | } | 6228 | } |
| 6232 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 6229 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 6233 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 6230 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 6234 | yield* runtime.events.pipe( | 6231 | yield* runtime.events.pipe( |
| 6235 | Stream.runForEach((event) => Queue.offer(events, event)), | 6232 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 6236 | Effect.forkScoped, | 6233 | Effect.forkScoped, |
| ... | @@ -6396,7 +6393,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -6396,7 +6393,8 @@ describe("AcpAdapterV2", () => { |
| 6396 | const mockAgentPath = yield* path.fromFileUrl( | 6393 | const mockAgentPath = yield* path.fromFileUrl( |
| 6397 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 6394 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 6398 | ); | 6395 | ); |
| 6399 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 6396 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 6397 | []; | ||
| 6400 | const bufferedAssistantText = "BUFFERED_WAKE_AFTER_USER_ATTACH"; | 6398 | const bufferedAssistantText = "BUFFERED_WAKE_AFTER_USER_ATTACH"; |
| 6401 | const instanceId = ProviderInstanceId.make("acp-test"); | 6399 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 6402 | let subagentPhase: "spawn" | "complete" = "spawn"; | 6400 | let subagentPhase: "spawn" | "complete" = "spawn"; |
| ... | @@ -6458,7 +6456,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6458,7 +6456,7 @@ describe("AcpAdapterV2", () => { |
| 6458 | }, | 6456 | }, |
| 6459 | }); | 6457 | }); |
| 6460 | const threadId = ThreadId.make("thread-acp-carryover-root-session-continuation"); | 6458 | const threadId = ThreadId.make("thread-acp-carryover-root-session-continuation"); |
| 6461 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 6459 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 6462 | runtimeMode: "full-access", | 6460 | runtimeMode: "full-access", |
| 6463 | interactionMode: "default", | 6461 | interactionMode: "default", |
| 6464 | cwd: process.cwd(), | 6462 | cwd: process.cwd(), |
| ... | @@ -6478,7 +6476,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6478,7 +6476,7 @@ describe("AcpAdapterV2", () => { |
| 6478 | ); | 6476 | ); |
| 6479 | } | 6477 | } |
| 6480 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 6478 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 6481 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 6479 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 6482 | yield* runtime.events.pipe( | 6480 | yield* runtime.events.pipe( |
| 6483 | Stream.runForEach((event) => Queue.offer(events, event)), | 6481 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 6484 | Effect.forkScoped, | 6482 | Effect.forkScoped, |
| ... | @@ -6678,7 +6676,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -6678,7 +6676,8 @@ describe("AcpAdapterV2", () => { |
| 6678 | const mockAgentPath = yield* path.fromFileUrl( | 6676 | const mockAgentPath = yield* path.fromFileUrl( |
| 6679 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 6677 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 6680 | ); | 6678 | ); |
| 6681 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 6679 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 6680 | []; | ||
| 6682 | const promptWireReturned = yield* Deferred.make<void>(); | 6681 | const promptWireReturned = yield* Deferred.make<void>(); |
| 6683 | const releasePromptCompletion = yield* Deferred.make<void>(); | 6682 | const releasePromptCompletion = yield* Deferred.make<void>(); |
| 6684 | const instanceId = ProviderInstanceId.make("acp-test"); | 6683 | const instanceId = ProviderInstanceId.make("acp-test"); |
| ... | @@ -6750,7 +6749,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6750,7 +6749,7 @@ describe("AcpAdapterV2", () => { |
| 6750 | }, | 6749 | }, |
| 6751 | }); | 6750 | }); |
| 6752 | const threadId = ThreadId.make("thread-acp-carryover-already-handled-re-report"); | 6751 | const threadId = ThreadId.make("thread-acp-carryover-already-handled-re-report"); |
| 6753 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 6752 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 6754 | runtimeMode: "full-access", | 6753 | runtimeMode: "full-access", |
| 6755 | interactionMode: "default", | 6754 | interactionMode: "default", |
| 6756 | cwd: process.cwd(), | 6755 | cwd: process.cwd(), |
| ... | @@ -6770,7 +6769,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6770,7 +6769,7 @@ describe("AcpAdapterV2", () => { |
| 6770 | ); | 6769 | ); |
| 6771 | } | 6770 | } |
| 6772 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 6771 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 6773 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 6772 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 6774 | yield* runtime.events.pipe( | 6773 | yield* runtime.events.pipe( |
| 6775 | Stream.runForEach((event) => Queue.offer(events, event)), | 6774 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 6776 | Effect.forkScoped, | 6775 | Effect.forkScoped, |
| ... | @@ -6914,7 +6913,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -6914,7 +6913,8 @@ describe("AcpAdapterV2", () => { |
| 6914 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 6913 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 6915 | ); | 6914 | ); |
| 6916 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 6915 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 6917 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 6916 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 6917 | []; | ||
| 6918 | const promptSettled = yield* Deferred.make<void>(); | 6918 | const promptSettled = yield* Deferred.make<void>(); |
| 6919 | const instanceId = ProviderInstanceId.make("acp-test"); | 6919 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 6920 | const childSessionId = "019f5470-bf92-7a90-afb3-5a6cea5b34a3"; | 6920 | const childSessionId = "019f5470-bf92-7a90-afb3-5a6cea5b34a3"; |
| ... | @@ -6988,7 +6988,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -6988,7 +6988,7 @@ describe("AcpAdapterV2", () => { |
| 6988 | }, | 6988 | }, |
| 6989 | }); | 6989 | }); |
| 6990 | const threadId = ThreadId.make("thread-acp-carryover-root-end-notice"); | 6990 | const threadId = ThreadId.make("thread-acp-carryover-root-end-notice"); |
| 6991 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 6991 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 6992 | runtimeMode: "full-access", | 6992 | runtimeMode: "full-access", |
| 6993 | interactionMode: "default", | 6993 | interactionMode: "default", |
| 6994 | cwd: process.cwd(), | 6994 | cwd: process.cwd(), |
| ... | @@ -7006,7 +7006,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7006,7 +7006,7 @@ describe("AcpAdapterV2", () => { |
| 7006 | ); | 7006 | ); |
| 7007 | } | 7007 | } |
| 7008 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 7008 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 7009 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 7009 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 7010 | yield* runtime.events.pipe( | 7010 | yield* runtime.events.pipe( |
| 7011 | Stream.runForEach((event) => Queue.offer(events, event)), | 7011 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 7012 | Effect.forkScoped, | 7012 | Effect.forkScoped, |
| ... | @@ -7136,7 +7136,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -7136,7 +7136,8 @@ describe("AcpAdapterV2", () => { |
| 7136 | const mockAgentPath = yield* path.fromFileUrl( | 7136 | const mockAgentPath = yield* path.fromFileUrl( |
| 7137 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 7137 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 7138 | ); | 7138 | ); |
| 7139 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 7139 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 7140 | []; | ||
| 7140 | const instanceId = ProviderInstanceId.make("acp-test"); | 7141 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 7141 | const childSessionId = "mock-child-session-pending-continuation"; | 7142 | const childSessionId = "mock-child-session-pending-continuation"; |
| 7142 | const bufferedAssistantText = "POST_SETTLE_BUFFERED_ASSISTANT_TEXT"; | 7143 | const bufferedAssistantText = "POST_SETTLE_BUFFERED_ASSISTANT_TEXT"; |
| ... | @@ -7199,7 +7200,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7199,7 +7200,7 @@ describe("AcpAdapterV2", () => { |
| 7199 | }, | 7200 | }, |
| 7200 | }); | 7201 | }); |
| 7201 | const threadId = ThreadId.make("thread-acp-carryover-child-pending-continuation"); | 7202 | const threadId = ThreadId.make("thread-acp-carryover-child-pending-continuation"); |
| 7202 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 7203 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 7203 | runtimeMode: "full-access", | 7204 | runtimeMode: "full-access", |
| 7204 | interactionMode: "default", | 7205 | interactionMode: "default", |
| 7205 | cwd: process.cwd(), | 7206 | cwd: process.cwd(), |
| ... | @@ -7219,7 +7220,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7219,7 +7220,7 @@ describe("AcpAdapterV2", () => { |
| 7219 | ); | 7220 | ); |
| 7220 | } | 7221 | } |
| 7221 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 7222 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 7222 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 7223 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 7223 | yield* runtime.events.pipe( | 7224 | yield* runtime.events.pipe( |
| 7224 | Stream.runForEach((event) => Queue.offer(events, event)), | 7225 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 7225 | Effect.forkScoped, | 7226 | Effect.forkScoped, |
| ... | @@ -7401,7 +7402,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -7401,7 +7402,8 @@ describe("AcpAdapterV2", () => { |
| 7401 | const mockAgentPath = yield* path.fromFileUrl( | 7402 | const mockAgentPath = yield* path.fromFileUrl( |
| 7402 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 7403 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 7403 | ); | 7404 | ); |
| 7404 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 7405 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 7406 | []; | ||
| 7405 | const instanceId = ProviderInstanceId.make("acp-test"); | 7407 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 7406 | const childSessionId = "mock-child-session-root-then-child"; | 7408 | const childSessionId = "mock-child-session-root-then-child"; |
| 7407 | let subagentPhase: "spawn" | "complete" = "spawn"; | 7409 | let subagentPhase: "spawn" | "complete" = "spawn"; |
| ... | @@ -7463,7 +7465,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7463,7 +7465,7 @@ describe("AcpAdapterV2", () => { |
| 7463 | }, | 7465 | }, |
| 7464 | }); | 7466 | }); |
| 7465 | const threadId = ThreadId.make("thread-acp-carryover-root-then-child"); | 7467 | const threadId = ThreadId.make("thread-acp-carryover-root-then-child"); |
| 7466 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 7468 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 7467 | runtimeMode: "full-access", | 7469 | runtimeMode: "full-access", |
| 7468 | interactionMode: "default", | 7470 | interactionMode: "default", |
| 7469 | cwd: process.cwd(), | 7471 | cwd: process.cwd(), |
| ... | @@ -7483,7 +7485,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7483,7 +7485,7 @@ describe("AcpAdapterV2", () => { |
| 7483 | ); | 7485 | ); |
| 7484 | } | 7486 | } |
| 7485 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 7487 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 7486 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 7488 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 7487 | yield* runtime.events.pipe( | 7489 | yield* runtime.events.pipe( |
| 7488 | Stream.runForEach((event) => Queue.offer(events, event)), | 7490 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 7489 | Effect.forkScoped, | 7491 | Effect.forkScoped, |
| ... | @@ -7701,7 +7703,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7701,7 +7703,7 @@ describe("AcpAdapterV2", () => { |
| 7701 | selfInvocation, | 7703 | selfInvocation, |
| 7702 | }); | 7704 | }); |
| 7703 | const threadId = ThreadId.make("thread-acp-settled-soft-steer"); | 7705 | const threadId = ThreadId.make("thread-acp-settled-soft-steer"); |
| 7704 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 7706 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 7705 | runtimeMode: "full-access", | 7707 | runtimeMode: "full-access", |
| 7706 | interactionMode: "default", | 7708 | interactionMode: "default", |
| 7707 | cwd: process.cwd(), | 7709 | cwd: process.cwd(), |
| ... | @@ -7713,7 +7715,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7713,7 +7715,7 @@ describe("AcpAdapterV2", () => { |
| 7713 | modelSelection, | 7715 | modelSelection, |
| 7714 | runtimePolicy, | 7716 | runtimePolicy, |
| 7715 | }); | 7717 | }); |
| 7716 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 7718 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 7717 | yield* runtime.events.pipe( | 7719 | yield* runtime.events.pipe( |
| 7718 | Stream.runForEach((event) => Queue.offer(events, event)), | 7720 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 7719 | Effect.forkScoped, | 7721 | Effect.forkScoped, |
| ... | @@ -7834,7 +7836,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7834,7 +7836,7 @@ describe("AcpAdapterV2", () => { |
| 7834 | selfInvocation, | 7836 | selfInvocation, |
| 7835 | }); | 7837 | }); |
| 7836 | const threadId = ThreadId.make("thread-acp-unsettled-steer-stays-hard"); | 7838 | const threadId = ThreadId.make("thread-acp-unsettled-steer-stays-hard"); |
| 7837 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 7839 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 7838 | runtimeMode: "full-access", | 7840 | runtimeMode: "full-access", |
| 7839 | interactionMode: "default", | 7841 | interactionMode: "default", |
| 7840 | cwd: process.cwd(), | 7842 | cwd: process.cwd(), |
| ... | @@ -7892,7 +7894,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -7892,7 +7894,8 @@ describe("AcpAdapterV2", () => { |
| 7892 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 7894 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 7893 | ); | 7895 | ); |
| 7894 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 7896 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 7895 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 7897 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 7898 | []; | ||
| 7896 | const instanceId = ProviderInstanceId.make("acp-test"); | 7899 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 7897 | let cancelCalled = false; | 7900 | let cancelCalled = false; |
| 7898 | let runtimeOrdinalSeen = 0; | 7901 | let runtimeOrdinalSeen = 0; |
| ... | @@ -7940,7 +7943,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7940,7 +7943,7 @@ describe("AcpAdapterV2", () => { |
| 7940 | }, | 7943 | }, |
| 7941 | }); | 7944 | }); |
| 7942 | const threadId = ThreadId.make("thread-acp-soft-mid-prompt-steer"); | 7945 | const threadId = ThreadId.make("thread-acp-soft-mid-prompt-steer"); |
| 7943 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 7946 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 7944 | runtimeMode: "full-access", | 7947 | runtimeMode: "full-access", |
| 7945 | interactionMode: "default", | 7948 | interactionMode: "default", |
| 7946 | cwd: process.cwd(), | 7949 | cwd: process.cwd(), |
| ... | @@ -7958,7 +7961,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -7958,7 +7961,7 @@ describe("AcpAdapterV2", () => { |
| 7958 | ); | 7961 | ); |
| 7959 | } | 7962 | } |
| 7960 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 7963 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 7961 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 7964 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 7962 | yield* runtime.events.pipe( | 7965 | yield* runtime.events.pipe( |
| 7963 | Stream.runForEach((event) => Queue.offer(events, event)), | 7966 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 7964 | Effect.forkScoped, | 7967 | Effect.forkScoped, |
| ... | @@ -8115,7 +8118,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8115,7 +8118,7 @@ describe("AcpAdapterV2", () => { |
| 8115 | continuationRequests: { offer: () => Effect.void }, | 8118 | continuationRequests: { offer: () => Effect.void }, |
| 8116 | }); | 8119 | }); |
| 8117 | const threadId = ThreadId.make("thread-acp-stop-quarantine-late-task"); | 8120 | const threadId = ThreadId.make("thread-acp-stop-quarantine-late-task"); |
| 8118 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 8121 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 8119 | runtimeMode: "full-access", | 8122 | runtimeMode: "full-access", |
| 8120 | interactionMode: "default", | 8123 | interactionMode: "default", |
| 8121 | cwd: process.cwd(), | 8124 | cwd: process.cwd(), |
| ... | @@ -8133,7 +8136,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8133,7 +8136,7 @@ describe("AcpAdapterV2", () => { |
| 8133 | ); | 8136 | ); |
| 8134 | } | 8137 | } |
| 8135 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 8138 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 8136 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 8139 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 8137 | yield* runtime.events.pipe( | 8140 | yield* runtime.events.pipe( |
| 8138 | Stream.runForEach((event) => Queue.offer(events, event)), | 8141 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 8139 | Effect.forkScoped, | 8142 | Effect.forkScoped, |
| ... | @@ -8255,7 +8258,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8255,7 +8258,7 @@ describe("AcpAdapterV2", () => { |
| 8255 | continuationRequests: { offer: () => Effect.void }, | 8258 | continuationRequests: { offer: () => Effect.void }, |
| 8256 | }); | 8259 | }); |
| 8257 | const threadId = ThreadId.make("thread-acp-production-stop-hard-kill"); | 8260 | const threadId = ThreadId.make("thread-acp-production-stop-hard-kill"); |
| 8258 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 8261 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 8259 | runtimeMode: "full-access", | 8262 | runtimeMode: "full-access", |
| 8260 | interactionMode: "default", | 8263 | interactionMode: "default", |
| 8261 | cwd: process.cwd(), | 8264 | cwd: process.cwd(), |
| ... | @@ -8267,7 +8270,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8267,7 +8270,7 @@ describe("AcpAdapterV2", () => { |
| 8267 | modelSelection, | 8270 | modelSelection, |
| 8268 | runtimePolicy, | 8271 | runtimePolicy, |
| 8269 | }); | 8272 | }); |
| 8270 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 8273 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 8271 | yield* runtime.events.pipe( | 8274 | yield* runtime.events.pipe( |
| 8272 | Stream.runForEach((event) => Queue.offer(events, event)), | 8275 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 8273 | Effect.forkScoped, | 8276 | Effect.forkScoped, |
| ... | @@ -8417,7 +8420,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8417,7 +8420,7 @@ describe("AcpAdapterV2", () => { |
| 8417 | selfInvocation, | 8420 | selfInvocation, |
| 8418 | }); | 8421 | }); |
| 8419 | const threadId = ThreadId.make("thread-acp-stop-after-soft-steer-orphan"); | 8422 | const threadId = ThreadId.make("thread-acp-stop-after-soft-steer-orphan"); |
| 8420 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 8423 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 8421 | runtimeMode: "full-access", | 8424 | runtimeMode: "full-access", |
| 8422 | interactionMode: "default", | 8425 | interactionMode: "default", |
| 8423 | cwd: process.cwd(), | 8426 | cwd: process.cwd(), |
| ... | @@ -8431,7 +8434,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8431,7 +8434,7 @@ describe("AcpAdapterV2", () => { |
| 8431 | modelSelection, | 8434 | modelSelection, |
| 8432 | runtimePolicy, | 8435 | runtimePolicy, |
| 8433 | }); | 8436 | }); |
| 8434 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 8437 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 8435 | yield* runtime.events.pipe( | 8438 | yield* runtime.events.pipe( |
| 8436 | Stream.runForEach((event) => Queue.offer(events, event)), | 8439 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 8437 | Effect.forkScoped, | 8440 | Effect.forkScoped, |
| ... | @@ -8700,7 +8703,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8700,7 +8703,7 @@ describe("AcpAdapterV2", () => { |
| 8700 | continuationRequests: { offer: () => Effect.void }, | 8703 | continuationRequests: { offer: () => Effect.void }, |
| 8701 | }); | 8704 | }); |
| 8702 | const threadId = ThreadId.make("thread-acp-direct-stop-deferred-terminal"); | 8705 | const threadId = ThreadId.make("thread-acp-direct-stop-deferred-terminal"); |
| 8703 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 8706 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 8704 | runtimeMode: "full-access", | 8707 | runtimeMode: "full-access", |
| 8705 | interactionMode: "default", | 8708 | interactionMode: "default", |
| 8706 | cwd: process.cwd(), | 8709 | cwd: process.cwd(), |
| ... | @@ -8720,7 +8723,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8720,7 +8723,7 @@ describe("AcpAdapterV2", () => { |
| 8720 | ); | 8723 | ); |
| 8721 | } | 8724 | } |
| 8722 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 8725 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 8723 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 8726 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 8724 | yield* runtime.events.pipe( | 8727 | yield* runtime.events.pipe( |
| 8725 | Stream.runForEach((event) => Queue.offer(events, event)), | 8728 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 8726 | Effect.forkScoped, | 8729 | Effect.forkScoped, |
| ... | @@ -8904,7 +8907,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8904,7 +8907,7 @@ describe("AcpAdapterV2", () => { |
| 8904 | selfInvocation, | 8907 | selfInvocation, |
| 8905 | }); | 8908 | }); |
| 8906 | const threadId = ThreadId.make("thread-acp-settled-soft-admission-race"); | 8909 | const threadId = ThreadId.make("thread-acp-settled-soft-admission-race"); |
| 8907 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 8910 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 8908 | runtimeMode: "full-access", | 8911 | runtimeMode: "full-access", |
| 8909 | interactionMode: "default", | 8912 | interactionMode: "default", |
| 8910 | cwd: process.cwd(), | 8913 | cwd: process.cwd(), |
| ... | @@ -8918,7 +8921,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -8918,7 +8921,7 @@ describe("AcpAdapterV2", () => { |
| 8918 | modelSelection, | 8921 | modelSelection, |
| 8919 | runtimePolicy, | 8922 | runtimePolicy, |
| 8920 | }); | 8923 | }); |
| 8921 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 8924 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 8922 | yield* runtime.events.pipe( | 8925 | yield* runtime.events.pipe( |
| 8923 | Stream.runForEach((event) => Queue.offer(events, event)), | 8926 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 8924 | Effect.forkScoped, | 8927 | Effect.forkScoped, |
| ... | @@ -8999,7 +9002,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -8999,7 +9002,8 @@ describe("AcpAdapterV2", () => { |
| 8999 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 9002 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 9000 | ); | 9003 | ); |
| 9001 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 9004 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 9002 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9005 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9006 | []; | ||
| 9003 | const instanceId = ProviderInstanceId.make("acp-test"); | 9007 | const instanceId = ProviderInstanceId.make("acp-test"); |
| 9004 | const adapter = yield* makeAcpAdapterV2({ | 9008 | const adapter = yield* makeAcpAdapterV2({ |
| 9005 | instanceId, | 9009 | instanceId, |
| ... | @@ -9037,7 +9041,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9037,7 +9041,7 @@ describe("AcpAdapterV2", () => { |
| 9037 | }, | 9041 | }, |
| 9038 | }); | 9042 | }); |
| 9039 | const threadId = ThreadId.make("thread-acp-already-handled-wake-pin"); | 9043 | const threadId = ThreadId.make("thread-acp-already-handled-wake-pin"); |
| 9040 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9044 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9041 | runtimeMode: "full-access", | 9045 | runtimeMode: "full-access", |
| 9042 | interactionMode: "default", | 9046 | interactionMode: "default", |
| 9043 | cwd: process.cwd(), | 9047 | cwd: process.cwd(), |
| ... | @@ -9057,7 +9061,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9057,7 +9061,7 @@ describe("AcpAdapterV2", () => { |
| 9057 | ); | 9061 | ); |
| 9058 | } | 9062 | } |
| 9059 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 9063 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 9060 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9064 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9061 | yield* runtime.events.pipe( | 9065 | yield* runtime.events.pipe( |
| 9062 | Stream.runForEach((event) => Queue.offer(events, event)), | 9066 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9063 | Effect.forkScoped, | 9067 | Effect.forkScoped, |
| ... | @@ -9123,7 +9127,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -9123,7 +9127,8 @@ describe("AcpAdapterV2", () => { |
| 9123 | const mockAgentPath = yield* path.fromFileUrl( | 9127 | const mockAgentPath = yield* path.fromFileUrl( |
| 9124 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 9128 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 9125 | ); | 9129 | ); |
| 9126 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9130 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9131 | []; | ||
| 9127 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 9132 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 9128 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 9133 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 9129 | const instanceId = ProviderInstanceId.make("acp-test"); | 9134 | const instanceId = ProviderInstanceId.make("acp-test"); |
| ... | @@ -9154,7 +9159,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9154,7 +9159,7 @@ describe("AcpAdapterV2", () => { |
| 9154 | }, | 9159 | }, |
| 9155 | }); | 9160 | }); |
| 9156 | const threadId = ThreadId.make("thread-acp-sticky-continuation-dispatch"); | 9161 | const threadId = ThreadId.make("thread-acp-sticky-continuation-dispatch"); |
| 9157 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9162 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9158 | runtimeMode: "full-access", | 9163 | runtimeMode: "full-access", |
| 9159 | interactionMode: "default", | 9164 | interactionMode: "default", |
| 9160 | cwd: process.cwd(), | 9165 | cwd: process.cwd(), |
| ... | @@ -9168,7 +9173,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9168,7 +9173,7 @@ describe("AcpAdapterV2", () => { |
| 9168 | modelSelection, | 9173 | modelSelection, |
| 9169 | runtimePolicy, | 9174 | runtimePolicy, |
| 9170 | }); | 9175 | }); |
| 9171 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9176 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9172 | yield* runtime.events.pipe( | 9177 | yield* runtime.events.pipe( |
| 9173 | Stream.runForEach((event) => Queue.offer(events, event)), | 9178 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9174 | Effect.forkScoped, | 9179 | Effect.forkScoped, |
| ... | @@ -9237,7 +9242,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -9237,7 +9242,8 @@ describe("AcpAdapterV2", () => { |
| 9237 | const mockAgentPath = yield* path.fromFileUrl( | 9242 | const mockAgentPath = yield* path.fromFileUrl( |
| 9238 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 9243 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 9239 | ); | 9244 | ); |
| 9240 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9245 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9246 | []; | ||
| 9241 | const userPromptStarted = yield* Deferred.make<void>(); | 9247 | const userPromptStarted = yield* Deferred.make<void>(); |
| 9242 | const releaseUserPrompt = yield* Deferred.make<void>(); | 9248 | const releaseUserPrompt = yield* Deferred.make<void>(); |
| 9243 | const bufferedAssistantText = "BUFFERED_WAKE_QUEUED_AFTER_USER"; | 9249 | const bufferedAssistantText = "BUFFERED_WAKE_QUEUED_AFTER_USER"; |
| ... | @@ -9284,7 +9290,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9284,7 +9290,7 @@ describe("AcpAdapterV2", () => { |
| 9284 | }, | 9290 | }, |
| 9285 | }); | 9291 | }); |
| 9286 | const threadId = ThreadId.make("thread-acp-buffered-continuation-user-race"); | 9292 | const threadId = ThreadId.make("thread-acp-buffered-continuation-user-race"); |
| 9287 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9293 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9288 | runtimeMode: "full-access", | 9294 | runtimeMode: "full-access", |
| 9289 | interactionMode: "default", | 9295 | interactionMode: "default", |
| 9290 | cwd: process.cwd(), | 9296 | cwd: process.cwd(), |
| ... | @@ -9304,7 +9310,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9304,7 +9310,7 @@ describe("AcpAdapterV2", () => { |
| 9304 | ); | 9310 | ); |
| 9305 | } | 9311 | } |
| 9306 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 9312 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 9307 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9313 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9308 | yield* runtime.events.pipe( | 9314 | yield* runtime.events.pipe( |
| 9309 | Stream.runForEach((event) => Queue.offer(events, event)), | 9315 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9310 | Effect.forkScoped, | 9316 | Effect.forkScoped, |
| ... | @@ -9480,7 +9486,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9480,7 +9486,7 @@ describe("AcpAdapterV2", () => { |
| 9480 | selfInvocation, | 9486 | selfInvocation, |
| 9481 | }); | 9487 | }); |
| 9482 | const threadId = ThreadId.make("thread-acp-injected-report-hold"); | 9488 | const threadId = ThreadId.make("thread-acp-injected-report-hold"); |
| 9483 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9489 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9484 | runtimeMode: "full-access", | 9490 | runtimeMode: "full-access", |
| 9485 | interactionMode: "default", | 9491 | interactionMode: "default", |
| 9486 | cwd: process.cwd(), | 9492 | cwd: process.cwd(), |
| ... | @@ -9492,7 +9498,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9492,7 +9498,7 @@ describe("AcpAdapterV2", () => { |
| 9492 | modelSelection, | 9498 | modelSelection, |
| 9493 | runtimePolicy, | 9499 | runtimePolicy, |
| 9494 | }); | 9500 | }); |
| 9495 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9501 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9496 | yield* runtime.events.pipe( | 9502 | yield* runtime.events.pipe( |
| 9497 | Stream.runForEach((event) => Queue.offer(events, event)), | 9503 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9498 | Effect.forkScoped, | 9504 | Effect.forkScoped, |
| ... | @@ -9515,7 +9521,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9515,7 +9521,7 @@ describe("AcpAdapterV2", () => { |
| 9515 | // hydration are ingested: the hydrated monitor card carries the | 9521 | // hydration are ingested: the hydrated monitor card carries the |
| 9516 | // fetched listing. | 9522 | // fetched listing. |
| 9517 | let reportSeen = false; | 9523 | let reportSeen = false; |
| 9518 | const trackReport = (event: ProviderAdapterV2Event): void => { | 9524 | const trackReport = (event: ProviderAdapter.ProviderAdapterV2Event): void => { |
| 9519 | if ( | 9525 | if ( |
| 9520 | event.type === "turn_item.updated" && | 9526 | event.type === "turn_item.updated" && |
| 9521 | event.turnItem.type === "assistant_message" && | 9527 | event.turnItem.type === "assistant_message" && |
| ... | @@ -9605,7 +9611,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -9605,7 +9611,8 @@ describe("AcpAdapterV2", () => { |
| 9605 | const triggerDir = yield* fileSystem.makeTempDirectoryScoped(); | 9611 | const triggerDir = yield* fileSystem.makeTempDirectoryScoped(); |
| 9606 | const triggerPath = path.join(triggerDir, "report-trigger"); | 9612 | const triggerPath = path.join(triggerDir, "report-trigger"); |
| 9607 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 9613 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 9608 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9614 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9615 | []; | ||
| 9609 | const capturedMutation: { | 9616 | const capturedMutation: { |
| 9610 | current: | 9617 | current: |
| 9611 | | ((mutation: { | 9618 | | ((mutation: { |
| ... | @@ -9662,7 +9669,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9662,7 +9669,7 @@ describe("AcpAdapterV2", () => { |
| 9662 | }, | 9669 | }, |
| 9663 | }); | 9670 | }); |
| 9664 | const threadId = ThreadId.make("thread-acp-settle-hold-ext-complete-no-wake"); | 9671 | const threadId = ThreadId.make("thread-acp-settle-hold-ext-complete-no-wake"); |
| 9665 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9672 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9666 | runtimeMode: "full-access", | 9673 | runtimeMode: "full-access", |
| 9667 | interactionMode: "default", | 9674 | interactionMode: "default", |
| 9668 | cwd: process.cwd(), | 9675 | cwd: process.cwd(), |
| ... | @@ -9676,7 +9683,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9676,7 +9683,7 @@ describe("AcpAdapterV2", () => { |
| 9676 | modelSelection, | 9683 | modelSelection, |
| 9677 | runtimePolicy, | 9684 | runtimePolicy, |
| 9678 | }); | 9685 | }); |
| 9679 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9686 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9680 | yield* runtime.events.pipe( | 9687 | yield* runtime.events.pipe( |
| 9681 | Stream.runForEach((event) => Queue.offer(events, event)), | 9688 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9682 | Effect.forkScoped, | 9689 | Effect.forkScoped, |
| ... | @@ -9696,7 +9703,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9696,7 +9703,7 @@ describe("AcpAdapterV2", () => { |
| 9696 | }); | 9703 | }); |
| 9697 | 9704 | ||
| 9698 | let reportSeen = false; | 9705 | let reportSeen = false; |
| 9699 | const trackReport = (event: ProviderAdapterV2Event): void => { | 9706 | const trackReport = (event: ProviderAdapter.ProviderAdapterV2Event): void => { |
| 9700 | if ( | 9707 | if ( |
| 9701 | event.type === "turn_item.updated" && | 9708 | event.type === "turn_item.updated" && |
| 9702 | event.turnItem.type === "assistant_message" && | 9709 | event.turnItem.type === "assistant_message" && |
| ... | @@ -9799,7 +9806,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -9799,7 +9806,8 @@ describe("AcpAdapterV2", () => { |
| 9799 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 9806 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 9800 | ); | 9807 | ); |
| 9801 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 9808 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 9802 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9809 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9810 | []; | ||
| 9803 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 9811 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 9804 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 9812 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 9805 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 9813 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -9854,7 +9862,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9854,7 +9862,7 @@ describe("AcpAdapterV2", () => { |
| 9854 | }, | 9862 | }, |
| 9855 | }); | 9863 | }); |
| 9856 | const threadId = ThreadId.make("thread-acp-pre-settle-arm-cleared-by-report"); | 9864 | const threadId = ThreadId.make("thread-acp-pre-settle-arm-cleared-by-report"); |
| 9857 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 9865 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 9858 | runtimeMode: "full-access", | 9866 | runtimeMode: "full-access", |
| 9859 | interactionMode: "default", | 9867 | interactionMode: "default", |
| 9860 | cwd: process.cwd(), | 9868 | cwd: process.cwd(), |
| ... | @@ -9868,7 +9876,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9868,7 +9876,7 @@ describe("AcpAdapterV2", () => { |
| 9868 | modelSelection, | 9876 | modelSelection, |
| 9869 | runtimePolicy, | 9877 | runtimePolicy, |
| 9870 | }); | 9878 | }); |
| 9871 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 9879 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 9872 | yield* runtime.events.pipe( | 9880 | yield* runtime.events.pipe( |
| 9873 | Stream.runForEach((event) => Queue.offer(events, event)), | 9881 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 9874 | Effect.forkScoped, | 9882 | Effect.forkScoped, |
| ... | @@ -9965,7 +9973,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -9965,7 +9973,7 @@ describe("AcpAdapterV2", () => { |
| 9965 | yield* Effect.yieldNow; | 9973 | yield* Effect.yieldNow; |
| 9966 | 9974 | ||
| 9967 | let reportSeen = false; | 9975 | let reportSeen = false; |
| 9968 | const trackReport = (event: ProviderAdapterV2Event): void => { | 9976 | const trackReport = (event: ProviderAdapter.ProviderAdapterV2Event): void => { |
| 9969 | if ( | 9977 | if ( |
| 9970 | event.type === "turn_item.updated" && | 9978 | event.type === "turn_item.updated" && |
| 9971 | event.turnItem.type === "assistant_message" && | 9979 | event.turnItem.type === "assistant_message" && |
| ... | @@ -10033,7 +10041,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -10033,7 +10041,8 @@ describe("AcpAdapterV2", () => { |
| 10033 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 10041 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 10034 | ); | 10042 | ); |
| 10035 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 10043 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 10036 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 10044 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 10045 | []; | ||
| 10037 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 10046 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 10038 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 10047 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 10039 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 10048 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -10095,7 +10104,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10095,7 +10104,7 @@ describe("AcpAdapterV2", () => { |
| 10095 | }, | 10104 | }, |
| 10096 | }); | 10105 | }); |
| 10097 | const threadId = ThreadId.make("thread-acp-staggered-midturn-keep-until-last"); | 10106 | const threadId = ThreadId.make("thread-acp-staggered-midturn-keep-until-last"); |
| 10098 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 10107 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 10099 | runtimeMode: "full-access", | 10108 | runtimeMode: "full-access", |
| 10100 | interactionMode: "default", | 10109 | interactionMode: "default", |
| 10101 | cwd: process.cwd(), | 10110 | cwd: process.cwd(), |
| ... | @@ -10109,7 +10118,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10109,7 +10118,7 @@ describe("AcpAdapterV2", () => { |
| 10109 | modelSelection, | 10118 | modelSelection, |
| 10110 | runtimePolicy, | 10119 | runtimePolicy, |
| 10111 | }); | 10120 | }); |
| 10112 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 10121 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 10113 | yield* runtime.events.pipe( | 10122 | yield* runtime.events.pipe( |
| 10114 | Stream.runForEach((event) => Queue.offer(events, event)), | 10123 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 10115 | Effect.forkScoped, | 10124 | Effect.forkScoped, |
| ... | @@ -10246,7 +10255,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -10246,7 +10255,8 @@ describe("AcpAdapterV2", () => { |
| 10246 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 10255 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 10247 | ); | 10256 | ); |
| 10248 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 10257 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 10249 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 10258 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 10259 | []; | ||
| 10250 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 10260 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 10251 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 10261 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 10252 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 10262 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -10312,7 +10322,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10312,7 +10322,7 @@ describe("AcpAdapterV2", () => { |
| 10312 | }, | 10322 | }, |
| 10313 | }); | 10323 | }); |
| 10314 | const threadId = ThreadId.make("thread-acp-staggered-midturn-clear-on-interrupt"); | 10324 | const threadId = ThreadId.make("thread-acp-staggered-midturn-clear-on-interrupt"); |
| 10315 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 10325 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 10316 | runtimeMode: "full-access", | 10326 | runtimeMode: "full-access", |
| 10317 | interactionMode: "default", | 10327 | interactionMode: "default", |
| 10318 | cwd: process.cwd(), | 10328 | cwd: process.cwd(), |
| ... | @@ -10326,7 +10336,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10326,7 +10336,7 @@ describe("AcpAdapterV2", () => { |
| 10326 | modelSelection, | 10336 | modelSelection, |
| 10327 | runtimePolicy, | 10337 | runtimePolicy, |
| 10328 | }); | 10338 | }); |
| 10329 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 10339 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 10330 | yield* runtime.events.pipe( | 10340 | yield* runtime.events.pipe( |
| 10331 | Stream.runForEach((event) => Queue.offer(events, event)), | 10341 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 10332 | Effect.forkScoped, | 10342 | Effect.forkScoped, |
| ... | @@ -10455,7 +10465,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -10455,7 +10465,8 @@ describe("AcpAdapterV2", () => { |
| 10455 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 10465 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 10456 | ); | 10466 | ); |
| 10457 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 10467 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 10458 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 10468 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 10469 | []; | ||
| 10459 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 10470 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 10460 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 10471 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 10461 | const promptGates: Array<Deferred.Deferred<EffectAcpSchema.PromptResponse, never>> = []; | 10472 | const promptGates: Array<Deferred.Deferred<EffectAcpSchema.PromptResponse, never>> = []; |
| ... | @@ -10543,7 +10554,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10543,7 +10554,7 @@ describe("AcpAdapterV2", () => { |
| 10543 | }, | 10554 | }, |
| 10544 | }); | 10555 | }); |
| 10545 | const threadId = ThreadId.make("thread-acp-multiturn-in-turn-monitor-no-wake"); | 10556 | const threadId = ThreadId.make("thread-acp-multiturn-in-turn-monitor-no-wake"); |
| 10546 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 10557 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 10547 | runtimeMode: "full-access", | 10558 | runtimeMode: "full-access", |
| 10548 | interactionMode: "default", | 10559 | interactionMode: "default", |
| 10549 | cwd: process.cwd(), | 10560 | cwd: process.cwd(), |
| ... | @@ -10563,7 +10574,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10563,7 +10574,7 @@ describe("AcpAdapterV2", () => { |
| 10563 | ); | 10574 | ); |
| 10564 | } | 10575 | } |
| 10565 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 10576 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 10566 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 10577 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 10567 | yield* runtime.events.pipe( | 10578 | yield* runtime.events.pipe( |
| 10568 | Stream.runForEach((event) => Queue.offer(events, event)), | 10579 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 10569 | Effect.forkScoped, | 10580 | Effect.forkScoped, |
| ... | @@ -10820,7 +10831,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -10820,7 +10831,8 @@ describe("AcpAdapterV2", () => { |
| 10820 | const mockAgentPath = yield* path.fromFileUrl( | 10831 | const mockAgentPath = yield* path.fromFileUrl( |
| 10821 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 10832 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 10822 | ); | 10833 | ); |
| 10823 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 10834 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 10835 | []; | ||
| 10824 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 10836 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 10825 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 10837 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 10826 | let applyMutation: AcpAdapterV2ExtensionContext["applyBackgroundTaskMutation"] | undefined; | 10838 | let applyMutation: AcpAdapterV2ExtensionContext["applyBackgroundTaskMutation"] | undefined; |
| ... | @@ -10860,7 +10872,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10860,7 +10872,7 @@ describe("AcpAdapterV2", () => { |
| 10860 | }, | 10872 | }, |
| 10861 | }); | 10873 | }); |
| 10862 | const threadId = ThreadId.make("thread-acp-wake-report-while-queued"); | 10874 | const threadId = ThreadId.make("thread-acp-wake-report-while-queued"); |
| 10863 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 10875 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 10864 | runtimeMode: "full-access", | 10876 | runtimeMode: "full-access", |
| 10865 | interactionMode: "default", | 10877 | interactionMode: "default", |
| 10866 | cwd: process.cwd(), | 10878 | cwd: process.cwd(), |
| ... | @@ -10872,7 +10884,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -10872,7 +10884,7 @@ describe("AcpAdapterV2", () => { |
| 10872 | modelSelection, | 10884 | modelSelection, |
| 10873 | runtimePolicy, | 10885 | runtimePolicy, |
| 10874 | }); | 10886 | }); |
| 10875 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 10887 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 10876 | yield* runtime.events.pipe( | 10888 | yield* runtime.events.pipe( |
| 10877 | Stream.runForEach((event) => Queue.offer(events, event)), | 10889 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 10878 | Effect.forkScoped, | 10890 | Effect.forkScoped, |
| ... | @@ -10969,7 +10981,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -10969,7 +10981,8 @@ describe("AcpAdapterV2", () => { |
| 10969 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 10981 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 10970 | ); | 10982 | ); |
| 10971 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 10983 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 10972 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 10984 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 10985 | []; | ||
| 10973 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 10986 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 10974 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 10987 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 10975 | const promptGates: Array<Deferred.Deferred<EffectAcpSchema.PromptResponse, never>> = []; | 10988 | const promptGates: Array<Deferred.Deferred<EffectAcpSchema.PromptResponse, never>> = []; |
| ... | @@ -11038,7 +11051,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11038,7 +11051,7 @@ describe("AcpAdapterV2", () => { |
| 11038 | }, | 11051 | }, |
| 11039 | }); | 11052 | }); |
| 11040 | const threadId = ThreadId.make("thread-acp-mid-turn-dirty-wake-buffer"); | 11053 | const threadId = ThreadId.make("thread-acp-mid-turn-dirty-wake-buffer"); |
| 11041 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 11054 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 11042 | runtimeMode: "full-access", | 11055 | runtimeMode: "full-access", |
| 11043 | interactionMode: "default", | 11056 | interactionMode: "default", |
| 11044 | cwd: process.cwd(), | 11057 | cwd: process.cwd(), |
| ... | @@ -11058,7 +11071,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11058,7 +11071,7 @@ describe("AcpAdapterV2", () => { |
| 11058 | ); | 11071 | ); |
| 11059 | } | 11072 | } |
| 11060 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 11073 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 11061 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 11074 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 11062 | yield* runtime.events.pipe( | 11075 | yield* runtime.events.pipe( |
| 11063 | Stream.runForEach((event) => Queue.offer(events, event)), | 11076 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 11064 | Effect.forkScoped, | 11077 | Effect.forkScoped, |
| ... | @@ -11294,7 +11307,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -11294,7 +11307,8 @@ describe("AcpAdapterV2", () => { |
| 11294 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 11307 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 11295 | ); | 11308 | ); |
| 11296 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 11309 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 11297 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 11310 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 11311 | []; | ||
| 11298 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 11312 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 11299 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 11313 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 11300 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 11314 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -11344,7 +11358,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11344,7 +11358,7 @@ describe("AcpAdapterV2", () => { |
| 11344 | }, | 11358 | }, |
| 11345 | }); | 11359 | }); |
| 11346 | const threadId = ThreadId.make("thread-acp-mid-turn-unhandled-offers-after-finalize"); | 11360 | const threadId = ThreadId.make("thread-acp-mid-turn-unhandled-offers-after-finalize"); |
| 11347 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 11361 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 11348 | runtimeMode: "full-access", | 11362 | runtimeMode: "full-access", |
| 11349 | interactionMode: "default", | 11363 | interactionMode: "default", |
| 11350 | cwd: process.cwd(), | 11364 | cwd: process.cwd(), |
| ... | @@ -11358,7 +11372,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11358,7 +11372,7 @@ describe("AcpAdapterV2", () => { |
| 11358 | modelSelection, | 11372 | modelSelection, |
| 11359 | runtimePolicy, | 11373 | runtimePolicy, |
| 11360 | }); | 11374 | }); |
| 11361 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 11375 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 11362 | yield* runtime.events.pipe( | 11376 | yield* runtime.events.pipe( |
| 11363 | Stream.runForEach((event) => Queue.offer(events, event)), | 11377 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 11364 | Effect.forkScoped, | 11378 | Effect.forkScoped, |
| ... | @@ -11446,7 +11460,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11446,7 +11460,7 @@ describe("AcpAdapterV2", () => { |
| 11446 | content: { type: "text", text: " \n\t " }, | 11460 | content: { type: "text", text: " \n\t " }, |
| 11447 | }, | 11461 | }, |
| 11448 | }); | 11462 | }); |
| 11449 | const lateEvents: Array<ProviderAdapterV2Event> = []; | 11463 | const lateEvents: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 11450 | let lateEvent = yield* Queue.poll(events); | 11464 | let lateEvent = yield* Queue.poll(events); |
| 11451 | while (Option.isSome(lateEvent)) { | 11465 | while (Option.isSome(lateEvent)) { |
| 11452 | lateEvents.push(lateEvent.value); | 11466 | lateEvents.push(lateEvent.value); |
| ... | @@ -11475,7 +11489,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -11475,7 +11489,8 @@ describe("AcpAdapterV2", () => { |
| 11475 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 11489 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 11476 | ); | 11490 | ); |
| 11477 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 11491 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 11478 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 11492 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 11493 | []; | ||
| 11479 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 11494 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 11480 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 11495 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 11481 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 11496 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -11529,7 +11544,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11529,7 +11544,7 @@ describe("AcpAdapterV2", () => { |
| 11529 | }, | 11544 | }, |
| 11530 | }); | 11545 | }); |
| 11531 | const threadId = ThreadId.make("thread-acp-empty-drain-continuation-quiet"); | 11546 | const threadId = ThreadId.make("thread-acp-empty-drain-continuation-quiet"); |
| 11532 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 11547 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 11533 | runtimeMode: "full-access", | 11548 | runtimeMode: "full-access", |
| 11534 | interactionMode: "default", | 11549 | interactionMode: "default", |
| 11535 | cwd: process.cwd(), | 11550 | cwd: process.cwd(), |
| ... | @@ -11543,7 +11558,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11543,7 +11558,7 @@ describe("AcpAdapterV2", () => { |
| 11543 | modelSelection, | 11558 | modelSelection, |
| 11544 | runtimePolicy, | 11559 | runtimePolicy, |
| 11545 | }); | 11560 | }); |
| 11546 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 11561 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 11547 | yield* runtime.events.pipe( | 11562 | yield* runtime.events.pipe( |
| 11548 | Stream.runForEach((event) => Queue.offer(events, event)), | 11563 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 11549 | Effect.forkScoped, | 11564 | Effect.forkScoped, |
| ... | @@ -11713,7 +11728,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -11713,7 +11728,8 @@ describe("AcpAdapterV2", () => { |
| 11713 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 11728 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 11714 | ); | 11729 | ); |
| 11715 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 11730 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 11716 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 11731 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 11732 | []; | ||
| 11717 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 11733 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 11718 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; | 11734 | let sessionUpdateHandler: Parameters<RuntimeService["handleSessionUpdate"]>[0] | undefined; |
| 11719 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); | 11735 | const promptGate = yield* Deferred.make<EffectAcpSchema.PromptResponse>(); |
| ... | @@ -11765,7 +11781,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11765,7 +11781,7 @@ describe("AcpAdapterV2", () => { |
| 11765 | }, | 11781 | }, |
| 11766 | }); | 11782 | }); |
| 11767 | const threadId = ThreadId.make("thread-acp-empty-drain-continuation-no-wedge"); | 11783 | const threadId = ThreadId.make("thread-acp-empty-drain-continuation-no-wedge"); |
| 11768 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 11784 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 11769 | runtimeMode: "full-access", | 11785 | runtimeMode: "full-access", |
| 11770 | interactionMode: "default", | 11786 | interactionMode: "default", |
| 11771 | cwd: process.cwd(), | 11787 | cwd: process.cwd(), |
| ... | @@ -11779,7 +11795,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11779,7 +11795,7 @@ describe("AcpAdapterV2", () => { |
| 11779 | modelSelection, | 11795 | modelSelection, |
| 11780 | runtimePolicy, | 11796 | runtimePolicy, |
| 11781 | }); | 11797 | }); |
| 11782 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 11798 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 11783 | yield* runtime.events.pipe( | 11799 | yield* runtime.events.pipe( |
| 11784 | Stream.runForEach((event) => Queue.offer(events, event)), | 11800 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 11785 | Effect.forkScoped, | 11801 | Effect.forkScoped, |
| ... | @@ -11913,7 +11929,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -11913,7 +11929,7 @@ describe("AcpAdapterV2", () => { |
| 11913 | selfInvocation, | 11929 | selfInvocation, |
| 11914 | }); | 11930 | }); |
| 11915 | const threadId = ThreadId.make("thread-acp-restart-after-interrupt"); | 11931 | const threadId = ThreadId.make("thread-acp-restart-after-interrupt"); |
| 11916 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 11932 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 11917 | runtimeMode: "full-access", | 11933 | runtimeMode: "full-access", |
| 11918 | interactionMode: "default", | 11934 | interactionMode: "default", |
| 11919 | cwd: process.cwd(), | 11935 | cwd: process.cwd(), |
| ... | @@ -12144,7 +12160,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -12144,7 +12160,8 @@ describe("AcpAdapterV2", () => { |
| 12144 | const residualCallbackResponseLogPath = path.join(residualCallbackDir, "responses.log"); | 12160 | const residualCallbackResponseLogPath = path.join(residualCallbackDir, "responses.log"); |
| 12145 | const residualCallbackTriggerPath = path.join(residualCallbackDir, "trigger"); | 12161 | const residualCallbackTriggerPath = path.join(residualCallbackDir, "trigger"); |
| 12146 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 12162 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 12147 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 12163 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 12164 | []; | ||
| 12148 | const teardownStarted = yield* Deferred.make<void>(); | 12165 | const teardownStarted = yield* Deferred.make<void>(); |
| 12149 | const releaseTeardown = yield* Deferred.make<void>(); | 12166 | const releaseTeardown = yield* Deferred.make<void>(); |
| 12150 | let terminatorCallCount = 0; | 12167 | let terminatorCallCount = 0; |
| ... | @@ -12187,7 +12204,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12187,7 +12204,7 @@ describe("AcpAdapterV2", () => { |
| 12187 | }, | 12204 | }, |
| 12188 | }); | 12205 | }); |
| 12189 | const threadId = ThreadId.make("thread-acp-failed-hard-teardown"); | 12206 | const threadId = ThreadId.make("thread-acp-failed-hard-teardown"); |
| 12190 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 12207 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 12191 | runtimeMode: "full-access", | 12208 | runtimeMode: "full-access", |
| 12192 | interactionMode: "default", | 12209 | interactionMode: "default", |
| 12193 | cwd: process.cwd(), | 12210 | cwd: process.cwd(), |
| ... | @@ -12202,7 +12219,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12202,7 +12219,7 @@ describe("AcpAdapterV2", () => { |
| 12202 | runtimePolicy, | 12219 | runtimePolicy, |
| 12203 | }) | 12220 | }) |
| 12204 | .pipe(Effect.provideService(Scope.Scope, sessionScope)); | 12221 | .pipe(Effect.provideService(Scope.Scope, sessionScope)); |
| 12205 | const adapterEvents = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 12222 | const adapterEvents = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 12206 | yield* runtime.events.pipe( | 12223 | yield* runtime.events.pipe( |
| 12207 | Stream.runForEach((event) => Queue.offer(adapterEvents, event)), | 12224 | Stream.runForEach((event) => Queue.offer(adapterEvents, event)), |
| 12208 | Effect.forkIn(sessionScope), | 12225 | Effect.forkIn(sessionScope), |
| ... | @@ -12368,7 +12385,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12368,7 +12385,7 @@ describe("AcpAdapterV2", () => { |
| 12368 | selfInvocation, | 12385 | selfInvocation, |
| 12369 | }); | 12386 | }); |
| 12370 | const threadId = ThreadId.make("thread-acp-missing-hard-teardown"); | 12387 | const threadId = ThreadId.make("thread-acp-missing-hard-teardown"); |
| 12371 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 12388 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 12372 | runtimeMode: "full-access", | 12389 | runtimeMode: "full-access", |
| 12373 | interactionMode: "default", | 12390 | interactionMode: "default", |
| 12374 | cwd: process.cwd(), | 12391 | cwd: process.cwd(), |
| ... | @@ -12464,7 +12481,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12464,7 +12481,7 @@ describe("AcpAdapterV2", () => { |
| 12464 | selfInvocation, | 12481 | selfInvocation, |
| 12465 | }); | 12482 | }); |
| 12466 | const threadId = ThreadId.make("thread-acp-concurrent-hard-teardown"); | 12483 | const threadId = ThreadId.make("thread-acp-concurrent-hard-teardown"); |
| 12467 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 12484 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 12468 | runtimeMode: "full-access", | 12485 | runtimeMode: "full-access", |
| 12469 | interactionMode: "default", | 12486 | interactionMode: "default", |
| 12470 | cwd: process.cwd(), | 12487 | cwd: process.cwd(), |
| ... | @@ -12540,7 +12557,8 @@ describe("AcpAdapterV2", () => { | ... | @@ -12540,7 +12557,8 @@ describe("AcpAdapterV2", () => { |
| 12540 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), | 12557 | new URL("../../../scripts/acp-mock-agent.ts", import.meta.url), |
| 12541 | ); | 12558 | ); |
| 12542 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); | 12559 | const protocolEvents = yield* Queue.bounded<EffectAcpProtocol.AcpProtocolLogEvent>(256); |
| 12543 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 12560 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 12561 | []; | ||
| 12544 | const responseLifecycle: Array<string> = []; | 12562 | const responseLifecycle: Array<string> = []; |
| 12545 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; | 12563 | type RuntimeService = AcpSessionRuntime.AcpSessionRuntime["Service"]; |
| 12546 | type HandlerRecord = { | 12564 | type HandlerRecord = { |
| ... | @@ -12633,7 +12651,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12633,7 +12651,7 @@ describe("AcpAdapterV2", () => { |
| 12633 | }, | 12651 | }, |
| 12634 | }); | 12652 | }); |
| 12635 | const threadId = ThreadId.make("thread-acp-successful-teardown-callback-quarantine"); | 12653 | const threadId = ThreadId.make("thread-acp-successful-teardown-callback-quarantine"); |
| 12636 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 12654 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 12637 | runtimeMode: "full-access", | 12655 | runtimeMode: "full-access", |
| 12638 | interactionMode: "default", | 12656 | interactionMode: "default", |
| 12639 | cwd: process.cwd(), | 12657 | cwd: process.cwd(), |
| ... | @@ -12647,7 +12665,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12647,7 +12665,7 @@ describe("AcpAdapterV2", () => { |
| 12647 | modelSelection, | 12665 | modelSelection, |
| 12648 | runtimePolicy, | 12666 | runtimePolicy, |
| 12649 | }); | 12667 | }); |
| 12650 | const adapterEvents = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 12668 | const adapterEvents = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 12651 | yield* runtime.events.pipe( | 12669 | yield* runtime.events.pipe( |
| 12652 | Stream.runForEach((event) => Queue.offer(adapterEvents, event)), | 12670 | Stream.runForEach((event) => Queue.offer(adapterEvents, event)), |
| 12653 | Effect.forkScoped, | 12671 | Effect.forkScoped, |
| ... | @@ -12849,7 +12867,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12849,7 +12867,7 @@ describe("AcpAdapterV2", () => { |
| 12849 | method: "_x.ai/ask_user_question", | 12867 | method: "_x.ai/ask_user_question", |
| 12850 | }, | 12868 | }, |
| 12851 | ).pipe(Effect.forkScoped); | 12869 | ).pipe(Effect.forkScoped); |
| 12852 | let replacementRequest: ProviderAdapterV2Event | undefined; | 12870 | let replacementRequest: ProviderAdapter.ProviderAdapterV2Event | undefined; |
| 12853 | while (replacementRequest === undefined) { | 12871 | while (replacementRequest === undefined) { |
| 12854 | const event = yield* Queue.take(adapterEvents); | 12872 | const event = yield* Queue.take(adapterEvents); |
| 12855 | if (event.type === "runtime_request.updated" && event.runtimeRequest.status === "pending") { | 12873 | if (event.type === "runtime_request.updated" && event.runtimeRequest.status === "pending") { |
| ... | @@ -12916,7 +12934,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12916,7 +12934,7 @@ describe("AcpAdapterV2", () => { |
| 12916 | selfInvocation, | 12934 | selfInvocation, |
| 12917 | }); | 12935 | }); |
| 12918 | const threadId = ThreadId.make("thread-acp-stale-deferred-cleanup"); | 12936 | const threadId = ThreadId.make("thread-acp-stale-deferred-cleanup"); |
| 12919 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 12937 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 12920 | runtimeMode: "approval-required", | 12938 | runtimeMode: "approval-required", |
| 12921 | interactionMode: "default", | 12939 | interactionMode: "default", |
| 12922 | cwd: process.cwd(), | 12940 | cwd: process.cwd(), |
| ... | @@ -12928,7 +12946,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12928,7 +12946,7 @@ describe("AcpAdapterV2", () => { |
| 12928 | modelSelection, | 12946 | modelSelection, |
| 12929 | runtimePolicy, | 12947 | runtimePolicy, |
| 12930 | }); | 12948 | }); |
| 12931 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 12949 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 12932 | yield* runtime.events.pipe( | 12950 | yield* runtime.events.pipe( |
| 12933 | Stream.runForEach((event) => Queue.offer(events, event)), | 12951 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 12934 | Effect.forkScoped, | 12952 | Effect.forkScoped, |
| ... | @@ -12975,7 +12993,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -12975,7 +12993,7 @@ describe("AcpAdapterV2", () => { |
| 12975 | yield* runtime.startTurn( | 12993 | yield* runtime.startTurn( |
| 12976 | makeTurnInput({ threadId, providerThread, instanceId, runtimePolicy, now, ordinal: 2 }), | 12994 | makeTurnInput({ threadId, providerThread, instanceId, runtimePolicy, now, ordinal: 2 }), |
| 12977 | ); | 12995 | ); |
| 12978 | let replacementPending: ProviderAdapterV2Event | undefined; | 12996 | let replacementPending: ProviderAdapter.ProviderAdapterV2Event | undefined; |
| 12979 | while (replacementPending === undefined) { | 12997 | while (replacementPending === undefined) { |
| 12980 | const event = yield* Queue.take(events); | 12998 | const event = yield* Queue.take(events); |
| 12981 | if (event.type === "runtime_request.updated" && event.runtimeRequest.status === "pending") { | 12999 | if (event.type === "runtime_request.updated" && event.runtimeRequest.status === "pending") { |
| ... | @@ -13045,7 +13063,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13045,7 +13063,7 @@ describe("AcpAdapterV2", () => { |
| 13045 | selfInvocation, | 13063 | selfInvocation, |
| 13046 | }); | 13064 | }); |
| 13047 | const threadId = ThreadId.make("thread-acp-concurrent-resume-teardown"); | 13065 | const threadId = ThreadId.make("thread-acp-concurrent-resume-teardown"); |
| 13048 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 13066 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 13049 | runtimeMode: "full-access", | 13067 | runtimeMode: "full-access", |
| 13050 | interactionMode: "default", | 13068 | interactionMode: "default", |
| 13051 | cwd: process.cwd(), | 13069 | cwd: process.cwd(), |
| ... | @@ -13192,7 +13210,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13192,7 +13210,7 @@ describe("AcpAdapterV2", () => { |
| 13192 | continuationRequests: { offer: () => Effect.void }, | 13210 | continuationRequests: { offer: () => Effect.void }, |
| 13193 | }); | 13211 | }); |
| 13194 | const threadId = ThreadId.make("thread-acp-direct-stop-running-command"); | 13212 | const threadId = ThreadId.make("thread-acp-direct-stop-running-command"); |
| 13195 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 13213 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 13196 | runtimeMode: "full-access", | 13214 | runtimeMode: "full-access", |
| 13197 | interactionMode: "default", | 13215 | interactionMode: "default", |
| 13198 | cwd: process.cwd(), | 13216 | cwd: process.cwd(), |
| ... | @@ -13206,7 +13224,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13206,7 +13224,7 @@ describe("AcpAdapterV2", () => { |
| 13206 | modelSelection, | 13224 | modelSelection, |
| 13207 | runtimePolicy, | 13225 | runtimePolicy, |
| 13208 | }); | 13226 | }); |
| 13209 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 13227 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 13210 | yield* runtime.events.pipe( | 13228 | yield* runtime.events.pipe( |
| 13211 | Stream.runForEach((event) => Queue.offer(events, event)), | 13229 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 13212 | Effect.forkScoped, | 13230 | Effect.forkScoped, |
| ... | @@ -13458,7 +13476,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13458,7 +13476,7 @@ describe("AcpAdapterV2", () => { |
| 13458 | selfInvocation, | 13476 | selfInvocation, |
| 13459 | }); | 13477 | }); |
| 13460 | const threadId = ThreadId.make("thread-acp-direct-stop-subagent-hold"); | 13478 | const threadId = ThreadId.make("thread-acp-direct-stop-subagent-hold"); |
| 13461 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 13479 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 13462 | runtimeMode: "full-access", | 13480 | runtimeMode: "full-access", |
| 13463 | interactionMode: "default", | 13481 | interactionMode: "default", |
| 13464 | cwd: process.cwd(), | 13482 | cwd: process.cwd(), |
| ... | @@ -13472,7 +13490,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13472,7 +13490,7 @@ describe("AcpAdapterV2", () => { |
| 13472 | modelSelection, | 13490 | modelSelection, |
| 13473 | runtimePolicy, | 13491 | runtimePolicy, |
| 13474 | }); | 13492 | }); |
| 13475 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 13493 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 13476 | yield* runtime.events.pipe( | 13494 | yield* runtime.events.pipe( |
| 13477 | Stream.runForEach((event) => Queue.offer(events, event)), | 13495 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 13478 | Effect.forkScoped, | 13496 | Effect.forkScoped, |
| ... | @@ -13602,7 +13620,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13602,7 +13620,7 @@ describe("AcpAdapterV2", () => { |
| 13602 | selfInvocation, | 13620 | selfInvocation, |
| 13603 | }); | 13621 | }); |
| 13604 | const threadId = ThreadId.make("thread-acp-restart-active-in-process"); | 13622 | const threadId = ThreadId.make("thread-acp-restart-active-in-process"); |
| 13605 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 13623 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 13606 | runtimeMode: "full-access", | 13624 | runtimeMode: "full-access", |
| 13607 | interactionMode: "default", | 13625 | interactionMode: "default", |
| 13608 | cwd: process.cwd(), | 13626 | cwd: process.cwd(), |
| ... | @@ -13614,7 +13632,7 @@ describe("AcpAdapterV2", () => { | ... | @@ -13614,7 +13632,7 @@ describe("AcpAdapterV2", () => { |
| 13614 | modelSelection, | 13632 | modelSelection, |
| 13615 | runtimePolicy, | 13633 | runtimePolicy, |
| 13616 | }); | 13634 | }); |
| 13617 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 13635 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 13618 | yield* runtime.events.pipe( | 13636 | yield* runtime.events.pipe( |
| 13619 | Stream.runForEach((event) => Queue.offer(events, event)), | 13637 | Stream.runForEach((event) => Queue.offer(events, event)), |
| 13620 | Effect.forkScoped, | 13638 | Effect.forkScoped, |
apps/server/src/orchestration-v2/Adapters/AcpRegistryAdapterV2.test.ts+4-4| ... | @@ -29,7 +29,7 @@ import { | ... | @@ -29,7 +29,7 @@ import { |
| 29 | makeAcpReplayCompletenessAssertion, | 29 | makeAcpReplayCompletenessAssertion, |
| 30 | makeAcpReplayRuntime, | 30 | makeAcpReplayRuntime, |
| 31 | } from "./AcpAdapterV2.testkit.ts"; | 31 | } from "./AcpAdapterV2.testkit.ts"; |
| 32 | import { ProviderAdapterV2RuntimePolicy } from "@t3tools/provider-core/server/ProviderAdapter"; | 32 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 33 | import { BUILT_IN_PROVIDER_ADAPTER_DRIVER_KINDS_V2 } from "../builtInProviderAdapterDrivers.ts"; | 33 | import { BUILT_IN_PROVIDER_ADAPTER_DRIVER_KINDS_V2 } from "../builtInProviderAdapterDrivers.ts"; |
| 34 | import { AcpRegistryAdapterV2Driver } from "@t3tools/provider-acp-registry/server"; | 34 | import { AcpRegistryAdapterV2Driver } from "@t3tools/provider-acp-registry/server"; |
| 35 | import { | 35 | import { |
| ... | @@ -216,7 +216,7 @@ describe("AcpRegistryAdapterV2", () => { | ... | @@ -216,7 +216,7 @@ describe("AcpRegistryAdapterV2", () => { |
| 216 | model: "default", | 216 | model: "default", |
| 217 | options: [{ id: ACP_SESSION_MODE_OPTION_ID, value: input.storedModePick }], | 217 | options: [{ id: ACP_SESSION_MODE_OPTION_ID, value: input.storedModePick }], |
| 218 | }, | 218 | }, |
| 219 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 219 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 220 | runtimeMode: "approval-required", | 220 | runtimeMode: "approval-required", |
| 221 | interactionMode: "default", | 221 | interactionMode: "default", |
| 222 | cwd: replayDir, | 222 | cwd: replayDir, |
| ... | @@ -304,7 +304,7 @@ describe("AcpRegistryAdapterV2", () => { | ... | @@ -304,7 +304,7 @@ describe("AcpRegistryAdapterV2", () => { |
| 304 | ); | 304 | ); |
| 305 | }), | 305 | }), |
| 306 | }); | 306 | }); |
| 307 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 307 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 308 | runtimeMode: "full-access", | 308 | runtimeMode: "full-access", |
| 309 | interactionMode: "default", | 309 | interactionMode: "default", |
| 310 | cwd: process.cwd(), | 310 | cwd: process.cwd(), |
| ... | @@ -413,7 +413,7 @@ describe("AcpRegistryAdapterV2", () => { | ... | @@ -413,7 +413,7 @@ describe("AcpRegistryAdapterV2", () => { |
| 413 | }, | 413 | }, |
| 414 | }); | 414 | }); |
| 415 | const threadId = ThreadId.make("thread-acp-registry-fixture"); | 415 | const threadId = ThreadId.make("thread-acp-registry-fixture"); |
| 416 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 416 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 417 | runtimeMode: "full-access", | 417 | runtimeMode: "full-access", |
| 418 | interactionMode: "default", | 418 | interactionMode: "default", |
| 419 | cwd: process.cwd(), | 419 | cwd: process.cwd(), |
apps/server/src/orchestration-v2/Adapters/AntigravityAdapterV2.test.ts+5-5| ... | @@ -27,7 +27,7 @@ import { layerTestProviderHost } from "@t3tools/provider-testing/host"; | ... | @@ -27,7 +27,7 @@ import { layerTestProviderHost } from "@t3tools/provider-testing/host"; |
| 27 | import type * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime"; | 27 | import type * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime"; |
| 28 | import { makeAntigravityAcpRuntime } from "../../provider/acp/AntigravityAcpSupport.ts"; | 28 | import { makeAntigravityAcpRuntime } from "../../provider/acp/AntigravityAcpSupport.ts"; |
| 29 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 29 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 30 | import { ProviderAdapterV2RuntimePolicy } from "@t3tools/provider-core/server/ProviderAdapter"; | 30 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 31 | import { | 31 | import { |
| 32 | makeAntigravityAcpAdapterFlavor, | 32 | makeAntigravityAcpAdapterFlavor, |
| 33 | makeAntigravityAdapterV2, | 33 | makeAntigravityAdapterV2, |
| ... | @@ -74,7 +74,7 @@ describe("AntigravityAdapterV2 flavor", () => { | ... | @@ -74,7 +74,7 @@ describe("AntigravityAdapterV2 flavor", () => { |
| 74 | it("maps runtime modes to the agent's native permission modes", () => { | 74 | it("maps runtime modes to the agent's native permission modes", () => { |
| 75 | const mode = (runtimeMode: "approval-required" | "auto-accept-edits" | "full-access") => | 75 | const mode = (runtimeMode: "approval-required" | "auto-accept-edits" | "full-access") => |
| 76 | flavor.sessionModeForPolicy?.( | 76 | flavor.sessionModeForPolicy?.( |
| 77 | ProviderAdapterV2RuntimePolicy.make({ | 77 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 78 | runtimeMode, | 78 | runtimeMode, |
| 79 | interactionMode: "default", | 79 | interactionMode: "default", |
| 80 | cwd: "/workspace", | 80 | cwd: "/workspace", |
| ... | @@ -190,7 +190,7 @@ describe("AntigravityAdapterV2 client file system", () => { | ... | @@ -190,7 +190,7 @@ describe("AntigravityAdapterV2 client file system", () => { |
| 190 | yield* fileSystem.writeFileString(attachment, "pasted"); | 190 | yield* fileSystem.writeFileString(attachment, "pasted"); |
| 191 | 191 | ||
| 192 | const threadId = ThreadId.make("thread-antigravity-containment"); | 192 | const threadId = ThreadId.make("thread-antigravity-containment"); |
| 193 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 193 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 194 | runtimeMode: "full-access", | 194 | runtimeMode: "full-access", |
| 195 | interactionMode: "default", | 195 | interactionMode: "default", |
| 196 | cwd: workspace, | 196 | cwd: workspace, |
| ... | @@ -325,7 +325,7 @@ describe("AntigravityAdapterV2 workspace changes", () => { | ... | @@ -325,7 +325,7 @@ describe("AntigravityAdapterV2 workspace changes", () => { |
| 325 | yield* fileSystem.writeFileString(path.join(workspaceA, "a.txt"), "from a"); | 325 | yield* fileSystem.writeFileString(path.join(workspaceA, "a.txt"), "from a"); |
| 326 | yield* fileSystem.writeFileString(path.join(workspaceB, "b.txt"), "from b"); | 326 | yield* fileSystem.writeFileString(path.join(workspaceB, "b.txt"), "from b"); |
| 327 | const policyFor = (cwd: string) => | 327 | const policyFor = (cwd: string) => |
| 328 | ProviderAdapterV2RuntimePolicy.make({ | 328 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 329 | runtimeMode: "full-access", | 329 | runtimeMode: "full-access", |
| 330 | interactionMode: "default", | 330 | interactionMode: "default", |
| 331 | cwd, | 331 | cwd, |
| ... | @@ -476,7 +476,7 @@ describe("AntigravityAdapterV2 client file system under restrictive policies", ( | ... | @@ -476,7 +476,7 @@ describe("AntigravityAdapterV2 client file system under restrictive policies", ( |
| 476 | }); | 476 | }); |
| 477 | yield* fileSystem.writeFileString(path.join(workspace, "existing.ts"), "existing"); | 477 | yield* fileSystem.writeFileString(path.join(workspace, "existing.ts"), "existing"); |
| 478 | const threadId = ThreadId.make(`thread-antigravity-restrictive-${policy.runtimeMode}`); | 478 | const threadId = ThreadId.make(`thread-antigravity-restrictive-${policy.runtimeMode}`); |
| 479 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 479 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 480 | ...policy, | 480 | ...policy, |
| 481 | interactionMode: "default", | 481 | interactionMode: "default", |
| 482 | cwd: workspace, | 482 | cwd: workspace, |
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts+101-67| ... | @@ -61,13 +61,9 @@ import { WorktreeToolkit } from "../../mcp/toolkits/worktree/tools.ts"; | ... | @@ -61,13 +61,9 @@ import { WorktreeToolkit } from "../../mcp/toolkits/worktree/tools.ts"; |
| 61 | import { ThreadToolkit } from "../../mcp/toolkits/thread/tools.ts"; | 61 | import { ThreadToolkit } from "../../mcp/toolkits/thread/tools.ts"; |
| 62 | import { OrchestratorToolkit } from "../../mcp/toolkits/orchestrator/tools.ts"; | 62 | import { OrchestratorToolkit } from "../../mcp/toolkits/orchestrator/tools.ts"; |
| 63 | import { ClaudeExecutableFileCheck } from "../../provider/Drivers/ClaudeExecutable.ts"; | 63 | import { ClaudeExecutableFileCheck } from "../../provider/Drivers/ClaudeExecutable.ts"; |
| 64 | import type { EventNdjsonLogger } from "../../provider/EventNdjsonLogger.ts"; | 64 | import type * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 65 | import { | 65 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 66 | ProviderAdapterV2RuntimePolicy, | 66 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 67 | type ProviderAdapterV2Event, | ||
| 68 | type ProviderAdapterV2TurnInput, | ||
| 69 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 70 | import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | ||
| 71 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; | 67 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; |
| 72 | import * as ClaudeAdapterV2 from "./ClaudeAdapterV2.ts"; | 68 | import * as ClaudeAdapterV2 from "./ClaudeAdapterV2.ts"; |
| 73 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 69 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| ... | @@ -81,7 +77,7 @@ const CLAUDE_TEST_MODEL_SELECTION = { | ... | @@ -81,7 +77,7 @@ const CLAUDE_TEST_MODEL_SELECTION = { |
| 81 | model: "claude-sonnet-4-6", | 77 | model: "claude-sonnet-4-6", |
| 82 | options: [{ id: "effort", value: "ultrathink" }], | 78 | options: [{ id: "effort", value: "ultrathink" }], |
| 83 | } satisfies ModelSelection; | 79 | } satisfies ModelSelection; |
| 84 | const CLAUDE_TEST_RUNTIME_POLICY = ProviderAdapterV2RuntimePolicy.make({ | 80 | const CLAUDE_TEST_RUNTIME_POLICY = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 85 | runtimeMode: "full-access", | 81 | runtimeMode: "full-access", |
| 86 | interactionMode: "default", | 82 | interactionMode: "default", |
| 87 | cwd: "/workspace", | 83 | cwd: "/workspace", |
| ... | @@ -127,14 +123,14 @@ function makeClaudeTestTurnInput(input: { | ... | @@ -127,14 +123,14 @@ function makeClaudeTestTurnInput(input: { |
| 127 | readonly now: DateTime.Utc; | 123 | readonly now: DateTime.Utc; |
| 128 | readonly attemptId: RunAttemptId; | 124 | readonly attemptId: RunAttemptId; |
| 129 | readonly text: string; | 125 | readonly text: string; |
| 130 | readonly attachments: ProviderAdapterV2TurnInput["message"]["attachments"]; | 126 | readonly attachments: ProviderAdapter.ProviderAdapterV2TurnInput["message"]["attachments"]; |
| 131 | readonly providerTurnOrdinal?: number; | 127 | readonly providerTurnOrdinal?: number; |
| 132 | readonly nativeThreadHasTurns?: boolean; | 128 | readonly nativeThreadHasTurns?: boolean; |
| 133 | readonly messageCreatedBy?: ProviderAdapterV2TurnInput["message"]["createdBy"]; | 129 | readonly messageCreatedBy?: ProviderAdapter.ProviderAdapterV2TurnInput["message"]["createdBy"]; |
| 134 | readonly messageCreationSource?: ProviderAdapterV2TurnInput["message"]["creationSource"]; | 130 | readonly messageCreationSource?: ProviderAdapter.ProviderAdapterV2TurnInput["message"]["creationSource"]; |
| 135 | readonly modelSelection?: ModelSelection; | 131 | readonly modelSelection?: ModelSelection; |
| 136 | readonly runtimePolicy?: ProviderAdapterV2RuntimePolicy; | 132 | readonly runtimePolicy?: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 137 | }): ProviderAdapterV2TurnInput { | 133 | }): ProviderAdapter.ProviderAdapterV2TurnInput { |
| 138 | return { | 134 | return { |
| 139 | appThread: makeClaudeTestAppThread(input), | 135 | appThread: makeClaudeTestAppThread(input), |
| 140 | threadId: input.threadId, | 136 | threadId: input.threadId, |
| ... | @@ -298,7 +294,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -298,7 +294,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 298 | 294 | ||
| 299 | it("maps canonical read-only never policy to Claude dontAsk with read-only tools", () => { | 295 | it("maps canonical read-only never policy to Claude dontAsk with read-only tools", () => { |
| 300 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 296 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 301 | ProviderAdapterV2RuntimePolicy.make({ | 297 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 302 | runtimeMode: "full-access", | 298 | runtimeMode: "full-access", |
| 303 | interactionMode: "default", | 299 | interactionMode: "default", |
| 304 | cwd: "/workspace", | 300 | cwd: "/workspace", |
| ... | @@ -321,7 +317,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -321,7 +317,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 321 | 317 | ||
| 322 | it("maps canonical read-only on-request policy to Claude default with callbacks", () => { | 318 | it("maps canonical read-only on-request policy to Claude default with callbacks", () => { |
| 323 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 319 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 324 | ProviderAdapterV2RuntimePolicy.make({ | 320 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 325 | runtimeMode: "full-access", | 321 | runtimeMode: "full-access", |
| 326 | interactionMode: "default", | 322 | interactionMode: "default", |
| 327 | cwd: "/workspace", | 323 | cwd: "/workspace", |
| ... | @@ -344,7 +340,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -344,7 +340,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 344 | 340 | ||
| 345 | it("does not auto-allow reads for canonical restricted read-only never policy", () => { | 341 | it("does not auto-allow reads for canonical restricted read-only never policy", () => { |
| 346 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 342 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 347 | ProviderAdapterV2RuntimePolicy.make({ | 343 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 348 | runtimeMode: "full-access", | 344 | runtimeMode: "full-access", |
| 349 | interactionMode: "default", | 345 | interactionMode: "default", |
| 350 | cwd: "/workspace", | 346 | cwd: "/workspace", |
| ... | @@ -370,7 +366,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -370,7 +366,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 370 | 366 | ||
| 371 | it("maps default full-access policy to Claude bypass permissions", () => { | 367 | it("maps default full-access policy to Claude bypass permissions", () => { |
| 372 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 368 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 373 | ProviderAdapterV2RuntimePolicy.make({ | 369 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 374 | runtimeMode: "full-access", | 370 | runtimeMode: "full-access", |
| 375 | interactionMode: "default", | 371 | interactionMode: "default", |
| 376 | cwd: "/workspace", | 372 | cwd: "/workspace", |
| ... | @@ -386,7 +382,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -386,7 +382,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 386 | 382 | ||
| 387 | it("maps Auto runtime mode to Claude's AI-reviewed permission mode", () => { | 383 | it("maps Auto runtime mode to Claude's AI-reviewed permission mode", () => { |
| 388 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 384 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 389 | ProviderAdapterV2RuntimePolicy.make({ | 385 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 390 | runtimeMode: "auto", | 386 | runtimeMode: "auto", |
| 391 | interactionMode: "default", | 387 | interactionMode: "default", |
| 392 | cwd: "/workspace", | 388 | cwd: "/workspace", |
| ... | @@ -401,7 +397,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -401,7 +397,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 401 | 397 | ||
| 402 | it("keeps approval-required mode interactive with danger-full-access sandboxing", () => { | 398 | it("keeps approval-required mode interactive with danger-full-access sandboxing", () => { |
| 403 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 399 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 404 | ProviderAdapterV2RuntimePolicy.make({ | 400 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 405 | runtimeMode: "approval-required", | 401 | runtimeMode: "approval-required", |
| 406 | interactionMode: "default", | 402 | interactionMode: "default", |
| 407 | cwd: "/workspace", | 403 | cwd: "/workspace", |
| ... | @@ -419,7 +415,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -419,7 +415,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 419 | 415 | ||
| 420 | it("installs the permission callback for approval-required plan mode", () => { | 416 | it("installs the permission callback for approval-required plan mode", () => { |
| 421 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 417 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 422 | ProviderAdapterV2RuntimePolicy.make({ | 418 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 423 | runtimeMode: "approval-required", | 419 | runtimeMode: "approval-required", |
| 424 | interactionMode: "plan", | 420 | interactionMode: "plan", |
| 425 | cwd: "/workspace", | 421 | cwd: "/workspace", |
| ... | @@ -434,7 +430,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -434,7 +430,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 434 | 430 | ||
| 435 | it("honors never approvals for approval-required workspace-write policy", () => { | 431 | it("honors never approvals for approval-required workspace-write policy", () => { |
| 436 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 432 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 437 | ProviderAdapterV2RuntimePolicy.make({ | 433 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 438 | runtimeMode: "approval-required", | 434 | runtimeMode: "approval-required", |
| 439 | interactionMode: "default", | 435 | interactionMode: "default", |
| 440 | cwd: "/workspace", | 436 | cwd: "/workspace", |
| ... | @@ -453,7 +449,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { | ... | @@ -453,7 +449,7 @@ describe("ClaudeAdapterV2 runtime query policy", () => { |
| 453 | 449 | ||
| 454 | it("honors never approvals for externally sandboxed policy", () => { | 450 | it("honors never approvals for externally sandboxed policy", () => { |
| 455 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 451 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 456 | ProviderAdapterV2RuntimePolicy.make({ | 452 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 457 | runtimeMode: "approval-required", | 453 | runtimeMode: "approval-required", |
| 458 | interactionMode: "default", | 454 | interactionMode: "default", |
| 459 | cwd: "/workspace", | 455 | cwd: "/workspace", |
| ... | @@ -595,7 +591,7 @@ describe("ClaudeAdapterV2 MCP query overrides", () => { | ... | @@ -595,7 +591,7 @@ describe("ClaudeAdapterV2 MCP query overrides", () => { |
| 595 | const threadId = ThreadId.make("thread-claude-mcp-query-key"); | 591 | const threadId = ThreadId.make("thread-claude-mcp-query-key"); |
| 596 | withMcpSession(threadId, () => { | 592 | withMcpSession(threadId, () => { |
| 597 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 593 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 598 | ProviderAdapterV2RuntimePolicy.make({ | 594 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 599 | runtimeMode: "full-access", | 595 | runtimeMode: "full-access", |
| 600 | interactionMode: "default", | 596 | interactionMode: "default", |
| 601 | cwd: "/workspace", | 597 | cwd: "/workspace", |
| ... | @@ -627,7 +623,7 @@ describe("ClaudeAdapterV2 MCP query overrides", () => { | ... | @@ -627,7 +623,7 @@ describe("ClaudeAdapterV2 MCP query overrides", () => { |
| 627 | const threadId = ThreadId.make("thread-claude-mcp-credential-rotation"); | 623 | const threadId = ThreadId.make("thread-claude-mcp-credential-rotation"); |
| 628 | withMcpSession(threadId, () => { | 624 | withMcpSession(threadId, () => { |
| 629 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( | 625 | const queryPolicy = ClaudeAdapterV2.claudeRuntimeQueryPolicyForRuntimePolicy( |
| 630 | ProviderAdapterV2RuntimePolicy.make({ | 626 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 631 | runtimeMode: "approval-required", | 627 | runtimeMode: "approval-required", |
| 632 | interactionMode: "default", | 628 | interactionMode: "default", |
| 633 | cwd: "/workspace", | 629 | cwd: "/workspace", |
| ... | @@ -750,7 +746,7 @@ describe("ClaudeAdapterV2 native protocol logging", () => { | ... | @@ -750,7 +746,7 @@ describe("ClaudeAdapterV2 native protocol logging", () => { |
| 750 | readonly event: unknown; | 746 | readonly event: unknown; |
| 751 | readonly threadId: ThreadId | null; | 747 | readonly threadId: ThreadId | null; |
| 752 | }> = []; | 748 | }> = []; |
| 753 | const logger: EventNdjsonLogger = { | 749 | const logger: ProviderEventLoggers.EventNdjsonLogger = { |
| 754 | filePath: "/tmp/events.log", | 750 | filePath: "/tmp/events.log", |
| 755 | write: (event, threadId) => | 751 | write: (event, threadId) => |
| 756 | Effect.sync(() => { | 752 | Effect.sync(() => { |
| ... | @@ -993,7 +989,7 @@ describe("ClaudeAdapterV2 Auto-accept edits", () => { | ... | @@ -993,7 +989,7 @@ describe("ClaudeAdapterV2 Auto-accept edits", () => { |
| 993 | assertComplete: Effect.void, | 989 | assertComplete: Effect.void, |
| 994 | }, | 990 | }, |
| 995 | }); | 991 | }); |
| 996 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 992 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 997 | runtimeMode: "auto-accept-edits", | 993 | runtimeMode: "auto-accept-edits", |
| 998 | interactionMode: "default", | 994 | interactionMode: "default", |
| 999 | cwd: "/workspace", | 995 | cwd: "/workspace", |
| ... | @@ -1701,7 +1697,7 @@ describe("ClaudeAdapterV2 native fork", () => { | ... | @@ -1701,7 +1697,7 @@ describe("ClaudeAdapterV2 native fork", () => { |
| 1701 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), | 1697 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), |
| 1702 | model: "claude-sonnet-4-6", | 1698 | model: "claude-sonnet-4-6", |
| 1703 | }, | 1699 | }, |
| 1704 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 1700 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1705 | runtimeMode: "full-access", | 1701 | runtimeMode: "full-access", |
| 1706 | interactionMode: "default", | 1702 | interactionMode: "default", |
| 1707 | cwd: "/workspace", | 1703 | cwd: "/workspace", |
| ... | @@ -1713,7 +1709,7 @@ describe("ClaudeAdapterV2 native fork", () => { | ... | @@ -1713,7 +1709,7 @@ describe("ClaudeAdapterV2 native fork", () => { |
| 1713 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), | 1709 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), |
| 1714 | model: "claude-sonnet-4-6", | 1710 | model: "claude-sonnet-4-6", |
| 1715 | }, | 1711 | }, |
| 1716 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 1712 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1717 | runtimeMode: "full-access", | 1713 | runtimeMode: "full-access", |
| 1718 | interactionMode: "default", | 1714 | interactionMode: "default", |
| 1719 | cwd: "/workspace", | 1715 | cwd: "/workspace", |
| ... | @@ -1808,7 +1804,7 @@ describe("ClaudeAdapterV2 native fork", () => { | ... | @@ -1808,7 +1804,7 @@ describe("ClaudeAdapterV2 native fork", () => { |
| 1808 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), | 1804 | instanceId: ProviderInstanceId.make(ClaudeAdapterV2.CLAUDE_PROVIDER), |
| 1809 | model: "claude-sonnet-4-6", | 1805 | model: "claude-sonnet-4-6", |
| 1810 | }, | 1806 | }, |
| 1811 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 1807 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1812 | runtimeMode: "full-access", | 1808 | runtimeMode: "full-access", |
| 1813 | interactionMode: "default", | 1809 | interactionMode: "default", |
| 1814 | cwd: "/workspace", | 1810 | cwd: "/workspace", |
| ... | @@ -2120,11 +2116,16 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2120,11 +2116,16 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2120 | }); | 2116 | }); |
| 2121 | const offeredMessages: Array<SDKUserMessage> = []; | 2117 | const offeredMessages: Array<SDKUserMessage> = []; |
| 2122 | const permissionModeChanges: Array<string> = []; | 2118 | const permissionModeChanges: Array<string> = []; |
| 2123 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 2119 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 2120 | []; | ||
| 2124 | const terminalReceipts = | 2121 | const terminalReceipts = |
| 2125 | yield* Queue.unbounded<Extract<ProviderAdapterV2Event, { type: "turn.terminal" }>>(); | 2122 | yield* Queue.unbounded< |
| 2123 | Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> | ||
| 2124 | >(); | ||
| 2126 | const systemNoticeReceipts = | 2125 | const systemNoticeReceipts = |
| 2127 | yield* Queue.unbounded<Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }>>(); | 2126 | yield* Queue.unbounded< |
| 2127 | Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn_item.updated" }> | ||
| 2128 | >(); | ||
| 2128 | let openedOptions: ClaudeAdapterV2.ClaudeAgentSdkQueryOptions | undefined; | 2129 | let openedOptions: ClaudeAdapterV2.ClaudeAgentSdkQueryOptions | undefined; |
| 2129 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 2130 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 2130 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 2131 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| ... | @@ -2210,7 +2211,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2210,7 +2211,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2210 | modelSelection: CLAUDE_TEST_MODEL_SELECTION, | 2211 | modelSelection: CLAUDE_TEST_MODEL_SELECTION, |
| 2211 | runtimePolicy: CLAUDE_TEST_RUNTIME_POLICY, | 2212 | runtimePolicy: CLAUDE_TEST_RUNTIME_POLICY, |
| 2212 | }); | 2213 | }); |
| 2213 | const events: Array<ProviderAdapterV2Event> = []; | 2214 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 2214 | yield* runtime.events.pipe( | 2215 | yield* runtime.events.pipe( |
| 2215 | Stream.runForEach((event) => | 2216 | Stream.runForEach((event) => |
| 2216 | Effect.gen(function* () { | 2217 | Effect.gen(function* () { |
| ... | @@ -2231,7 +2232,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2231,7 +2232,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2231 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 2232 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 2232 | const terminalEvents = () => | 2233 | const terminalEvents = () => |
| 2233 | events.filter( | 2234 | events.filter( |
| 2234 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 2235 | ( |
| 2236 | event, | ||
| 2237 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 2235 | event.type === "turn.terminal", | 2238 | event.type === "turn.terminal", |
| 2236 | ); | 2239 | ); |
| 2237 | return { | 2240 | return { |
| ... | @@ -2817,7 +2820,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -2817,7 +2820,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 2817 | attemptId: RunAttemptId.make("attempt-claude-auth-failure"), | 2820 | attemptId: RunAttemptId.make("attempt-claude-auth-failure"), |
| 2818 | text: "Continue.", | 2821 | text: "Continue.", |
| 2819 | attachments: [], | 2822 | attachments: [], |
| 2820 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 2823 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 2821 | runtimeMode: "full-access", | 2824 | runtimeMode: "full-access", |
| 2822 | interactionMode: "default", | 2825 | interactionMode: "default", |
| 2823 | cwd, | 2826 | cwd, |
| ... | @@ -3633,10 +3636,16 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -3633,10 +3636,16 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 3633 | ), | 3636 | ), |
| 3634 | ); | 3637 | ); |
| 3635 | 3638 | ||
| 3636 | const providerThreadRosterEvents = (events: ReadonlyArray<ProviderAdapterV2Event>) => | 3639 | const providerThreadRosterEvents = ( |
| 3640 | events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>, | ||
| 3641 | ) => | ||
| 3637 | events.filter( | 3642 | events.filter( |
| 3638 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_thread.updated" }> => | 3643 | ( |
| 3639 | event.type === "provider_thread.updated", | 3644 | event, |
| 3645 | ): event is Extract< | ||
| 3646 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 3647 | { type: "provider_thread.updated" } | ||
| 3648 | > => event.type === "provider_thread.updated", | ||
| 3640 | ); | 3649 | ); |
| 3641 | 3650 | ||
| 3642 | it.effect( | 3651 | it.effect( |
| ... | @@ -3932,8 +3941,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -3932,8 +3941,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 3932 | }); | 3941 | }); |
| 3933 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 3942 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 3934 | const firstCloseRequested = yield* Deferred.make<void>(); | 3943 | const firstCloseRequested = yield* Deferred.make<void>(); |
| 3935 | const events: Array<ProviderAdapterV2Event> = []; | 3944 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 3936 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 3945 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 3946 | []; | ||
| 3937 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 3947 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 3938 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 3948 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 3939 | settings: DEFAULT_CLAUDE_SETTINGS, | 3949 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -4179,7 +4189,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -4179,7 +4189,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 4179 | readonly nativeThreadId: string; | 4189 | readonly nativeThreadId: string; |
| 4180 | readonly queue: Queue.Queue<SDKMessage>; | 4190 | readonly queue: Queue.Queue<SDKMessage>; |
| 4181 | }> = []; | 4191 | }> = []; |
| 4182 | const events: Array<ProviderAdapterV2Event> = []; | 4192 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 4183 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 4193 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 4184 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 4194 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 4185 | settings: DEFAULT_CLAUDE_SETTINGS, | 4195 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -4430,7 +4440,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -4430,7 +4440,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 4430 | Effect.gen(function* () { | 4440 | Effect.gen(function* () { |
| 4431 | const harness = yield* makeWakeHarness; | 4441 | const harness = yield* makeWakeHarness; |
| 4432 | const now = yield* DateTime.now; | 4442 | const now = yield* DateTime.now; |
| 4433 | const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({ | 4443 | const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4434 | runtimeMode, | 4444 | runtimeMode, |
| 4435 | interactionMode: "default", | 4445 | interactionMode: "default", |
| 4436 | cwd: "/workspace", | 4446 | cwd: "/workspace", |
| ... | @@ -4731,7 +4741,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -4731,7 +4741,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 4731 | Effect.gen(function* () { | 4741 | Effect.gen(function* () { |
| 4732 | const harness = yield* makeWakeHarness; | 4742 | const harness = yield* makeWakeHarness; |
| 4733 | const now = yield* DateTime.now; | 4743 | const now = yield* DateTime.now; |
| 4734 | const approvalPolicy = ProviderAdapterV2RuntimePolicy.make({ | 4744 | const approvalPolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 4735 | runtimeMode: "approval-required", | 4745 | runtimeMode: "approval-required", |
| 4736 | interactionMode: "default", | 4746 | interactionMode: "default", |
| 4737 | cwd: "/workspace", | 4747 | cwd: "/workspace", |
| ... | @@ -5972,7 +5982,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -5972,7 +5982,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 5972 | session_id: WAKE_NATIVE_SESSION, | 5982 | session_id: WAKE_NATIVE_SESSION, |
| 5973 | }); | 5983 | }); |
| 5974 | const subagentRouting = ( | 5984 | const subagentRouting = ( |
| 5975 | events: ReadonlyArray<ProviderAdapterV2Event>, | 5985 | events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>, |
| 5976 | nativeToolIds: ReadonlyArray<string>, | 5986 | nativeToolIds: ReadonlyArray<string>, |
| 5977 | ) => { | 5987 | ) => { |
| 5978 | const childThreadId = | 5988 | const childThreadId = |
| ... | @@ -6090,7 +6100,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -6090,7 +6100,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 6090 | const userTurn = ( | 6100 | const userTurn = ( |
| 6091 | attempt: string, | 6101 | attempt: string, |
| 6092 | providerTurnOrdinal: number, | 6102 | providerTurnOrdinal: number, |
| 6093 | attachments: ProviderAdapterV2TurnInput["message"]["attachments"] = [], | 6103 | attachments: ProviderAdapter.ProviderAdapterV2TurnInput["message"]["attachments"] = [], |
| 6094 | ) => | 6104 | ) => |
| 6095 | harness.runtime.startTurn( | 6105 | harness.runtime.startTurn( |
| 6096 | makeClaudeTestTurnInput({ | 6106 | makeClaudeTestTurnInput({ |
| ... | @@ -7838,8 +7848,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -7838,8 +7848,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 7838 | const now = yield* DateTime.now; | 7848 | const now = yield* DateTime.now; |
| 7839 | const subagentEvents = () => | 7849 | const subagentEvents = () => |
| 7840 | harness.events.filter( | 7850 | harness.events.filter( |
| 7841 | (event): event is Extract<ProviderAdapterV2Event, { type: "subagent.updated" }> => | 7851 | ( |
| 7842 | event.type === "subagent.updated", | 7852 | event, |
| 7853 | ): event is Extract< | ||
| 7854 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 7855 | { type: "subagent.updated" } | ||
| 7856 | > => event.type === "subagent.updated", | ||
| 7843 | ); | 7857 | ); |
| 7844 | 7858 | ||
| 7845 | yield* harness.runtime.startTurn( | 7859 | yield* harness.runtime.startTurn( |
| ... | @@ -7942,8 +7956,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -7942,8 +7956,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 7942 | const now = yield* DateTime.now; | 7956 | const now = yield* DateTime.now; |
| 7943 | const subagentEvents = () => | 7957 | const subagentEvents = () => |
| 7944 | harness.events.filter( | 7958 | harness.events.filter( |
| 7945 | (event): event is Extract<ProviderAdapterV2Event, { type: "subagent.updated" }> => | 7959 | ( |
| 7946 | event.type === "subagent.updated", | 7960 | event, |
| 7961 | ): event is Extract< | ||
| 7962 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 7963 | { type: "subagent.updated" } | ||
| 7964 | > => event.type === "subagent.updated", | ||
| 7947 | ); | 7965 | ); |
| 7948 | 7966 | ||
| 7949 | yield* harness.runtime.startTurn( | 7967 | yield* harness.runtime.startTurn( |
| ... | @@ -8059,8 +8077,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8059,8 +8077,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8059 | const now = yield* DateTime.now; | 8077 | const now = yield* DateTime.now; |
| 8060 | const subagentEvents = () => | 8078 | const subagentEvents = () => |
| 8061 | harness.events.filter( | 8079 | harness.events.filter( |
| 8062 | (event): event is Extract<ProviderAdapterV2Event, { type: "subagent.updated" }> => | 8080 | ( |
| 8063 | event.type === "subagent.updated", | 8081 | event, |
| 8082 | ): event is Extract< | ||
| 8083 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 8084 | { type: "subagent.updated" } | ||
| 8085 | > => event.type === "subagent.updated", | ||
| 8064 | ); | 8086 | ); |
| 8065 | 8087 | ||
| 8066 | yield* harness.runtime.startTurn( | 8088 | yield* harness.runtime.startTurn( |
| ... | @@ -8249,7 +8271,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8249,7 +8271,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8249 | // already pre-opened by the wake buffer before the drain replay. | 8271 | // already pre-opened by the wake buffer before the drain replay. |
| 8250 | const nodeStatuses = harness.events | 8272 | const nodeStatuses = harness.events |
| 8251 | .filter( | 8273 | .filter( |
| 8252 | (event): event is Extract<ProviderAdapterV2Event, { type: "node.updated" }> => | 8274 | ( |
| 8275 | event, | ||
| 8276 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "node.updated" }> => | ||
| 8253 | event.type === "node.updated" && | 8277 | event.type === "node.updated" && |
| 8254 | event.node.kind === "subagent" && | 8278 | event.node.kind === "subagent" && |
| 8255 | event.node.nativeItemRef?.nativeId === SUBAGENT_TASK_ID, | 8279 | event.node.nativeItemRef?.nativeId === SUBAGENT_TASK_ID, |
| ... | @@ -8288,8 +8312,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8288,8 +8312,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8288 | prefix: "t3-claude-v2-process-reset-", | 8312 | prefix: "t3-claude-v2-process-reset-", |
| 8289 | }); | 8313 | }); |
| 8290 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 8314 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 8291 | const events: Array<ProviderAdapterV2Event> = []; | 8315 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 8292 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 8316 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 8317 | []; | ||
| 8293 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 8318 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 8294 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 8319 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 8295 | settings: DEFAULT_CLAUDE_SETTINGS, | 8320 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -8472,8 +8497,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8472,8 +8497,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8472 | prefix: "t3-claude-v2-buffer-replace-", | 8497 | prefix: "t3-claude-v2-buffer-replace-", |
| 8473 | }); | 8498 | }); |
| 8474 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 8499 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 8475 | const events: Array<ProviderAdapterV2Event> = []; | 8500 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 8476 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 8501 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 8502 | []; | ||
| 8477 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 8503 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 8478 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 8504 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 8479 | settings: DEFAULT_CLAUDE_SETTINGS, | 8505 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -8708,8 +8734,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8708,8 +8734,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8708 | prefix: "t3-claude-v2-subagent-buffer-replace-", | 8734 | prefix: "t3-claude-v2-subagent-buffer-replace-", |
| 8709 | }); | 8735 | }); |
| 8710 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 8736 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 8711 | const events: Array<ProviderAdapterV2Event> = []; | 8737 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 8712 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 8738 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 8739 | []; | ||
| 8713 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 8740 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 8714 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 8741 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 8715 | settings: DEFAULT_CLAUDE_SETTINGS, | 8742 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -8775,8 +8802,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8775,8 +8802,12 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8775 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 8802 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 8776 | const subagentEvents = () => | 8803 | const subagentEvents = () => |
| 8777 | events.filter( | 8804 | events.filter( |
| 8778 | (event): event is Extract<ProviderAdapterV2Event, { type: "subagent.updated" }> => | 8805 | ( |
| 8779 | event.type === "subagent.updated", | 8806 | event, |
| 8807 | ): event is Extract< | ||
| 8808 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 8809 | { type: "subagent.updated" } | ||
| 8810 | > => event.type === "subagent.updated", | ||
| 8780 | ); | 8811 | ); |
| 8781 | const now = yield* DateTime.now; | 8812 | const now = yield* DateTime.now; |
| 8782 | 8813 | ||
| ... | @@ -8880,7 +8911,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8880,7 +8911,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8880 | assert.equal(finalSubagent?.result, SUBAGENT_SUMMARY); | 8911 | assert.equal(finalSubagent?.result, SUBAGENT_SUMMARY); |
| 8881 | assert.equal(finalSubagent?.runId, subagentEvents()[0]?.subagent.runId); | 8912 | assert.equal(finalSubagent?.runId, subagentEvents()[0]?.subagent.runId); |
| 8882 | const subagentNodeEvents = events.filter( | 8913 | const subagentNodeEvents = events.filter( |
| 8883 | (event): event is Extract<ProviderAdapterV2Event, { type: "node.updated" }> => | 8914 | ( |
| 8915 | event, | ||
| 8916 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "node.updated" }> => | ||
| 8884 | event.type === "node.updated" && | 8917 | event.type === "node.updated" && |
| 8885 | event.node.kind === "subagent" && | 8918 | event.node.kind === "subagent" && |
| 8886 | event.node.nativeItemRef?.nativeId === SUBAGENT_TASK_ID, | 8919 | event.node.nativeItemRef?.nativeId === SUBAGENT_TASK_ID, |
| ... | @@ -8902,7 +8935,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -8902,7 +8935,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 8902 | prefix: "t3-claude-v2-model-change-running-subagent-", | 8935 | prefix: "t3-claude-v2-model-change-running-subagent-", |
| 8903 | }); | 8936 | }); |
| 8904 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 8937 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 8905 | const events: Array<ProviderAdapterV2Event> = []; | 8938 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 8906 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 8939 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 8907 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 8940 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 8908 | settings: DEFAULT_CLAUDE_SETTINGS, | 8941 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -9069,7 +9102,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -9069,7 +9102,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 9069 | }); | 9102 | }); |
| 9070 | let openCount = 0; | 9103 | let openCount = 0; |
| 9071 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 9104 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 9072 | const events: Array<ProviderAdapterV2Event> = []; | 9105 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 9073 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 9106 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 9074 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 9107 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 9075 | settings: DEFAULT_CLAUDE_SETTINGS, | 9108 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -9198,8 +9231,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -9198,8 +9231,9 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 9198 | }); | 9231 | }); |
| 9199 | let openCount = 0; | 9232 | let openCount = 0; |
| 9200 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; | 9233 | const processQueues: Array<Queue.Queue<SDKMessage>> = []; |
| 9201 | const events: Array<ProviderAdapterV2Event> = []; | 9234 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 9202 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 9235 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 9236 | []; | ||
| 9203 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 9237 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 9204 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 9238 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 9205 | settings: DEFAULT_CLAUDE_SETTINGS, | 9239 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -9394,7 +9428,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -9394,7 +9428,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 9394 | const attachmentsDir = yield* fileSystem.makeTempDirectoryScoped({ | 9428 | const attachmentsDir = yield* fileSystem.makeTempDirectoryScoped({ |
| 9395 | prefix: "t3-claude-v2-first-open-fail-", | 9429 | prefix: "t3-claude-v2-first-open-fail-", |
| 9396 | }); | 9430 | }); |
| 9397 | const events: Array<ProviderAdapterV2Event> = []; | 9431 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 9398 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ | 9432 | const adapter = ClaudeAdapterV2.makeClaudeAdapterV2({ |
| 9399 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, | 9433 | instanceId: ClaudeAdapterV2.CLAUDE_DEFAULT_INSTANCE_ID, |
| 9400 | settings: DEFAULT_CLAUDE_SETTINGS, | 9434 | settings: DEFAULT_CLAUDE_SETTINGS, |
| ... | @@ -9496,7 +9530,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { | ... | @@ -9496,7 +9530,7 @@ describe("ClaudeAdapterV2 background wake turns", () => { |
| 9496 | uuid, | 9530 | uuid, |
| 9497 | session_id: WAKE_NATIVE_SESSION, | 9531 | session_id: WAKE_NATIVE_SESSION, |
| 9498 | }); | 9532 | }); |
| 9499 | const goalStatuses = (events: ReadonlyArray<ProviderAdapterV2Event>) => | 9533 | const goalStatuses = (events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 9500 | events.flatMap((event) => | 9534 | events.flatMap((event) => |
| 9501 | event.type === "provider_thread.updated" && event.providerThread.goal != null | 9535 | event.type === "provider_thread.updated" && event.providerThread.goal != null |
| 9502 | ? [event.providerThread.goal] | 9536 | ? [event.providerThread.goal] |
apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts+7-11| ... | @@ -101,10 +101,9 @@ import { | ... | @@ -101,10 +101,9 @@ import { |
| 101 | } from "../../provider/ClaudeModelCatalog.ts"; | 101 | } from "../../provider/ClaudeModelCatalog.ts"; |
| 102 | import { | 102 | import { |
| 103 | boundProviderEventForLogging, | 103 | boundProviderEventForLogging, |
| 104 | type EventNdjsonLogger, | ||
| 105 | shouldPersistProviderEvent, | 104 | shouldPersistProviderEvent, |
| 106 | } from "../../provider/EventNdjsonLogger.ts"; | 105 | } from "../../provider/EventNdjsonLogger.ts"; |
| 107 | import * as ProviderEventLoggers from "../../provider/ProviderEventLoggers.ts"; | 106 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 108 | import { | 107 | import { |
| 109 | claudeRateLimitEventToUpdate, | 108 | claudeRateLimitEventToUpdate, |
| 110 | type ClaudeScopedLimitNames, | 109 | type ClaudeScopedLimitNames, |
| ... | @@ -135,7 +134,7 @@ import { | ... | @@ -135,7 +134,7 @@ import { |
| 135 | type BackgroundWorkReport, | 134 | type BackgroundWorkReport, |
| 136 | backgroundWorkNotification, | 135 | backgroundWorkNotification, |
| 137 | } from "@t3tools/provider-core/server/notification"; | 136 | } from "@t3tools/provider-core/server/notification"; |
| 138 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 137 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 139 | import { | 138 | import { |
| 140 | makeSubagentChildThread, | 139 | makeSubagentChildThread, |
| 141 | makeSubagentConversationArtifacts, | 140 | makeSubagentConversationArtifacts, |
| ... | @@ -570,7 +569,7 @@ export function loggedClaudeQueryOptions( | ... | @@ -570,7 +569,7 @@ export function loggedClaudeQueryOptions( |
| 570 | } | 569 | } |
| 571 | 570 | ||
| 572 | export function makeClaudeAgentSdkProtocolLogger(input: { | 571 | export function makeClaudeAgentSdkProtocolLogger(input: { |
| 573 | readonly nativeEventLogger: EventNdjsonLogger | undefined; | 572 | readonly nativeEventLogger: ProviderEventLoggers.EventNdjsonLogger | undefined; |
| 574 | readonly threadId: ThreadId; | 573 | readonly threadId: ThreadId; |
| 575 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; | 574 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; |
| 576 | }): ClaudeAgentSdkProtocolLogger | undefined { | 575 | }): ClaudeAgentSdkProtocolLogger | undefined { |
| ... | @@ -1118,7 +1117,7 @@ function resultTextFromSdkMessage( | ... | @@ -1118,7 +1117,7 @@ function resultTextFromSdkMessage( |
| 1118 | } | 1117 | } |
| 1119 | 1118 | ||
| 1120 | function makeProviderThread(input: { | 1119 | function makeProviderThread(input: { |
| 1121 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 1120 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 1122 | readonly providerInstanceId: ProviderInstanceId; | 1121 | readonly providerInstanceId: ProviderInstanceId; |
| 1123 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; | 1122 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; |
| 1124 | readonly ownerNodeId?: OrchestrationV2ProviderThread["ownerNodeId"]; | 1123 | readonly ownerNodeId?: OrchestrationV2ProviderThread["ownerNodeId"]; |
| ... | @@ -2581,7 +2580,7 @@ function providerFailureFromApiRetry(message: SDKAPIRetryMessage): Orchestration | ... | @@ -2581,7 +2580,7 @@ function providerFailureFromApiRetry(message: SDKAPIRetryMessage): Orchestration |
| 2581 | } | 2580 | } |
| 2582 | 2581 | ||
| 2583 | function buildAssistantArtifacts(input: { | 2582 | function buildAssistantArtifacts(input: { |
| 2584 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 2583 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 2585 | readonly turnInput: ProviderAdapter.ProviderAdapterV2TurnInput; | 2584 | readonly turnInput: ProviderAdapter.ProviderAdapterV2TurnInput; |
| 2586 | readonly providerTurnId: OrchestrationV2ProviderTurn["id"]; | 2585 | readonly providerTurnId: OrchestrationV2ProviderTurn["id"]; |
| 2587 | readonly nativeItemId: string; | 2586 | readonly nativeItemId: string; |
| ... | @@ -3015,7 +3014,7 @@ export interface ClaudeAdapterV2Options { | ... | @@ -3015,7 +3014,7 @@ export interface ClaudeAdapterV2Options { |
| 3015 | readonly fileSystem: FileSystem.FileSystem; | 3014 | readonly fileSystem: FileSystem.FileSystem; |
| 3016 | readonly path: Path.Path; | 3015 | readonly path: Path.Path; |
| 3017 | readonly crypto: Crypto.Crypto; | 3016 | readonly crypto: Crypto.Crypto; |
| 3018 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 3017 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 3019 | readonly queryRunner: ClaudeAgentSdkQueryRunnerShape; | 3018 | readonly queryRunner: ClaudeAgentSdkQueryRunnerShape; |
| 3020 | readonly scopedLimitNames?: Ref.Ref<ClaudeScopedLimitNames>; | 3019 | readonly scopedLimitNames?: Ref.Ref<ClaudeScopedLimitNames>; |
| 3021 | readonly onUsageLimits?: ServerProviderShape["applyUsageLimits"]; | 3020 | readonly onUsageLimits?: ServerProviderShape["applyUsageLimits"]; |
| ... | @@ -3029,7 +3028,7 @@ export interface ClaudeAdapterV2Options { | ... | @@ -3029,7 +3028,7 @@ export interface ClaudeAdapterV2Options { |
| 3029 | 3028 | ||
| 3030 | export function makeClaudeAdapterV2( | 3029 | export function makeClaudeAdapterV2( |
| 3031 | adapterOptions: ClaudeAdapterV2Options, | 3030 | adapterOptions: ClaudeAdapterV2Options, |
| 3032 | ): ProviderAdapter.ProviderAdapterV2Shape { | 3031 | ): ProviderAdapter.ProviderAdapterV2["Service"] { |
| 3033 | const { attachmentsDir, fileSystem, path, crypto, idAllocator, queryRunner } = adapterOptions; | 3032 | const { attachmentsDir, fileSystem, path, crypto, idAllocator, queryRunner } = adapterOptions; |
| 3034 | const continuationRequests = adapterOptions.continuationRequests ?? { | 3033 | const continuationRequests = adapterOptions.continuationRequests ?? { |
| 3035 | offer: () => Effect.void, | 3034 | offer: () => Effect.void, |
| ... | @@ -3356,7 +3355,6 @@ export function makeClaudeAdapterV2( | ... | @@ -3356,7 +3355,6 @@ export function makeClaudeAdapterV2( |
| 3356 | type: "turn_item.updated", | 3355 | type: "turn_item.updated", |
| 3357 | driver: CLAUDE_PROVIDER, | 3356 | driver: CLAUDE_PROVIDER, |
| 3358 | turnItem: makeProviderRetryTurnItem({ | 3357 | turnItem: makeProviderRetryTurnItem({ |
| 3359 | idAllocator, | ||
| 3360 | driver: CLAUDE_PROVIDER, | 3358 | driver: CLAUDE_PROVIDER, |
| 3361 | threadId: context.input.threadId, | 3359 | threadId: context.input.threadId, |
| 3362 | runId: context.input.runId, | 3360 | runId: context.input.runId, |
| ... | @@ -5083,7 +5081,6 @@ export function makeClaudeAdapterV2( | ... | @@ -5083,7 +5081,6 @@ export function makeClaudeAdapterV2( |
| 5083 | type: "turn_item.updated", | 5081 | type: "turn_item.updated", |
| 5084 | driver: CLAUDE_PROVIDER, | 5082 | driver: CLAUDE_PROVIDER, |
| 5085 | turnItem: makeProviderRetryTurnItem({ | 5083 | turnItem: makeProviderRetryTurnItem({ |
| 5086 | idAllocator, | ||
| 5087 | driver: CLAUDE_PROVIDER, | 5084 | driver: CLAUDE_PROVIDER, |
| 5088 | threadId: input.context.input.threadId, | 5085 | threadId: input.context.input.threadId, |
| 5089 | runId: input.context.input.runId, | 5086 | runId: input.context.input.runId, |
| ... | @@ -6089,7 +6086,6 @@ export function makeClaudeAdapterV2( | ... | @@ -6089,7 +6086,6 @@ export function makeClaudeAdapterV2( |
| 6089 | type: "turn_item.updated", | 6086 | type: "turn_item.updated", |
| 6090 | driver: CLAUDE_PROVIDER, | 6087 | driver: CLAUDE_PROVIDER, |
| 6091 | turnItem: makeProviderRetryTurnItem({ | 6088 | turnItem: makeProviderRetryTurnItem({ |
| 6092 | idAllocator, | ||
| 6093 | driver: CLAUDE_PROVIDER, | 6089 | driver: CLAUDE_PROVIDER, |
| 6094 | threadId: context.input.threadId, | 6090 | threadId: context.input.threadId, |
| 6095 | runId: context.input.runId, | 6091 | runId: context.input.runId, |
apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts+108-57| ... | @@ -1,7 +1,6 @@ | ... | @@ -1,7 +1,6 @@ |
| 1 | import * as NodeOS from "node:os"; | 1 | import * as NodeOS from "node:os"; |
| 2 | 2 | ||
| 3 | import { historyResponseItems } from "@t3tools/provider-core/server/handoffBudget"; | 3 | import { historyResponseItems } from "@t3tools/provider-core/server/handoffBudget"; |
| 4 | import type { ProviderAdapterV2HistoricalContext } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 5 | import { | 4 | import { |
| 6 | makeProviderTextDeltaCoalescer, | 5 | makeProviderTextDeltaCoalescer, |
| 7 | type ProviderTextDeltaUpdate, | 6 | type ProviderTextDeltaUpdate, |
| ... | @@ -56,21 +55,13 @@ import { ChildProcess, ChildProcessSpawner } from "effect/process"; | ... | @@ -56,21 +55,13 @@ import { ChildProcess, ChildProcessSpawner } from "effect/process"; |
| 56 | import packageJson from "../../../package.json" with { type: "json" }; | 55 | import packageJson from "../../../package.json" with { type: "json" }; |
| 57 | import * as ServerConfig from "../../config.ts"; | 56 | import * as ServerConfig from "../../config.ts"; |
| 58 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; | 57 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; |
| 59 | import type { EventNdjsonLogger } from "../../provider/EventNdjsonLogger.ts"; | 58 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 60 | import * as ProviderEventLoggers from "../../provider/ProviderEventLoggers.ts"; | ||
| 61 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 59 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 62 | import * as EffectWorker from "../EffectWorker.ts"; | 60 | import * as EffectWorker from "../EffectWorker.ts"; |
| 63 | import * as Orchestrator from "../Orchestrator.ts"; | 61 | import * as Orchestrator from "../Orchestrator.ts"; |
| 64 | import * as ProviderReplayHarness from "../testkit/ProviderReplayHarness.ts"; | 62 | import * as ProviderReplayHarness from "../testkit/ProviderReplayHarness.ts"; |
| 65 | import { | 63 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 66 | ProviderAdapterForkThreadError, | 64 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 67 | ProviderAdapterOpenSessionError, | ||
| 68 | ProviderAdapterRollbackThreadError, | ||
| 69 | ProviderAdapterV2RuntimePolicy, | ||
| 70 | type ProviderAdapterV2Event, | ||
| 71 | type ProviderAdapterV2TurnInput, | ||
| 72 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 73 | import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | ||
| 74 | import * as CodexAdapterV2 from "./CodexAdapterV2.ts"; | 65 | import * as CodexAdapterV2 from "./CodexAdapterV2.ts"; |
| 75 | import { makeReplayServerConfig, withCodexReplayChildMetadata } from "./CodexAdapterV2.testkit.ts"; | 66 | import { makeReplayServerConfig, withCodexReplayChildMetadata } from "./CodexAdapterV2.testkit.ts"; |
| 76 | import * as CodexAdapterV2Testkit from "./CodexAdapterV2.testkit.ts"; | 67 | import * as CodexAdapterV2Testkit from "./CodexAdapterV2.testkit.ts"; |
| ... | @@ -767,7 +758,7 @@ describe("CodexAdapterV2 process spawning", () => { | ... | @@ -767,7 +758,7 @@ describe("CodexAdapterV2 process spawning", () => { |
| 767 | instanceId: CodexAdapterV2.CODEX_DEFAULT_INSTANCE_ID, | 758 | instanceId: CodexAdapterV2.CODEX_DEFAULT_INSTANCE_ID, |
| 768 | threadId: ThreadId.make("thread-launch-args"), | 759 | threadId: ThreadId.make("thread-launch-args"), |
| 769 | providerSessionId: ProviderSessionId.make("provider-session-launch-args"), | 760 | providerSessionId: ProviderSessionId.make("provider-session-launch-args"), |
| 770 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 761 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 771 | runtimeMode: "full-access", | 762 | runtimeMode: "full-access", |
| 772 | interactionMode: "default", | 763 | interactionMode: "default", |
| 773 | cwd: "/workspace", | 764 | cwd: "/workspace", |
| ... | @@ -1036,7 +1027,7 @@ describe("CodexAdapterV2 native protocol logging", () => { | ... | @@ -1036,7 +1027,7 @@ describe("CodexAdapterV2 native protocol logging", () => { |
| 1036 | readonly event: unknown; | 1027 | readonly event: unknown; |
| 1037 | readonly threadId: ThreadId | null; | 1028 | readonly threadId: ThreadId | null; |
| 1038 | }> = []; | 1029 | }> = []; |
| 1039 | const logger: EventNdjsonLogger = { | 1030 | const logger: ProviderEventLoggers.EventNdjsonLogger = { |
| 1040 | filePath: "/tmp/events.log", | 1031 | filePath: "/tmp/events.log", |
| 1041 | write: (event, threadId) => | 1032 | write: (event, threadId) => |
| 1042 | Effect.sync(() => { | 1033 | Effect.sync(() => { |
| ... | @@ -1410,7 +1401,7 @@ describe("CodexAdapterV2 fork boundary", () => { | ... | @@ -1410,7 +1401,7 @@ describe("CodexAdapterV2 fork boundary", () => { |
| 1410 | }), | 1401 | }), |
| 1411 | ); | 1402 | ); |
| 1412 | 1403 | ||
| 1413 | assert.instanceOf(error, ProviderAdapterForkThreadError); | 1404 | assert.instanceOf(error, ProviderAdapter.ProviderAdapterForkThreadError); |
| 1414 | assert.include(String(error.cause), "provider-turn-missing"); | 1405 | assert.include(String(error.cause), "provider-turn-missing"); |
| 1415 | }), | 1406 | }), |
| 1416 | ); | 1407 | ); |
| ... | @@ -1478,7 +1469,7 @@ const CODEX_TEST_MODEL_SELECTION = { | ... | @@ -1478,7 +1469,7 @@ const CODEX_TEST_MODEL_SELECTION = { |
| 1478 | instanceId: CodexAdapterV2.CODEX_DEFAULT_INSTANCE_ID, | 1469 | instanceId: CodexAdapterV2.CODEX_DEFAULT_INSTANCE_ID, |
| 1479 | model: "gpt-5.4", | 1470 | model: "gpt-5.4", |
| 1480 | } satisfies ModelSelection; | 1471 | } satisfies ModelSelection; |
| 1481 | const CODEX_TEST_RUNTIME_POLICY = ProviderAdapterV2RuntimePolicy.make({ | 1472 | const CODEX_TEST_RUNTIME_POLICY = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 1482 | runtimeMode: "full-access", | 1473 | runtimeMode: "full-access", |
| 1483 | interactionMode: "default", | 1474 | interactionMode: "default", |
| 1484 | cwd: "/workspace", | 1475 | cwd: "/workspace", |
| ... | @@ -1524,7 +1515,7 @@ function makeCodexTestTurnInput(input: { | ... | @@ -1524,7 +1515,7 @@ function makeCodexTestTurnInput(input: { |
| 1524 | readonly now: DateTime.Utc; | 1515 | readonly now: DateTime.Utc; |
| 1525 | readonly attemptId: RunAttemptId; | 1516 | readonly attemptId: RunAttemptId; |
| 1526 | readonly text: string; | 1517 | readonly text: string; |
| 1527 | }): ProviderAdapterV2TurnInput { | 1518 | }): ProviderAdapter.ProviderAdapterV2TurnInput { |
| 1528 | return { | 1519 | return { |
| 1529 | appThread: makeCodexTestAppThread(input), | 1520 | appThread: makeCodexTestAppThread(input), |
| 1530 | threadId: input.threadId, | 1521 | threadId: input.threadId, |
| ... | @@ -1747,7 +1738,7 @@ describe("CodexAdapterV2 session initialize", () => { | ... | @@ -1747,7 +1738,7 @@ describe("CodexAdapterV2 session initialize", () => { |
| 1747 | ), | 1738 | ), |
| 1748 | Effect.mapError( | 1739 | Effect.mapError( |
| 1749 | (cause) => | 1740 | (cause) => |
| 1750 | new ProviderAdapterOpenSessionError({ | 1741 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 1751 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, | 1742 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, |
| 1752 | providerSessionId: openInput.providerSessionId, | 1743 | providerSessionId: openInput.providerSessionId, |
| 1753 | cause, | 1744 | cause, |
| ... | @@ -1907,7 +1898,8 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -1907,7 +1898,8 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 1907 | 1898 | ||
| 1908 | const makeCodexReplayHarness = ( | 1899 | const makeCodexReplayHarness = ( |
| 1909 | transcript: CodexReplay.CodexAppServerReplayTranscript, | 1900 | transcript: CodexReplay.CodexAppServerReplayTranscript, |
| 1910 | onEvent: (event: ProviderAdapterV2Event) => Effect.Effect<unknown> = () => Effect.void, | 1901 | onEvent: (event: ProviderAdapter.ProviderAdapterV2Event) => Effect.Effect<unknown> = () => |
| 1902 | Effect.void, | ||
| 1911 | onRequest: (method: string, params: unknown) => Effect.Effect<void> = () => Effect.void, | 1903 | onRequest: (method: string, params: unknown) => Effect.Effect<void> = () => Effect.void, |
| 1912 | readChildMetadata?: Parameters<typeof withCodexReplayChildMetadata>[2], | 1904 | readChildMetadata?: Parameters<typeof withCodexReplayChildMetadata>[2], |
| 1913 | ) => | 1905 | ) => |
| ... | @@ -1915,13 +1907,14 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -1915,13 +1907,14 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 1915 | const fileSystem = yield* FileSystem.FileSystem; | 1907 | const fileSystem = yield* FileSystem.FileSystem; |
| 1916 | const idAllocator = yield* IdAllocator.IdAllocatorV2; | 1908 | const idAllocator = yield* IdAllocator.IdAllocatorV2; |
| 1917 | const serverConfig = yield* makeReplayServerConfig(transcript.scenario).pipe(Effect.orDie); | 1909 | const serverConfig = yield* makeReplayServerConfig(transcript.scenario).pipe(Effect.orDie); |
| 1918 | const continuationRequests: Array<ProviderContinuationRequest> = []; | 1910 | const continuationRequests: Array<ProviderContinuationRequests.ProviderContinuationRequest> = |
| 1911 | []; | ||
| 1919 | const clientFactory: CodexAdapterV2.CodexAppServerClientFactoryShape = { | 1912 | const clientFactory: CodexAdapterV2.CodexAppServerClientFactoryShape = { |
| 1920 | open: (openInput) => | 1913 | open: (openInput) => |
| 1921 | Layer.build(CodexReplay.layerReplay(transcript)).pipe( | 1914 | Layer.build(CodexReplay.layerReplay(transcript)).pipe( |
| 1922 | Effect.mapError( | 1915 | Effect.mapError( |
| 1923 | (cause) => | 1916 | (cause) => |
| 1924 | new ProviderAdapterOpenSessionError({ | 1917 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 1925 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, | 1918 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, |
| 1926 | providerSessionId: openInput.providerSessionId, | 1919 | providerSessionId: openInput.providerSessionId, |
| 1927 | cause, | 1920 | cause, |
| ... | @@ -1975,7 +1968,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -1975,7 +1968,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 1975 | modelSelection: CODEX_TEST_MODEL_SELECTION, | 1968 | modelSelection: CODEX_TEST_MODEL_SELECTION, |
| 1976 | runtimePolicy: CODEX_TEST_RUNTIME_POLICY, | 1969 | runtimePolicy: CODEX_TEST_RUNTIME_POLICY, |
| 1977 | }); | 1970 | }); |
| 1978 | const events: Array<ProviderAdapterV2Event> = []; | 1971 | const events: Array<ProviderAdapter.ProviderAdapterV2Event> = []; |
| 1979 | const firstTerminal = yield* Deferred.make<void>(); | 1972 | const firstTerminal = yield* Deferred.make<void>(); |
| 1980 | yield* runtime.events.pipe( | 1973 | yield* runtime.events.pipe( |
| 1981 | Stream.runForEach((event) => | 1974 | Stream.runForEach((event) => |
| ... | @@ -1998,13 +1991,19 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -1998,13 +1991,19 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 1998 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; | 1991 | const hasPendingBackgroundWork = runtime.hasPendingBackgroundWork; |
| 1999 | const terminalEvents = () => | 1992 | const terminalEvents = () => |
| 2000 | events.filter( | 1993 | events.filter( |
| 2001 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 1994 | ( |
| 1995 | event, | ||
| 1996 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 2002 | event.type === "turn.terminal", | 1997 | event.type === "turn.terminal", |
| 2003 | ); | 1998 | ); |
| 2004 | const subagentUpdates = () => | 1999 | const subagentUpdates = () => |
| 2005 | events.filter( | 2000 | events.filter( |
| 2006 | (event): event is Extract<ProviderAdapterV2Event, { type: "subagent.updated" }> => | 2001 | ( |
| 2007 | event.type === "subagent.updated", | 2002 | event, |
| 2003 | ): event is Extract< | ||
| 2004 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 2005 | { type: "subagent.updated" } | ||
| 2006 | > => event.type === "subagent.updated", | ||
| 2008 | ); | 2007 | ); |
| 2009 | return { | 2008 | return { |
| 2010 | runtime, | 2009 | runtime, |
| ... | @@ -2026,7 +2025,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -2026,7 +2025,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 2026 | Effect.gen(function* () { | 2025 | Effect.gen(function* () { |
| 2027 | const nativeThreadId = `inject-${response}`; | 2026 | const nativeThreadId = `inject-${response}`; |
| 2028 | const prompt = "Only the current request"; | 2027 | const prompt = "Only the current request"; |
| 2029 | const history: ProviderAdapterV2HistoricalContext = { | 2028 | const history: ProviderAdapter.ProviderAdapterV2HistoricalContext = { |
| 2030 | context: "Historical conversation", | 2029 | context: "Historical conversation", |
| 2031 | messages: (["user", "assistant"] as const).map((role) => ({ | 2030 | messages: (["user", "assistant"] as const).map((role) => ({ |
| 2032 | role, | 2031 | role, |
| ... | @@ -2528,12 +2527,14 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -2528,12 +2527,14 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 2528 | }).pipe(Effect.scoped, Effect.provide(Layer.merge(IdAllocator.layer, NodeServices.layer))), | 2527 | }).pipe(Effect.scoped, Effect.provide(Layer.merge(IdAllocator.layer, NodeServices.layer))), |
| 2529 | ); | 2528 | ); |
| 2530 | 2529 | ||
| 2531 | const assistantMessages = (events: ReadonlyArray<ProviderAdapterV2Event>) => | 2530 | const assistantMessages = (events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 2532 | events.filter( | 2531 | events.filter( |
| 2533 | (event): event is Extract<ProviderAdapterV2Event, { type: "message.updated" }> => | 2532 | ( |
| 2533 | event, | ||
| 2534 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "message.updated" }> => | ||
| 2534 | event.type === "message.updated" && event.message.role === "assistant", | 2535 | event.type === "message.updated" && event.message.role === "assistant", |
| 2535 | ); | 2536 | ); |
| 2536 | const assistantTurnItems = (events: ReadonlyArray<ProviderAdapterV2Event>) => | 2537 | const assistantTurnItems = (events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 2537 | events.flatMap((event) => | 2538 | events.flatMap((event) => |
| 2538 | event.type === "turn_item.updated" && event.turnItem.type === "assistant_message" | 2539 | event.type === "turn_item.updated" && event.turnItem.type === "assistant_message" |
| 2539 | ? [event.turnItem] | 2540 | ? [event.turnItem] |
| ... | @@ -4914,8 +4915,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -4914,8 +4915,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 4914 | ); | 4915 | ); |
| 4915 | 4916 | ||
| 4916 | const providerTurnId = harness.events.find( | 4917 | const providerTurnId = harness.events.find( |
| 4917 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 4918 | ( |
| 4918 | event.type === "provider_turn.updated", | 4919 | event, |
| 4920 | ): event is Extract< | ||
| 4921 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 4922 | { type: "provider_turn.updated" } | ||
| 4923 | > => event.type === "provider_turn.updated", | ||
| 4919 | )?.providerTurn.id; | 4924 | )?.providerTurn.id; |
| 4920 | assert.isDefined(providerTurnId); | 4925 | assert.isDefined(providerTurnId); |
| 4921 | 4926 | ||
| ... | @@ -4931,7 +4936,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -4931,7 +4936,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 4931 | assert.isAtLeast(terminalIndex, 0); | 4936 | assert.isAtLeast(terminalIndex, 0); |
| 4932 | 4937 | ||
| 4933 | let lastCommandBeforeTerminal: | 4938 | let lastCommandBeforeTerminal: |
| 4934 | | Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }> | 4939 | | Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn_item.updated" }> |
| 4935 | | undefined; | 4940 | | undefined; |
| 4936 | for (let index = 0; index < terminalIndex; index++) { | 4941 | for (let index = 0; index < terminalIndex; index++) { |
| 4937 | const event = harness.events[index]; | 4942 | const event = harness.events[index]; |
| ... | @@ -4997,8 +5002,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -4997,8 +5002,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 4997 | ); | 5002 | ); |
| 4998 | 5003 | ||
| 4999 | const commandUpdates = harness.events.filter( | 5004 | const commandUpdates = harness.events.filter( |
| 5000 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }> => | 5005 | ( |
| 5001 | event.type === "turn_item.updated" && event.turnItem.type === "command_execution", | 5006 | event, |
| 5007 | ): event is Extract< | ||
| 5008 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5009 | { type: "turn_item.updated" } | ||
| 5010 | > => event.type === "turn_item.updated" && event.turnItem.type === "command_execution", | ||
| 5002 | ); | 5011 | ); |
| 5003 | assert.isAtLeast(commandUpdates.length, 2, "start + interrupt terminalization"); | 5012 | assert.isAtLeast(commandUpdates.length, 2, "start + interrupt terminalization"); |
| 5004 | assert.equal(commandUpdates[commandUpdates.length - 1]?.turnItem.status, "interrupted"); | 5013 | assert.equal(commandUpdates[commandUpdates.length - 1]?.turnItem.status, "interrupted"); |
| ... | @@ -5142,7 +5151,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5142,7 +5151,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5142 | }); | 5151 | }); |
| 5143 | 5152 | ||
| 5144 | const assertChildProviderTerminalBeforeRoot = ( | 5153 | const assertChildProviderTerminalBeforeRoot = ( |
| 5145 | events: ReadonlyArray<ProviderAdapterV2Event>, | 5154 | events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>, |
| 5146 | rootThreadId: ThreadId, | 5155 | rootThreadId: ThreadId, |
| 5147 | ) => { | 5156 | ) => { |
| 5148 | const terminalIndex = events.findIndex((event) => event.type === "turn.terminal"); | 5157 | const terminalIndex = events.findIndex((event) => event.type === "turn.terminal"); |
| ... | @@ -5199,8 +5208,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5199,8 +5208,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5199 | "running child command item", | 5208 | "running child command item", |
| 5200 | ); | 5209 | ); |
| 5201 | const providerTurnId = harness.events.find( | 5210 | const providerTurnId = harness.events.find( |
| 5202 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5211 | ( |
| 5203 | event.type === "provider_turn.updated" && event.threadId === harness.threadId, | 5212 | event, |
| 5213 | ): event is Extract< | ||
| 5214 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5215 | { type: "provider_turn.updated" } | ||
| 5216 | > => event.type === "provider_turn.updated" && event.threadId === harness.threadId, | ||
| 5204 | )?.providerTurn.id; | 5217 | )?.providerTurn.id; |
| 5205 | assert.isDefined(providerTurnId); | 5218 | assert.isDefined(providerTurnId); |
| 5206 | 5219 | ||
| ... | @@ -5212,7 +5225,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5212,7 +5225,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5212 | yield* awaitUntil(() => harness.terminalEvents().length === 1, "interrupted root terminal"); | 5225 | yield* awaitUntil(() => harness.terminalEvents().length === 1, "interrupted root terminal"); |
| 5213 | assert.equal(harness.terminalEvents()[0]?.status, "interrupted"); | 5226 | assert.equal(harness.terminalEvents()[0]?.status, "interrupted"); |
| 5214 | const childCommandUpdates = harness.events.filter( | 5227 | const childCommandUpdates = harness.events.filter( |
| 5215 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }> => | 5228 | ( |
| 5229 | event, | ||
| 5230 | ): event is Extract< | ||
| 5231 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5232 | { type: "turn_item.updated" } | ||
| 5233 | > => | ||
| 5216 | event.type === "turn_item.updated" && | 5234 | event.type === "turn_item.updated" && |
| 5217 | event.turnItem.type === "command_execution" && | 5235 | event.turnItem.type === "command_execution" && |
| 5218 | event.turnItem.nativeItemRef?.nativeId === INTERRUPT_CHILD_COMMAND_ITEM, | 5236 | event.turnItem.nativeItemRef?.nativeId === INTERRUPT_CHILD_COMMAND_ITEM, |
| ... | @@ -5289,8 +5307,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5289,8 +5307,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5289 | "running child command item", | 5307 | "running child command item", |
| 5290 | ); | 5308 | ); |
| 5291 | const providerTurnId = harness.events.find( | 5309 | const providerTurnId = harness.events.find( |
| 5292 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5310 | ( |
| 5293 | event.type === "provider_turn.updated" && event.threadId === harness.threadId, | 5311 | event, |
| 5312 | ): event is Extract< | ||
| 5313 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5314 | { type: "provider_turn.updated" } | ||
| 5315 | > => event.type === "provider_turn.updated" && event.threadId === harness.threadId, | ||
| 5294 | )?.providerTurn.id; | 5316 | )?.providerTurn.id; |
| 5295 | assert.isDefined(providerTurnId); | 5317 | assert.isDefined(providerTurnId); |
| 5296 | 5318 | ||
| ... | @@ -5361,8 +5383,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5361,8 +5383,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5361 | "running child command item", | 5383 | "running child command item", |
| 5362 | ); | 5384 | ); |
| 5363 | const providerTurnId = harness.events.find( | 5385 | const providerTurnId = harness.events.find( |
| 5364 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5386 | ( |
| 5365 | event.type === "provider_turn.updated" && event.threadId === harness.threadId, | 5387 | event, |
| 5388 | ): event is Extract< | ||
| 5389 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5390 | { type: "provider_turn.updated" } | ||
| 5391 | > => event.type === "provider_turn.updated" && event.threadId === harness.threadId, | ||
| 5366 | )?.providerTurn.id; | 5392 | )?.providerTurn.id; |
| 5367 | assert.isDefined(providerTurnId); | 5393 | assert.isDefined(providerTurnId); |
| 5368 | 5394 | ||
| ... | @@ -5460,8 +5486,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5460,8 +5486,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5460 | "running child command item", | 5486 | "running child command item", |
| 5461 | ); | 5487 | ); |
| 5462 | const providerTurnId = harness.events.find( | 5488 | const providerTurnId = harness.events.find( |
| 5463 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5489 | ( |
| 5464 | event.type === "provider_turn.updated" && event.threadId === harness.threadId, | 5490 | event, |
| 5491 | ): event is Extract< | ||
| 5492 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5493 | { type: "provider_turn.updated" } | ||
| 5494 | > => event.type === "provider_turn.updated" && event.threadId === harness.threadId, | ||
| 5465 | )?.providerTurn.id; | 5495 | )?.providerTurn.id; |
| 5466 | assert.isDefined(providerTurnId); | 5496 | assert.isDefined(providerTurnId); |
| 5467 | 5497 | ||
| ... | @@ -5481,7 +5511,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5481,7 +5511,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5481 | 5511 | ||
| 5482 | yield* awaitUntil(() => harness.terminalEvents().length === 1, "interrupted root terminal"); | 5512 | yield* awaitUntil(() => harness.terminalEvents().length === 1, "interrupted root terminal"); |
| 5483 | const lateChildUpdates = harness.events.filter( | 5513 | const lateChildUpdates = harness.events.filter( |
| 5484 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5514 | ( |
| 5515 | event, | ||
| 5516 | ): event is Extract< | ||
| 5517 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5518 | { type: "provider_turn.updated" } | ||
| 5519 | > => | ||
| 5485 | event.type === "provider_turn.updated" && | 5520 | event.type === "provider_turn.updated" && |
| 5486 | event.providerTurn.nativeTurnRef?.nativeId === INTERRUPT_LATE_CHILD_NATIVE_TURN, | 5521 | event.providerTurn.nativeTurnRef?.nativeId === INTERRUPT_LATE_CHILD_NATIVE_TURN, |
| 5487 | ); | 5522 | ); |
| ... | @@ -5589,8 +5624,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5589,8 +5624,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5589 | "running child command item", | 5624 | "running child command item", |
| 5590 | ); | 5625 | ); |
| 5591 | const providerTurnId = harness.events.find( | 5626 | const providerTurnId = harness.events.find( |
| 5592 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5627 | ( |
| 5593 | event.type === "provider_turn.updated" && event.threadId === harness.threadId, | 5628 | event, |
| 5629 | ): event is Extract< | ||
| 5630 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5631 | { type: "provider_turn.updated" } | ||
| 5632 | > => event.type === "provider_turn.updated" && event.threadId === harness.threadId, | ||
| 5594 | )?.providerTurn.id; | 5633 | )?.providerTurn.id; |
| 5595 | assert.isDefined(providerTurnId); | 5634 | assert.isDefined(providerTurnId); |
| 5596 | 5635 | ||
| ... | @@ -5835,8 +5874,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5835,8 +5874,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5835 | "running command item", | 5874 | "running command item", |
| 5836 | ); | 5875 | ); |
| 5837 | const providerTurnId = harness.events.find( | 5876 | const providerTurnId = harness.events.find( |
| 5838 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 5877 | ( |
| 5839 | event.type === "provider_turn.updated", | 5878 | event, |
| 5879 | ): event is Extract< | ||
| 5880 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5881 | { type: "provider_turn.updated" } | ||
| 5882 | > => event.type === "provider_turn.updated", | ||
| 5840 | )?.providerTurn.id; | 5883 | )?.providerTurn.id; |
| 5841 | assert.isDefined(providerTurnId); | 5884 | assert.isDefined(providerTurnId); |
| 5842 | 5885 | ||
| ... | @@ -5868,8 +5911,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5868,8 +5911,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5868 | assert.lengthOf(terminalProviderTurnsBeforeLateEvents, 1); | 5911 | assert.lengthOf(terminalProviderTurnsBeforeLateEvents, 1); |
| 5869 | 5912 | ||
| 5870 | const commandUpdatesBeforeLateEvents = harness.events.filter( | 5913 | const commandUpdatesBeforeLateEvents = harness.events.filter( |
| 5871 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }> => | 5914 | ( |
| 5872 | event.type === "turn_item.updated" && event.turnItem.type === "command_execution", | 5915 | event, |
| 5916 | ): event is Extract< | ||
| 5917 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 5918 | { type: "turn_item.updated" } | ||
| 5919 | > => event.type === "turn_item.updated" && event.turnItem.type === "command_execution", | ||
| 5873 | ); | 5920 | ); |
| 5874 | const terminalCommands = commandUpdatesBeforeLateEvents.filter( | 5921 | const terminalCommands = commandUpdatesBeforeLateEvents.filter( |
| 5875 | (event) => | 5922 | (event) => |
| ... | @@ -5993,8 +6040,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -5993,8 +6040,12 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 5993 | "running command item", | 6040 | "running command item", |
| 5994 | ); | 6041 | ); |
| 5995 | const providerTurnId = harness.events.find( | 6042 | const providerTurnId = harness.events.find( |
| 5996 | (event): event is Extract<ProviderAdapterV2Event, { type: "provider_turn.updated" }> => | 6043 | ( |
| 5997 | event.type === "provider_turn.updated", | 6044 | event, |
| 6045 | ): event is Extract< | ||
| 6046 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 6047 | { type: "provider_turn.updated" } | ||
| 6048 | > => event.type === "provider_turn.updated", | ||
| 5998 | )?.providerTurn.id; | 6049 | )?.providerTurn.id; |
| 5999 | assert.isDefined(providerTurnId); | 6050 | assert.isDefined(providerTurnId); |
| 6000 | 6051 | ||
| ... | @@ -7663,7 +7714,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -7663,7 +7714,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 7663 | }), | 7714 | }), |
| 7664 | ); | 7715 | ); |
| 7665 | 7716 | ||
| 7666 | assert.instanceOf(error, ProviderAdapterRollbackThreadError); | 7717 | assert.instanceOf(error, ProviderAdapter.ProviderAdapterRollbackThreadError); |
| 7667 | assert.include( | 7718 | assert.include( |
| 7668 | errorCauseChainText(error), | 7719 | errorCauseChainText(error), |
| 7669 | "legacy", | 7720 | "legacy", |
| ... | @@ -7904,7 +7955,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -7904,7 +7955,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 7904 | }), | 7955 | }), |
| 7905 | ); | 7956 | ); |
| 7906 | 7957 | ||
| 7907 | assert.instanceOf(error, ProviderAdapterForkThreadError); | 7958 | assert.instanceOf(error, ProviderAdapter.ProviderAdapterForkThreadError); |
| 7908 | assert.include( | 7959 | assert.include( |
| 7909 | errorCauseChainText(error), | 7960 | errorCauseChainText(error), |
| 7910 | "legacy", | 7961 | "legacy", |
| ... | @@ -7969,7 +8020,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -7969,7 +8020,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 7969 | }), | 8020 | }), |
| 7970 | ); | 8021 | ); |
| 7971 | 8022 | ||
| 7972 | assert.instanceOf(error, ProviderAdapterForkThreadError); | 8023 | assert.instanceOf(error, ProviderAdapter.ProviderAdapterForkThreadError); |
| 7973 | assert.include(errorCauseChainText(error), "fork exploded"); | 8024 | assert.include(errorCauseChainText(error), "fork exploded"); |
| 7974 | }).pipe(Effect.scoped, Effect.provide(Layer.merge(IdAllocator.layer, NodeServices.layer))), | 8025 | }).pipe(Effect.scoped, Effect.provide(Layer.merge(IdAllocator.layer, NodeServices.layer))), |
| 7975 | ); | 8026 | ); |
| ... | @@ -8033,7 +8084,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { | ... | @@ -8033,7 +8084,7 @@ describe("CodexAdapterV2 post-settle continuation", () => { |
| 8033 | }), | 8084 | }), |
| 8034 | ), | 8085 | ), |
| 8035 | ); | 8086 | ); |
| 8036 | const providerGoals = (events: ReadonlyArray<ProviderAdapterV2Event>) => | 8087 | const providerGoals = (events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 8037 | events.flatMap((event) => | 8088 | events.flatMap((event) => |
| 8038 | event.type === "provider_thread.updated" ? [event.providerThread.goal?.status ?? null] : [], | 8089 | event.type === "provider_thread.updated" ? [event.providerThread.goal?.status ?? null] : [], |
| 8039 | ); | 8090 | ); |
apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.testkit.ts+2-2| ... | @@ -15,7 +15,7 @@ import * as Schema from "effect/Schema"; | ... | @@ -15,7 +15,7 @@ import * as Schema from "effect/Schema"; |
| 15 | 15 | ||
| 16 | import * as ServerConfig from "../../config.ts"; | 16 | import * as ServerConfig from "../../config.ts"; |
| 17 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 17 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 18 | import { ProviderAdapterOpenSessionError } from "@t3tools/provider-core/server/ProviderAdapter"; | 18 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 19 | import { ProviderAdapterDriverCreateError } from "@t3tools/provider-core/server/adapterDriver"; | 19 | import { ProviderAdapterDriverCreateError } from "@t3tools/provider-core/server/adapterDriver"; |
| 20 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 20 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 21 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; | 21 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; |
| ... | @@ -195,7 +195,7 @@ export function layer(input: { | ... | @@ -195,7 +195,7 @@ export function layer(input: { |
| 195 | const context = yield* Layer.build(layerReplay).pipe( | 195 | const context = yield* Layer.build(layerReplay).pipe( |
| 196 | Effect.mapError( | 196 | Effect.mapError( |
| 197 | (cause) => | 197 | (cause) => |
| 198 | new ProviderAdapterOpenSessionError({ | 198 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 199 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, | 199 | driver: CodexAdapterV2.CODEX_DRIVER_KIND, |
| 200 | providerSessionId: openInput.providerSessionId, | 200 | providerSessionId: openInput.providerSessionId, |
| 201 | cause, | 201 | cause, |
apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts+102-106| ... | @@ -102,10 +102,9 @@ import { | ... | @@ -102,10 +102,9 @@ import { |
| 102 | } from "../../provider/Drivers/CodexHomeLayout.ts"; | 102 | } from "../../provider/Drivers/CodexHomeLayout.ts"; |
| 103 | import { | 103 | import { |
| 104 | boundProviderEventForLogging, | 104 | boundProviderEventForLogging, |
| 105 | type EventNdjsonLogger, | ||
| 106 | shouldPersistProviderEvent, | 105 | shouldPersistProviderEvent, |
| 107 | } from "../../provider/EventNdjsonLogger.ts"; | 106 | } from "../../provider/EventNdjsonLogger.ts"; |
| 108 | import { ProviderEventLoggers } from "../../provider/ProviderEventLoggers.ts"; | 107 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 109 | import { codexAppServerArgs, resolveCodexLaunchArgs } from "../../provider/codexLaunchArgs.ts"; | 108 | import { codexAppServerArgs, resolveCodexLaunchArgs } from "../../provider/codexLaunchArgs.ts"; |
| 110 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; | 109 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; |
| 111 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; | 110 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; |
| ... | @@ -121,11 +120,7 @@ import { | ... | @@ -121,11 +120,7 @@ import { |
| 121 | type ProviderAdapterDriver, | 120 | type ProviderAdapterDriver, |
| 122 | type ProviderAdapterDriverCreateInput, | 121 | type ProviderAdapterDriverCreateInput, |
| 123 | } from "@t3tools/provider-core/server/adapterDriver"; | 122 | } from "@t3tools/provider-core/server/adapterDriver"; |
| 124 | import { IdAllocatorV2, type IdAllocatorV2Shape } from "@t3tools/provider-core/server/IdAllocator"; | 123 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 125 | import { | ||
| 126 | type ProviderContinuationRequest, | ||
| 127 | ProviderContinuationRequests, | ||
| 128 | } from "@t3tools/provider-core/server/continuationRequests"; | ||
| 129 | import { backgroundWorkNotification } from "@t3tools/provider-core/server/notification"; | 124 | import { backgroundWorkNotification } from "@t3tools/provider-core/server/notification"; |
| 130 | import { | 125 | import { |
| 131 | makeProviderFailure, | 126 | makeProviderFailure, |
| ... | @@ -137,35 +132,13 @@ import { | ... | @@ -137,35 +132,13 @@ import { |
| 137 | isProviderNativeImageAttachment, | 132 | isProviderNativeImageAttachment, |
| 138 | providerMessageTextWithAttachmentPaths, | 133 | providerMessageTextWithAttachmentPaths, |
| 139 | } from "@t3tools/provider-core/server/attachmentPrompt"; | 134 | } from "@t3tools/provider-core/server/attachmentPrompt"; |
| 140 | import { | ||
| 141 | ProviderAdapterEnsureThreadError, | ||
| 142 | ProviderAdapterForkThreadError, | ||
| 143 | ProviderAdapterInterruptError, | ||
| 144 | ProviderAdapterOpenSessionError, | ||
| 145 | ProviderAdapterProtocolError, | ||
| 146 | ProviderAdapterReadThreadSnapshotError, | ||
| 147 | ProviderAdapterResumeThreadError, | ||
| 148 | ProviderAdapterRollbackThreadError, | ||
| 149 | ProviderAdapterRuntimeRequestResponseError, | ||
| 150 | ProviderAdapterSteerRunError, | ||
| 151 | ProviderAdapterTurnStartError, | ||
| 152 | ProviderAdapterV2, | ||
| 153 | type ProviderAdapterV2Shape, | ||
| 154 | type ProviderAdapterV2Event, | ||
| 155 | type ProviderAdapterV2ForkThreadInput, | ||
| 156 | type ProviderAdapterV2RollbackThreadInput, | ||
| 157 | type ProviderAdapterV2RuntimePolicy, | ||
| 158 | type ProviderAdapterV2McpApps, | ||
| 159 | type ProviderAdapterV2SessionRuntime, | ||
| 160 | type ProviderAdapterV2InterruptInput, | ||
| 161 | type ProviderAdapterV2SteerInput, | ||
| 162 | type ProviderAdapterV2TurnInput, | ||
| 163 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 164 | import { | 135 | import { |
| 165 | makeSubagentChildThread, | 136 | makeSubagentChildThread, |
| 166 | makeSubagentConversationArtifacts, | 137 | makeSubagentConversationArtifacts, |
| 167 | subagentThreadTitle, | 138 | subagentThreadTitle, |
| 168 | } from "@t3tools/provider-core/server/subagentProjection"; | 139 | } from "@t3tools/provider-core/server/subagentProjection"; |
| 140 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | ||
| 141 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 169 | 142 | ||
| 170 | const CODEX_PROVIDER = ProviderDriverKind.make("codex"); | 143 | const CODEX_PROVIDER = ProviderDriverKind.make("codex"); |
| 171 | export const CODEX_DRIVER_KIND = CODEX_PROVIDER; | 144 | export const CODEX_DRIVER_KIND = CODEX_PROVIDER; |
| ... | @@ -341,8 +314,11 @@ export const CodexProviderCapabilitiesV2 = { | ... | @@ -341,8 +314,11 @@ export const CodexProviderCapabilitiesV2 = { |
| 341 | }, | 314 | }, |
| 342 | } satisfies OrchestrationV2ProviderCapabilities; | 315 | } satisfies OrchestrationV2ProviderCapabilities; |
| 343 | 316 | ||
| 344 | function toProtocolError(detail: string, payload?: unknown): ProviderAdapterProtocolError { | 317 | function toProtocolError( |
| 345 | return new ProviderAdapterProtocolError({ | 318 | detail: string, |
| 319 | payload?: unknown, | ||
| 320 | ): ProviderAdapter.ProviderAdapterProtocolError { | ||
| 321 | return new ProviderAdapter.ProviderAdapterProtocolError({ | ||
| 346 | driver: CODEX_PROVIDER, | 322 | driver: CODEX_PROVIDER, |
| 347 | detail, | 323 | detail, |
| 348 | ...(payload === undefined ? {} : { payload }), | 324 | ...(payload === undefined ? {} : { payload }), |
| ... | @@ -385,7 +361,7 @@ function mapCodexTurnStatus( | ... | @@ -385,7 +361,7 @@ function mapCodexTurnStatus( |
| 385 | 361 | ||
| 386 | function providerTurnStatusToTerminal( | 362 | function providerTurnStatusToTerminal( |
| 387 | status: OrchestrationV2ProviderTurn["status"], | 363 | status: OrchestrationV2ProviderTurn["status"], |
| 388 | ): Extract<ProviderAdapterV2Event, { type: "turn.terminal" }>["status"] { | 364 | ): Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }>["status"] { |
| 389 | switch (status) { | 365 | switch (status) { |
| 390 | case "completed": | 366 | case "completed": |
| 391 | return "completed"; | 367 | return "completed"; |
| ... | @@ -677,7 +653,7 @@ const decodeCodexTurnStartParamsWithCollaborationMode = Schema.decodeUnknownEffe | ... | @@ -677,7 +653,7 @@ const decodeCodexTurnStartParamsWithCollaborationMode = Schema.decodeUnknownEffe |
| 677 | CodexTurnStartParamsWithCollaborationMode, | 653 | CodexTurnStartParamsWithCollaborationMode, |
| 678 | ); | 654 | ); |
| 679 | const isProviderAdapterRuntimeRequestResponseError = Schema.is( | 655 | const isProviderAdapterRuntimeRequestResponseError = Schema.is( |
| 680 | ProviderAdapterRuntimeRequestResponseError, | 656 | ProviderAdapter.ProviderAdapterRuntimeRequestResponseError, |
| 681 | ); | 657 | ); |
| 682 | 658 | ||
| 683 | function codexRuntimeModeTurnDefaults(runtimeMode: RuntimeMode): { | 659 | function codexRuntimeModeTurnDefaults(runtimeMode: RuntimeMode): { |
| ... | @@ -724,7 +700,7 @@ function codexRuntimeModeTurnDefaults(runtimeMode: RuntimeMode): { | ... | @@ -724,7 +700,7 @@ function codexRuntimeModeTurnDefaults(runtimeMode: RuntimeMode): { |
| 724 | export function buildCodexTurnStartParams(input: { | 700 | export function buildCodexTurnStartParams(input: { |
| 725 | readonly nativeThreadId: string; | 701 | readonly nativeThreadId: string; |
| 726 | readonly codexInput: ReadonlyArray<CodexSchema.V2TurnStartParams__UserInput>; | 702 | readonly codexInput: ReadonlyArray<CodexSchema.V2TurnStartParams__UserInput>; |
| 727 | readonly runtimePolicy: ProviderAdapterV2RuntimePolicy; | 703 | readonly runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 728 | readonly modelSelection: ModelSelection; | 704 | readonly modelSelection: ModelSelection; |
| 729 | readonly hasT3Mcp?: boolean; | 705 | readonly hasT3Mcp?: boolean; |
| 730 | readonly browserToolsAvailable?: boolean; | 706 | readonly browserToolsAvailable?: boolean; |
| ... | @@ -732,7 +708,7 @@ export function buildCodexTurnStartParams(input: { | ... | @@ -732,7 +708,7 @@ export function buildCodexTurnStartParams(input: { |
| 732 | /** ChatGPT token sharing does not accept service tiers. */ | 708 | /** ChatGPT token sharing does not accept service tiers. */ |
| 733 | readonly omitServiceTier?: boolean; | 709 | readonly omitServiceTier?: boolean; |
| 734 | /** What the thread's MCP Apps want the agent to know (`ui/update-model-context`). */ | 710 | /** What the thread's MCP Apps want the agent to know (`ui/update-model-context`). */ |
| 735 | readonly appContext?: ProviderAdapterV2TurnInput["appContext"]; | 711 | readonly appContext?: ProviderAdapter.ProviderAdapterV2TurnInput["appContext"]; |
| 736 | }) { | 712 | }) { |
| 737 | return Effect.gen(function* () { | 713 | return Effect.gen(function* () { |
| 738 | const runtimeModeDefaults = codexRuntimeModeTurnDefaults(input.runtimePolicy.runtimeMode); | 714 | const runtimeModeDefaults = codexRuntimeModeTurnDefaults(input.runtimePolicy.runtimeMode); |
| ... | @@ -851,7 +827,7 @@ function getNativeThreadId(providerThread: OrchestrationV2ProviderThread) { | ... | @@ -851,7 +827,7 @@ function getNativeThreadId(providerThread: OrchestrationV2ProviderThread) { |
| 851 | 827 | ||
| 852 | function providerThreadFromCodexThread(input: { | 828 | function providerThreadFromCodexThread(input: { |
| 853 | readonly appThreadId: ThreadId | null; | 829 | readonly appThreadId: ThreadId | null; |
| 854 | readonly idAllocator: IdAllocatorV2Shape; | 830 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 855 | readonly ownerNodeId: OrchestrationV2ProviderThread["ownerNodeId"]; | 831 | readonly ownerNodeId: OrchestrationV2ProviderThread["ownerNodeId"]; |
| 856 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; | 832 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; |
| 857 | readonly providerInstanceId: ProviderInstanceId; | 833 | readonly providerInstanceId: ProviderInstanceId; |
| ... | @@ -983,7 +959,7 @@ const countTerminalTurnsAfterBoundary = ( | ... | @@ -983,7 +959,7 @@ const countTerminalTurnsAfterBoundary = ( |
| 983 | }; | 959 | }; |
| 984 | 960 | ||
| 985 | const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkRollbackTurnCount")( | 961 | const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkRollbackTurnCount")( |
| 986 | function* (input: ProviderAdapterV2ForkThreadInput) { | 962 | function* (input: ProviderAdapter.ProviderAdapterV2ForkThreadInput) { |
| 987 | if (input.providerTurnId === undefined || input.sourceProviderTurns === undefined) { | 963 | if (input.providerTurnId === undefined || input.sourceProviderTurns === undefined) { |
| 988 | return 0; | 964 | return 0; |
| 989 | } | 965 | } |
| ... | @@ -993,7 +969,7 @@ const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkR | ... | @@ -993,7 +969,7 @@ const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkR |
| 993 | input.providerTurnId, | 969 | input.providerTurnId, |
| 994 | ); | 970 | ); |
| 995 | if (rollbackTurnCount === null) { | 971 | if (rollbackTurnCount === null) { |
| 996 | return yield* new ProviderAdapterForkThreadError({ | 972 | return yield* new ProviderAdapter.ProviderAdapterForkThreadError({ |
| 997 | driver: CODEX_PROVIDER, | 973 | driver: CODEX_PROVIDER, |
| 998 | providerThreadId: input.sourceProviderThread.id, | 974 | providerThreadId: input.sourceProviderThread.id, |
| 999 | cause: `Cannot fork Codex thread from provider turn ${input.providerTurnId}: source turn was not found in provider thread ${input.sourceProviderThread.id}.`, | 975 | cause: `Cannot fork Codex thread from provider turn ${input.providerTurnId}: source turn was not found in provider thread ${input.sourceProviderThread.id}.`, |
| ... | @@ -1012,7 +988,7 @@ const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkR | ... | @@ -1012,7 +988,7 @@ const resolveCodexForkRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveForkR |
| 1012 | * only for source turns that predate native turn references. | 988 | * only for source turns that predate native turn references. |
| 1013 | */ | 989 | */ |
| 1014 | export const resolveCodexForkBoundary = Effect.fn("CodexAdapterV2.resolveForkBoundary")(function* ( | 990 | export const resolveCodexForkBoundary = Effect.fn("CodexAdapterV2.resolveForkBoundary")(function* ( |
| 1015 | input: ProviderAdapterV2ForkThreadInput, | 991 | input: ProviderAdapter.ProviderAdapterV2ForkThreadInput, |
| 1016 | ) { | 992 | ) { |
| 1017 | const rollbackTurnCount = yield* resolveCodexForkRollbackTurnCount(input); | 993 | const rollbackTurnCount = yield* resolveCodexForkRollbackTurnCount(input); |
| 1018 | if (input.providerTurnId === undefined || input.sourceProviderTurns === undefined) { | 994 | if (input.providerTurnId === undefined || input.sourceProviderTurns === undefined) { |
| ... | @@ -1066,14 +1042,14 @@ const readCodexThreadHistoryMetadata = Effect.fn("CodexAdapterV2.readThreadHisto | ... | @@ -1066,14 +1042,14 @@ const readCodexThreadHistoryMetadata = Effect.fn("CodexAdapterV2.readThreadHisto |
| 1066 | ); | 1042 | ); |
| 1067 | 1043 | ||
| 1068 | export const resolveCodexRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveRollbackTurnCount")( | 1044 | export const resolveCodexRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveRollbackTurnCount")( |
| 1069 | function* (input: ProviderAdapterV2RollbackThreadInput) { | 1045 | function* (input: ProviderAdapter.ProviderAdapterV2RollbackThreadInput) { |
| 1070 | const providerTurns = input.providerThreadTurns; | 1046 | const providerTurns = input.providerThreadTurns; |
| 1071 | switch (input.target.type) { | 1047 | switch (input.target.type) { |
| 1072 | case "thread_start": | 1048 | case "thread_start": |
| 1073 | return providerTurns.filter(isTerminalProviderTurn).length; | 1049 | return providerTurns.filter(isTerminalProviderTurn).length; |
| 1074 | case "provider_turn": { | 1050 | case "provider_turn": { |
| 1075 | if (input.target.providerTurn.providerThreadId !== input.providerThread.id) { | 1051 | if (input.target.providerTurn.providerThreadId !== input.providerThread.id) { |
| 1076 | return yield* new ProviderAdapterRollbackThreadError({ | 1052 | return yield* new ProviderAdapter.ProviderAdapterRollbackThreadError({ |
| 1077 | driver: CODEX_PROVIDER, | 1053 | driver: CODEX_PROVIDER, |
| 1078 | providerThreadId: input.providerThread.id, | 1054 | providerThreadId: input.providerThread.id, |
| 1079 | cause: `Cannot roll back Codex thread ${input.providerThread.id} to provider turn ${input.target.providerTurn.id}: target turn belongs to provider thread ${input.target.providerTurn.providerThreadId}.`, | 1055 | cause: `Cannot roll back Codex thread ${input.providerThread.id} to provider turn ${input.target.providerTurn.id}: target turn belongs to provider thread ${input.target.providerTurn.providerThreadId}.`, |
| ... | @@ -1085,7 +1061,7 @@ export const resolveCodexRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveRo | ... | @@ -1085,7 +1061,7 @@ export const resolveCodexRollbackTurnCount = Effect.fn("CodexAdapterV2.resolveRo |
| 1085 | input.target.providerTurn.id, | 1061 | input.target.providerTurn.id, |
| 1086 | ); | 1062 | ); |
| 1087 | if (rollbackTurnCount === null) { | 1063 | if (rollbackTurnCount === null) { |
| 1088 | return yield* new ProviderAdapterRollbackThreadError({ | 1064 | return yield* new ProviderAdapter.ProviderAdapterRollbackThreadError({ |
| 1089 | driver: CODEX_PROVIDER, | 1065 | driver: CODEX_PROVIDER, |
| 1090 | providerThreadId: input.providerThread.id, | 1066 | providerThreadId: input.providerThread.id, |
| 1091 | cause: `Cannot roll back Codex thread ${input.providerThread.id} to provider turn ${input.target.providerTurn.id}: target turn was not found in durable provider turn history.`, | 1067 | cause: `Cannot roll back Codex thread ${input.providerThread.id} to provider turn ${input.target.providerTurn.id}: target turn was not found in durable provider turn history.`, |
| ... | @@ -1129,10 +1105,10 @@ interface ActiveCodexTurnContext { | ... | @@ -1129,10 +1105,10 @@ interface ActiveCodexTurnContext { |
| 1129 | readonly failure: OrchestrationV2ProviderFailure; | 1105 | readonly failure: OrchestrationV2ProviderFailure; |
| 1130 | }; | 1106 | }; |
| 1131 | readonly nativeStartReady?: Deferred.Deferred<void>; | 1107 | readonly nativeStartReady?: Deferred.Deferred<void>; |
| 1132 | readonly input: ProviderAdapterV2TurnInput; | 1108 | readonly input: ProviderAdapter.ProviderAdapterV2TurnInput; |
| 1133 | readonly projectionAppThread: OrchestrationV2AppThread; | 1109 | readonly projectionAppThread: OrchestrationV2AppThread; |
| 1134 | readonly projectionThreadId: ThreadId; | 1110 | readonly projectionThreadId: ThreadId; |
| 1135 | readonly projectionRunId: ProviderAdapterV2TurnInput["runId"] | null; | 1111 | readonly projectionRunId: ProviderAdapter.ProviderAdapterV2TurnInput["runId"] | null; |
| 1136 | readonly nativeTurnId: string; | 1112 | readonly nativeTurnId: string; |
| 1137 | readonly providerThread: OrchestrationV2ProviderThread; | 1113 | readonly providerThread: OrchestrationV2ProviderThread; |
| 1138 | readonly providerTurnId: ProviderTurnId; | 1114 | readonly providerTurnId: ProviderTurnId; |
| ... | @@ -1177,7 +1153,10 @@ function isPersistentCodexDynamicTool(item: CodexDynamicToolItem): boolean { | ... | @@ -1177,7 +1153,10 @@ function isPersistentCodexDynamicTool(item: CodexDynamicToolItem): boolean { |
| 1177 | return Reflect.get(input, "persistent") === true; | 1153 | return Reflect.get(input, "persistent") === true; |
| 1178 | } | 1154 | } |
| 1179 | 1155 | ||
| 1180 | type CodexRootTerminalEvent = Extract<ProviderAdapterV2Event, { readonly type: "turn.terminal" }>; | 1156 | type CodexRootTerminalEvent = Extract< |
| 1157 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 1158 | { readonly type: "turn.terminal" } | ||
| 1159 | >; | ||
| 1181 | 1160 | ||
| 1182 | /** A completed root turn whose run stays open for the goal turn Codex starts next. */ | 1161 | /** A completed root turn whose run stays open for the goal turn Codex starts next. */ |
| 1183 | interface CodexGoalHold { | 1162 | interface CodexGoalHold { |
| ... | @@ -1294,12 +1273,12 @@ export interface CodexAppServerClientFactoryShape { | ... | @@ -1294,12 +1273,12 @@ export interface CodexAppServerClientFactoryShape { |
| 1294 | readonly instanceId: ProviderInstanceId; | 1273 | readonly instanceId: ProviderInstanceId; |
| 1295 | readonly threadId: ThreadId; | 1274 | readonly threadId: ThreadId; |
| 1296 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; | 1275 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; |
| 1297 | readonly runtimePolicy: ProviderAdapterV2RuntimePolicy; | 1276 | readonly runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 1298 | readonly settings: CodexSettings; | 1277 | readonly settings: CodexSettings; |
| 1299 | readonly environment: NodeJS.ProcessEnv; | 1278 | readonly environment: NodeJS.ProcessEnv; |
| 1300 | }) => Effect.Effect< | 1279 | }) => Effect.Effect< |
| 1301 | CodexClient.CodexAppServerClient["Service"], | 1280 | CodexClient.CodexAppServerClient["Service"], |
| 1302 | ProviderAdapterOpenSessionError, | 1281 | ProviderAdapter.ProviderAdapterOpenSessionError, |
| 1303 | Scope.Scope | 1282 | Scope.Scope |
| 1304 | >; | 1283 | >; |
| 1305 | } | 1284 | } |
| ... | @@ -1319,7 +1298,7 @@ export const CODEX_THREAD_CONFIG = { "tools.update_plan.enabled": true } as cons | ... | @@ -1319,7 +1298,7 @@ export const CODEX_THREAD_CONFIG = { "tools.update_plan.enabled": true } as cons |
| 1319 | export function codexThreadRuntimeParams(input: { | 1298 | export function codexThreadRuntimeParams(input: { |
| 1320 | readonly threadId: ThreadId | null; | 1299 | readonly threadId: ThreadId | null; |
| 1321 | readonly modelSelection?: { readonly model: string }; | 1300 | readonly modelSelection?: { readonly model: string }; |
| 1322 | readonly runtimePolicy?: ProviderAdapterV2RuntimePolicy; | 1301 | readonly runtimePolicy?: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 1323 | }): { | 1302 | }): { |
| 1324 | readonly cwd?: string; | 1303 | readonly cwd?: string; |
| 1325 | readonly model?: string; | 1304 | readonly model?: string; |
| ... | @@ -1417,7 +1396,7 @@ const layerCodexAppServerClientFactoryCommand = ( | ... | @@ -1417,7 +1396,7 @@ const layerCodexAppServerClientFactoryCommand = ( |
| 1417 | Effect.provideService(Scope.Scope, scope), | 1396 | Effect.provideService(Scope.Scope, scope), |
| 1418 | Effect.mapError( | 1397 | Effect.mapError( |
| 1419 | (cause) => | 1398 | (cause) => |
| 1420 | new ProviderAdapterOpenSessionError({ | 1399 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 1421 | driver: CODEX_PROVIDER, | 1400 | driver: CODEX_PROVIDER, |
| 1422 | providerSessionId: input.providerSessionId, | 1401 | providerSessionId: input.providerSessionId, |
| 1423 | cause, | 1402 | cause, |
| ... | @@ -1434,7 +1413,7 @@ const layerCodexAppServerClientFactoryCommand = ( | ... | @@ -1434,7 +1413,7 @@ const layerCodexAppServerClientFactoryCommand = ( |
| 1434 | ); | 1413 | ); |
| 1435 | 1414 | ||
| 1436 | export function makeCodexAppServerProtocolLogger(input: { | 1415 | export function makeCodexAppServerProtocolLogger(input: { |
| 1437 | readonly nativeEventLogger: EventNdjsonLogger | undefined; | 1416 | readonly nativeEventLogger: ProviderEventLoggers.EventNdjsonLogger | undefined; |
| 1438 | readonly threadId: ThreadId; | 1417 | readonly threadId: ThreadId; |
| 1439 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; | 1418 | readonly providerSessionId: OrchestrationV2ProviderSession["id"]; |
| 1440 | }): CodexClient.CodexAppServerClientOptions["logger"] | undefined { | 1419 | }): CodexClient.CodexAppServerClientOptions["logger"] | undefined { |
| ... | @@ -1510,12 +1489,12 @@ function isSensitiveCodexProtocolKey(key: string): boolean { | ... | @@ -1510,12 +1489,12 @@ function isSensitiveCodexProtocolKey(key: string): boolean { |
| 1510 | export const layerAppServerClientFactory: Layer.Layer< | 1489 | export const layerAppServerClientFactory: Layer.Layer< |
| 1511 | CodexAppServerClientFactory, | 1490 | CodexAppServerClientFactory, |
| 1512 | never, | 1491 | never, |
| 1513 | ChildProcessSpawner.ChildProcessSpawner | ProviderEventLoggers | 1492 | ChildProcessSpawner.ChildProcessSpawner | ProviderEventLoggers.ProviderEventLoggers |
| 1514 | > = Layer.effect( | 1493 | > = Layer.effect( |
| 1515 | CodexAppServerClientFactory, | 1494 | CodexAppServerClientFactory, |
| 1516 | Effect.gen(function* () { | 1495 | Effect.gen(function* () { |
| 1517 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; | 1496 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; |
| 1518 | const { native: nativeEventLogger } = yield* ProviderEventLoggers; | 1497 | const { native: nativeEventLogger } = yield* ProviderEventLoggers.ProviderEventLoggers; |
| 1519 | 1498 | ||
| 1520 | return CodexAppServerClientFactory.of({ | 1499 | return CodexAppServerClientFactory.of({ |
| 1521 | open: (input) => | 1500 | open: (input) => |
| ... | @@ -1536,7 +1515,7 @@ export const layerAppServerClientFactory: Layer.Layer< | ... | @@ -1536,7 +1515,7 @@ export const layerAppServerClientFactory: Layer.Layer< |
| 1536 | Effect.provideService(Scope.Scope, scope), | 1515 | Effect.provideService(Scope.Scope, scope), |
| 1537 | Effect.mapError( | 1516 | Effect.mapError( |
| 1538 | (cause) => | 1517 | (cause) => |
| 1539 | new ProviderAdapterOpenSessionError({ | 1518 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 1540 | driver: CODEX_PROVIDER, | 1519 | driver: CODEX_PROVIDER, |
| 1541 | providerSessionId: input.providerSessionId, | 1520 | providerSessionId: input.providerSessionId, |
| 1542 | cause, | 1521 | cause, |
| ... | @@ -1569,7 +1548,7 @@ export type CodexAdapterV2DriverEnv = | ... | @@ -1569,7 +1548,7 @@ export type CodexAdapterV2DriverEnv = |
| 1569 | | CodexAppServerClientFactory | 1548 | | CodexAppServerClientFactory |
| 1570 | | Crypto.Crypto | 1549 | | Crypto.Crypto |
| 1571 | | FileSystem.FileSystem | 1550 | | FileSystem.FileSystem |
| 1572 | | IdAllocatorV2 | 1551 | | IdAllocator.IdAllocatorV2 |
| 1573 | | Path.Path | 1552 | | Path.Path |
| 1574 | | ServerConfig; | 1553 | | ServerConfig; |
| 1575 | 1554 | ||
| ... | @@ -1579,11 +1558,11 @@ export const createCodexAdapterV2 = ( | ... | @@ -1579,11 +1558,11 @@ export const createCodexAdapterV2 = ( |
| 1579 | ) => | 1558 | ) => |
| 1580 | Effect.gen(function* () { | 1559 | Effect.gen(function* () { |
| 1581 | const clientFactory = yield* CodexAppServerClientFactory; | 1560 | const clientFactory = yield* CodexAppServerClientFactory; |
| 1582 | const continuationRequests = yield* ProviderContinuationRequests; | 1561 | const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests; |
| 1583 | const crypto = yield* Crypto.Crypto; | 1562 | const crypto = yield* Crypto.Crypto; |
| 1584 | const fileSystem = yield* FileSystem.FileSystem; | 1563 | const fileSystem = yield* FileSystem.FileSystem; |
| 1585 | const hostEnvironment = yield* HostProcessEnvironment; | 1564 | const hostEnvironment = yield* HostProcessEnvironment; |
| 1586 | const idAllocator = yield* IdAllocatorV2; | 1565 | const idAllocator = yield* IdAllocator.IdAllocatorV2; |
| 1587 | const serverConfig = yield* ServerConfig; | 1566 | const serverConfig = yield* ServerConfig; |
| 1588 | const homeLayout = yield* resolveCodexHomeLayout(config); | 1567 | const homeLayout = yield* resolveCodexHomeLayout(config); |
| 1589 | 1568 | ||
| ... | @@ -1628,18 +1607,22 @@ export const CodexAdapterV2Driver: ProviderAdapterDriver<CodexSettings, CodexAda | ... | @@ -1628,18 +1607,22 @@ export const CodexAdapterV2Driver: ProviderAdapterDriver<CodexSettings, CodexAda |
| 1628 | }; | 1607 | }; |
| 1629 | 1608 | ||
| 1630 | const layer: Layer.Layer< | 1609 | const layer: Layer.Layer< |
| 1631 | ProviderAdapterV2, | 1610 | ProviderAdapter.ProviderAdapterV2, |
| 1632 | never, | 1611 | never, |
| 1633 | CodexAppServerClientFactory | Crypto.Crypto | FileSystem.FileSystem | IdAllocatorV2 | ServerConfig | 1612 | | CodexAppServerClientFactory |
| 1613 | | Crypto.Crypto | ||
| 1614 | | FileSystem.FileSystem | ||
| 1615 | | IdAllocator.IdAllocatorV2 | ||
| 1616 | | ServerConfig | ||
| 1634 | > = Layer.effect( | 1617 | > = Layer.effect( |
| 1635 | ProviderAdapterV2, | 1618 | ProviderAdapter.ProviderAdapterV2, |
| 1636 | Effect.gen(function* () { | 1619 | Effect.gen(function* () { |
| 1637 | const clientFactory = yield* CodexAppServerClientFactory; | 1620 | const clientFactory = yield* CodexAppServerClientFactory; |
| 1638 | const continuationRequests = yield* ProviderContinuationRequests; | 1621 | const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests; |
| 1639 | const crypto = yield* Crypto.Crypto; | 1622 | const crypto = yield* Crypto.Crypto; |
| 1640 | const fileSystem = yield* FileSystem.FileSystem; | 1623 | const fileSystem = yield* FileSystem.FileSystem; |
| 1641 | const hostEnvironment = yield* HostProcessEnvironment; | 1624 | const hostEnvironment = yield* HostProcessEnvironment; |
| 1642 | const idAllocator = yield* IdAllocatorV2; | 1625 | const idAllocator = yield* IdAllocator.IdAllocatorV2; |
| 1643 | const serverConfig = yield* ServerConfig; | 1626 | const serverConfig = yield* ServerConfig; |
| 1644 | 1627 | ||
| 1645 | return makeCodexAdapterV2({ | 1628 | return makeCodexAdapterV2({ |
| ... | @@ -1670,7 +1653,7 @@ export interface CodexAdapterV2Options { | ... | @@ -1670,7 +1653,7 @@ export interface CodexAdapterV2Options { |
| 1670 | readonly resolveRuntime?: Effect.Effect<CodexEffectiveRuntime, ProviderSetupError, Scope.Scope>; | 1653 | readonly resolveRuntime?: Effect.Effect<CodexEffectiveRuntime, ProviderSetupError, Scope.Scope>; |
| 1671 | readonly crypto: Crypto.Crypto; | 1654 | readonly crypto: Crypto.Crypto; |
| 1672 | readonly fileSystem: FileSystem.FileSystem; | 1655 | readonly fileSystem: FileSystem.FileSystem; |
| 1673 | readonly idAllocator: IdAllocatorV2Shape; | 1656 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 1674 | readonly serverConfig: ServerConfig["Service"]; | 1657 | readonly serverConfig: ServerConfig["Service"]; |
| 1675 | /** | 1658 | /** |
| 1676 | * Sink for post-settle background command completions so the orchestrator | 1659 | * Sink for post-settle background command completions so the orchestrator |
| ... | @@ -1678,15 +1661,19 @@ export interface CodexAdapterV2Options { | ... | @@ -1678,15 +1661,19 @@ export interface CodexAdapterV2Options { |
| 1678 | * projection-only handling for late item completions. | 1661 | * projection-only handling for late item completions. |
| 1679 | */ | 1662 | */ |
| 1680 | readonly continuationRequests?: { | 1663 | readonly continuationRequests?: { |
| 1681 | readonly offer: (request: ProviderContinuationRequest) => Effect.Effect<void>; | 1664 | readonly offer: ( |
| 1665 | request: ProviderContinuationRequests.ProviderContinuationRequest, | ||
| 1666 | ) => Effect.Effect<void>; | ||
| 1682 | }; | 1667 | }; |
| 1683 | } | 1668 | } |
| 1684 | 1669 | ||
| 1685 | export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): ProviderAdapterV2Shape { | 1670 | export function makeCodexAdapterV2( |
| 1671 | adapterOptions: CodexAdapterV2Options, | ||
| 1672 | ): ProviderAdapter.ProviderAdapterV2["Service"] { | ||
| 1686 | const { clientFactory, crypto, fileSystem, idAllocator, serverConfig } = adapterOptions; | 1673 | const { clientFactory, crypto, fileSystem, idAllocator, serverConfig } = adapterOptions; |
| 1687 | const continuationRequests = adapterOptions.continuationRequests; | 1674 | const continuationRequests = adapterOptions.continuationRequests; |
| 1688 | 1675 | ||
| 1689 | return ProviderAdapterV2.of({ | 1676 | return ProviderAdapter.ProviderAdapterV2.of({ |
| 1690 | instanceId: adapterOptions.instanceId, | 1677 | instanceId: adapterOptions.instanceId, |
| 1691 | driver: CODEX_PROVIDER, | 1678 | driver: CODEX_PROVIDER, |
| 1692 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 1679 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| ... | @@ -1700,7 +1687,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1700,7 +1687,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1700 | : yield* adapterOptions.resolveRuntime.pipe( | 1687 | : yield* adapterOptions.resolveRuntime.pipe( |
| 1701 | Effect.mapError( | 1688 | Effect.mapError( |
| 1702 | (cause) => | 1689 | (cause) => |
| 1703 | new ProviderAdapterOpenSessionError({ | 1690 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 1704 | driver: CODEX_PROVIDER, | 1691 | driver: CODEX_PROVIDER, |
| 1705 | providerSessionId: input.providerSessionId, | 1692 | providerSessionId: input.providerSessionId, |
| 1706 | cause, | 1693 | cause, |
| ... | @@ -1800,7 +1787,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1800,7 +1787,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1800 | model: input.modelSelection.model, | 1787 | model: input.modelSelection.model, |
| 1801 | now, | 1788 | now, |
| 1802 | }); | 1789 | }); |
| 1803 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 1790 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 1804 | const rateLimitSnapshot = yield* Ref.make<CodexRateLimitSnapshot | undefined>(undefined); | 1791 | const rateLimitSnapshot = yield* Ref.make<CodexRateLimitSnapshot | undefined>(undefined); |
| 1805 | const limitedTurnItems = yield* Ref.make( | 1792 | const limitedTurnItems = yield* Ref.make( |
| 1806 | new Map<ProviderThreadId, Extract<OrchestrationV2TurnItem, { type: "error" }>>(), | 1793 | new Map<ProviderThreadId, Extract<OrchestrationV2TurnItem, { type: "error" }>>(), |
| ... | @@ -1833,7 +1820,9 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1833,7 +1820,9 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1833 | context.nativeTurnId, | 1820 | context.nativeTurnId, |
| 1834 | ).hasSubagents = true; | 1821 | ).hasSubagents = true; |
| 1835 | }; | 1822 | }; |
| 1836 | const pendingRootTurns = yield* Ref.make(new Map<string, ProviderAdapterV2TurnInput>()); | 1823 | const pendingRootTurns = yield* Ref.make( |
| 1824 | new Map<string, ProviderAdapter.ProviderAdapterV2TurnInput>(), | ||
| 1825 | ); | ||
| 1837 | const turnWaiters = yield* Ref.make(new Map<string, Deferred.Deferred<void, never>>()); | 1826 | const turnWaiters = yield* Ref.make(new Map<string, Deferred.Deferred<void, never>>()); |
| 1838 | const subagentThreads = yield* Ref.make(new Map<string, CodexSubagentThreadContext>()); | 1827 | const subagentThreads = yield* Ref.make(new Map<string, CodexSubagentThreadContext>()); |
| 1839 | const subagentSelections = new Map<string, Omit<ModelSelection, "instanceId">>(); | 1828 | const subagentSelections = new Map<string, Omit<ModelSelection, "instanceId">>(); |
| ... | @@ -1893,7 +1882,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1893,7 +1882,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1893 | const latestGoalTurnId = (providerTurnId: ProviderTurnId) => | 1882 | const latestGoalTurnId = (providerTurnId: ProviderTurnId) => |
| 1894 | goalRuns.get(providerTurnId)?.at(-1)?.providerTurnId ?? providerTurnId; | 1883 | goalRuns.get(providerTurnId)?.at(-1)?.providerTurnId ?? providerTurnId; |
| 1895 | 1884 | ||
| 1896 | const emitProviderEvent = (event: ProviderAdapterV2Event) => | 1885 | const emitProviderEvent = (event: ProviderAdapter.ProviderAdapterV2Event) => |
| 1897 | Queue.offer(events, event).pipe(Effect.asVoid); | 1886 | Queue.offer(events, event).pipe(Effect.asVoid); |
| 1898 | 1887 | ||
| 1899 | /** Writes the thread's current native goal onto its root provider thread. */ | 1888 | /** Writes the thread's current native goal onto its root provider thread. */ |
| ... | @@ -1942,7 +1931,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1942,7 +1931,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1942 | type: "turn_item.updated", | 1931 | type: "turn_item.updated", |
| 1943 | driver: CODEX_PROVIDER, | 1932 | driver: CODEX_PROVIDER, |
| 1944 | turnItem: makeProviderRetryTurnItem({ | 1933 | turnItem: makeProviderRetryTurnItem({ |
| 1945 | idAllocator, | ||
| 1946 | driver: CODEX_PROVIDER, | 1934 | driver: CODEX_PROVIDER, |
| 1947 | threadId: context.projectionThreadId, | 1935 | threadId: context.projectionThreadId, |
| 1948 | runId: context.projectionRunId, | 1936 | runId: context.projectionRunId, |
| ... | @@ -1960,7 +1948,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -1960,7 +1948,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 1960 | }); | 1948 | }); |
| 1961 | 1949 | ||
| 1962 | const registerRootTurn = (input: { | 1950 | const registerRootTurn = (input: { |
| 1963 | readonly turnInput: ProviderAdapterV2TurnInput; | 1951 | readonly turnInput: ProviderAdapter.ProviderAdapterV2TurnInput; |
| 1964 | readonly nativeTurnId: string; | 1952 | readonly nativeTurnId: string; |
| 1965 | readonly startedAt: DateTime.Utc; | 1953 | readonly startedAt: DateTime.Utc; |
| 1966 | readonly waitForNativeStart?: boolean; | 1954 | readonly waitForNativeStart?: boolean; |
| ... | @@ -3143,7 +3131,11 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -3143,7 +3131,11 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 3143 | }); | 3131 | }); |
| 3144 | 3132 | ||
| 3145 | const toCodexInput = ( | 3133 | const toCodexInput = ( |
| 3146 | turnInput: Pick<ProviderAdapterV2TurnInput | ProviderAdapterV2SteerInput, "message">, | 3134 | turnInput: Pick< |
| 3135 | | ProviderAdapter.ProviderAdapterV2TurnInput | ||
| 3136 | | ProviderAdapter.ProviderAdapterV2SteerInput, | ||
| 3137 | "message" | ||
| 3138 | >, | ||
| 3147 | ) => | 3139 | ) => |
| 3148 | Effect.gen(function* () { | 3140 | Effect.gen(function* () { |
| 3149 | const inputItems: Array<CodexSchema.V2TurnStartParams__UserInput> = []; | 3141 | const inputItems: Array<CodexSchema.V2TurnStartParams__UserInput> = []; |
| ... | @@ -4539,7 +4531,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -4539,7 +4531,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 4539 | type: "turn_item.updated", | 4531 | type: "turn_item.updated", |
| 4540 | driver: CODEX_PROVIDER, | 4532 | driver: CODEX_PROVIDER, |
| 4541 | turnItem: makeProviderRetryTurnItem({ | 4533 | turnItem: makeProviderRetryTurnItem({ |
| 4542 | idAllocator, | ||
| 4543 | driver: CODEX_PROVIDER, | 4534 | driver: CODEX_PROVIDER, |
| 4544 | threadId: context.projectionThreadId, | 4535 | threadId: context.projectionThreadId, |
| 4545 | runId: context.projectionRunId, | 4536 | runId: context.projectionRunId, |
| ... | @@ -5584,7 +5575,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -5584,7 +5575,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 5584 | } | 5575 | } |
| 5585 | if (current.status === "failed" && current.failure.class === "usage_limit") { | 5576 | if (current.status === "failed" && current.failure.class === "usage_limit") { |
| 5586 | const item = makeProviderFailureTurnItem({ | 5577 | const item = makeProviderFailureTurnItem({ |
| 5587 | idAllocator, | ||
| 5588 | driver: CODEX_PROVIDER, | 5578 | driver: CODEX_PROVIDER, |
| 5589 | threadId: context.input.threadId, | 5579 | threadId: context.input.threadId, |
| 5590 | runId: context.input.runId, | 5580 | runId: context.input.runId, |
| ... | @@ -5735,7 +5725,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -5735,7 +5725,6 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 5735 | type: "turn_item.updated", | 5725 | type: "turn_item.updated", |
| 5736 | driver: CODEX_PROVIDER, | 5726 | driver: CODEX_PROVIDER, |
| 5737 | turnItem: makeProviderRetryTurnItem({ | 5727 | turnItem: makeProviderRetryTurnItem({ |
| 5738 | idAllocator, | ||
| 5739 | driver: CODEX_PROVIDER, | 5728 | driver: CODEX_PROVIDER, |
| 5740 | threadId: input.context.projectionThreadId, | 5729 | threadId: input.context.projectionThreadId, |
| 5741 | runId: input.context.projectionRunId, | 5730 | runId: input.context.projectionRunId, |
| ... | @@ -6000,7 +5989,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6000,7 +5989,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6000 | * assistant text, as Claude's own `/goal` output is. | 5989 | * assistant text, as Claude's own `/goal` output is. |
| 6001 | */ | 5990 | */ |
| 6002 | const completeGoalCommandTurn = Effect.fnUntraced(function* ( | 5991 | const completeGoalCommandTurn = Effect.fnUntraced(function* ( |
| 6003 | turnInput: ProviderAdapterV2TurnInput, | 5992 | turnInput: ProviderAdapter.ProviderAdapterV2TurnInput, |
| 6004 | reply: string, | 5993 | reply: string, |
| 6005 | ) { | 5994 | ) { |
| 6006 | const now = yield* DateTime.now; | 5995 | const now = yield* DateTime.now; |
| ... | @@ -6104,7 +6093,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6104,7 +6093,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6104 | * Stop also reaches. | 6093 | * Stop also reaches. |
| 6105 | */ | 6094 | */ |
| 6106 | const resolveGoalStopTarget = Effect.fnUntraced(function* ( | 6095 | const resolveGoalStopTarget = Effect.fnUntraced(function* ( |
| 6107 | turnInput: ProviderAdapterV2InterruptInput, | 6096 | turnInput: ProviderAdapter.ProviderAdapterV2InterruptInput, |
| 6108 | ) { | 6097 | ) { |
| 6109 | const goalThreadId = turnInput.providerThread.nativeThreadRef?.nativeId; | 6098 | const goalThreadId = turnInput.providerThread.nativeThreadRef?.nativeId; |
| 6110 | if (goalThreadId == null) { | 6099 | if (goalThreadId == null) { |
| ... | @@ -6172,7 +6161,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6172,7 +6161,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6172 | 6161 | ||
| 6173 | /** Starts a native turn with this run's full turn configuration. */ | 6162 | /** Starts a native turn with this run's full turn configuration. */ |
| 6174 | const startNativeTurn = ( | 6163 | const startNativeTurn = ( |
| 6175 | turnInput: ProviderAdapterV2TurnInput, | 6164 | turnInput: ProviderAdapter.ProviderAdapterV2TurnInput, |
| 6176 | codexInput: ReadonlyArray<CodexSchema.V2TurnStartParams__UserInput>, | 6165 | codexInput: ReadonlyArray<CodexSchema.V2TurnStartParams__UserInput>, |
| 6177 | ) => | 6166 | ) => |
| 6178 | Effect.gen(function* () { | 6167 | Effect.gen(function* () { |
| ... | @@ -6227,7 +6216,10 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6227,7 +6216,10 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6227 | * turn Codex starts on its own reuses the last turn's settings. Codex | 6216 | * turn Codex starts on its own reuses the last turn's settings. Codex |
| 6228 | * continues later goal turns itself. Other commands settle with a reply. | 6217 | * continues later goal turns itself. Other commands settle with a reply. |
| 6229 | */ | 6218 | */ |
| 6230 | const runGoalCommand = (turnInput: ProviderAdapterV2TurnInput, command: CodexGoalCommand) => | 6219 | const runGoalCommand = ( |
| 6220 | turnInput: ProviderAdapter.ProviderAdapterV2TurnInput, | ||
| 6221 | command: CodexGoalCommand, | ||
| 6222 | ) => | ||
| 6231 | Effect.gen(function* () { | 6223 | Effect.gen(function* () { |
| 6232 | const threadId = yield* getNativeThreadId(turnInput.providerThread); | 6224 | const threadId = yield* getNativeThreadId(turnInput.providerThread); |
| 6233 | // Goal notifications during the command belong to this run's snapshot. | 6225 | // Goal notifications during the command belong to this run's snapshot. |
| ... | @@ -6326,7 +6318,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6326,7 +6318,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6326 | }).pipe( | 6318 | }).pipe( |
| 6327 | Effect.mapError( | 6319 | Effect.mapError( |
| 6328 | (cause) => | 6320 | (cause) => |
| 6329 | new ProviderAdapterTurnStartError({ | 6321 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 6330 | driver: CODEX_PROVIDER, | 6322 | driver: CODEX_PROVIDER, |
| 6331 | threadId: turnInput.threadId, | 6323 | threadId: turnInput.threadId, |
| 6332 | providerThreadId: turnInput.providerThread.id, | 6324 | providerThreadId: turnInput.providerThread.id, |
| ... | @@ -6339,8 +6331,12 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6339,8 +6331,12 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6339 | // MCP Apps reach their server through Codex's own MCP client, so any | 6331 | // MCP Apps reach their server through Codex's own MCP client, so any |
| 6340 | // server the user configured for Codex works without T3 connecting to it. | 6332 | // server the user configured for Codex works without T3 connecting to it. |
| 6341 | const mcpAppsError = (detail: string) => (cause: unknown) => | 6333 | const mcpAppsError = (detail: string) => (cause: unknown) => |
| 6342 | new ProviderAdapterProtocolError({ driver: CODEX_PROVIDER, detail, payload: cause }); | 6334 | new ProviderAdapter.ProviderAdapterProtocolError({ |
| 6343 | const mcpApps: ProviderAdapterV2McpApps = { | 6335 | driver: CODEX_PROVIDER, |
| 6336 | detail, | ||
| 6337 | payload: cause, | ||
| 6338 | }); | ||
| 6339 | const mcpApps: ProviderAdapter.ProviderAdapterV2McpApps = { | ||
| 6344 | listTools: (toolsInput) => | 6340 | listTools: (toolsInput) => |
| 6345 | Effect.gen(function* () { | 6341 | Effect.gen(function* () { |
| 6346 | const threadId = yield* getNativeThreadId(toolsInput.providerThread); | 6342 | const threadId = yield* getNativeThreadId(toolsInput.providerThread); |
| ... | @@ -6394,7 +6390,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6394,7 +6390,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6394 | }).pipe(Effect.mapError(mcpAppsError("Codex MCP resource read failed."))), | 6390 | }).pipe(Effect.mapError(mcpAppsError("Codex MCP resource read failed."))), |
| 6395 | }; | 6391 | }; |
| 6396 | 6392 | ||
| 6397 | const runtime: ProviderAdapterV2SessionRuntime = { | 6393 | const runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime = { |
| 6398 | instanceId: adapterOptions.instanceId, | 6394 | instanceId: adapterOptions.instanceId, |
| 6399 | driver: CODEX_PROVIDER, | 6395 | driver: CODEX_PROVIDER, |
| 6400 | providerSessionId: input.providerSessionId, | 6396 | providerSessionId: input.providerSessionId, |
| ... | @@ -6471,7 +6467,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6471,7 +6467,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6471 | ), | 6467 | ), |
| 6472 | Effect.mapError( | 6468 | Effect.mapError( |
| 6473 | (cause) => | 6469 | (cause) => |
| 6474 | new ProviderAdapterEnsureThreadError({ | 6470 | new ProviderAdapter.ProviderAdapterEnsureThreadError({ |
| 6475 | driver: CODEX_PROVIDER, | 6471 | driver: CODEX_PROVIDER, |
| 6476 | threadId: threadInput.threadId, | 6472 | threadId: threadInput.threadId, |
| 6477 | cause: normalizeCodexCause(cause), | 6473 | cause: normalizeCodexCause(cause), |
| ... | @@ -6535,7 +6531,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6535,7 +6531,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6535 | }).pipe( | 6531 | }).pipe( |
| 6536 | Effect.mapError( | 6532 | Effect.mapError( |
| 6537 | (cause) => | 6533 | (cause) => |
| 6538 | new ProviderAdapterResumeThreadError({ | 6534 | new ProviderAdapter.ProviderAdapterResumeThreadError({ |
| 6539 | driver: CODEX_PROVIDER, | 6535 | driver: CODEX_PROVIDER, |
| 6540 | providerSessionId: input.providerSessionId, | 6536 | providerSessionId: input.providerSessionId, |
| 6541 | providerThreadId: threadInput.providerThread.id, | 6537 | providerThreadId: threadInput.providerThread.id, |
| ... | @@ -6563,7 +6559,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6563,7 +6559,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6563 | }).pipe( | 6559 | }).pipe( |
| 6564 | Effect.mapError( | 6560 | Effect.mapError( |
| 6565 | (cause) => | 6561 | (cause) => |
| 6566 | new ProviderAdapterTurnStartError({ | 6562 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 6567 | driver: CODEX_PROVIDER, | 6563 | driver: CODEX_PROVIDER, |
| 6568 | threadId: turnInput.threadId, | 6564 | threadId: turnInput.threadId, |
| 6569 | providerThreadId: turnInput.providerThread.id, | 6565 | providerThreadId: turnInput.providerThread.id, |
| ... | @@ -6593,7 +6589,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6593,7 +6589,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6593 | }).pipe( | 6589 | }).pipe( |
| 6594 | Effect.mapError( | 6590 | Effect.mapError( |
| 6595 | (cause) => | 6591 | (cause) => |
| 6596 | new ProviderAdapterProtocolError({ | 6592 | new ProviderAdapter.ProviderAdapterProtocolError({ |
| 6597 | driver: CODEX_PROVIDER, | 6593 | driver: CODEX_PROVIDER, |
| 6598 | detail: "Failed to inject historical context", | 6594 | detail: "Failed to inject historical context", |
| 6599 | cause, | 6595 | cause, |
| ... | @@ -6617,7 +6613,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6617,7 +6613,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6617 | }).pipe( | 6613 | }).pipe( |
| 6618 | Effect.mapError( | 6614 | Effect.mapError( |
| 6619 | (cause) => | 6615 | (cause) => |
| 6620 | new ProviderAdapterTurnStartError({ | 6616 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 6621 | driver: CODEX_PROVIDER, | 6617 | driver: CODEX_PROVIDER, |
| 6622 | threadId: turnInput.threadId, | 6618 | threadId: turnInput.threadId, |
| 6623 | providerThreadId: turnInput.providerThread.id, | 6619 | providerThreadId: turnInput.providerThread.id, |
| ... | @@ -6655,7 +6651,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6655,7 +6651,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6655 | }).pipe( | 6651 | }).pipe( |
| 6656 | Effect.mapError( | 6652 | Effect.mapError( |
| 6657 | (cause) => | 6653 | (cause) => |
| 6658 | new ProviderAdapterSteerRunError({ | 6654 | new ProviderAdapter.ProviderAdapterSteerRunError({ |
| 6659 | driver: CODEX_PROVIDER, | 6655 | driver: CODEX_PROVIDER, |
| 6660 | providerThreadId: turnInput.providerThread.id, | 6656 | providerThreadId: turnInput.providerThread.id, |
| 6661 | providerTurnId: turnInput.providerTurnId, | 6657 | providerTurnId: turnInput.providerTurnId, |
| ... | @@ -6674,7 +6670,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -6674,7 +6670,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 6674 | Effect.mapError((cause) => | 6670 | Effect.mapError((cause) => |
| 6675 | cause._tag === "ProviderAdapterProtocolError" | 6671 | cause._tag === "ProviderAdapterProtocolError" |
| 6676 | ? cause | 6672 | ? cause |
| 6677 | : new ProviderAdapterProtocolError({ | 6673 | : new ProviderAdapter.ProviderAdapterProtocolError({ |
| 6678 | driver: CODEX_PROVIDER, | 6674 | driver: CODEX_PROVIDER, |
| 6679 | detail: `Failed to unload Codex thread for provider thread ${unloadInput.providerThread.id}`, | 6675 | detail: `Failed to unload Codex thread for provider thread ${unloadInput.providerThread.id}`, |
| 6680 | cause: normalizeCodexCause(cause), | 6676 | cause: normalizeCodexCause(cause), |
| ... | @@ -7061,7 +7057,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7061,7 +7057,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7061 | }).pipe( | 7057 | }).pipe( |
| 7062 | Effect.mapError( | 7058 | Effect.mapError( |
| 7063 | (cause) => | 7059 | (cause) => |
| 7064 | new ProviderAdapterInterruptError({ | 7060 | new ProviderAdapter.ProviderAdapterInterruptError({ |
| 7065 | driver: CODEX_PROVIDER, | 7061 | driver: CODEX_PROVIDER, |
| 7066 | providerThreadId: requestedInput.providerThread.id, | 7062 | providerThreadId: requestedInput.providerThread.id, |
| 7067 | providerTurnId: requestedInput.providerTurnId, | 7063 | providerTurnId: requestedInput.providerTurnId, |
| ... | @@ -7075,7 +7071,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7075,7 +7071,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7075 | String(requestInput.requestId), | 7071 | String(requestInput.requestId), |
| 7076 | ); | 7072 | ); |
| 7077 | if (pending === undefined) { | 7073 | if (pending === undefined) { |
| 7078 | return yield* new ProviderAdapterRuntimeRequestResponseError({ | 7074 | return yield* new ProviderAdapter.ProviderAdapterRuntimeRequestResponseError({ |
| 7079 | driver: CODEX_PROVIDER, | 7075 | driver: CODEX_PROVIDER, |
| 7080 | requestId: requestInput.requestId, | 7076 | requestId: requestInput.requestId, |
| 7081 | cause: toProtocolError( | 7077 | cause: toProtocolError( |
| ... | @@ -7085,7 +7081,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7085,7 +7081,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7085 | } | 7081 | } |
| 7086 | if (pending.type === "user_input") { | 7082 | if (pending.type === "user_input") { |
| 7087 | if (requestInput.answers === undefined) { | 7083 | if (requestInput.answers === undefined) { |
| 7088 | return yield* new ProviderAdapterRuntimeRequestResponseError({ | 7084 | return yield* new ProviderAdapter.ProviderAdapterRuntimeRequestResponseError({ |
| 7089 | driver: CODEX_PROVIDER, | 7085 | driver: CODEX_PROVIDER, |
| 7090 | requestId: requestInput.requestId, | 7086 | requestId: requestInput.requestId, |
| 7091 | cause: toProtocolError( | 7087 | cause: toProtocolError( |
| ... | @@ -7097,7 +7093,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7097,7 +7093,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7097 | return; | 7093 | return; |
| 7098 | } | 7094 | } |
| 7099 | if (requestInput.decision === undefined) { | 7095 | if (requestInput.decision === undefined) { |
| 7100 | return yield* new ProviderAdapterRuntimeRequestResponseError({ | 7096 | return yield* new ProviderAdapter.ProviderAdapterRuntimeRequestResponseError({ |
| 7101 | driver: CODEX_PROVIDER, | 7097 | driver: CODEX_PROVIDER, |
| 7102 | requestId: requestInput.requestId, | 7098 | requestId: requestInput.requestId, |
| 7103 | cause: toProtocolError( | 7099 | cause: toProtocolError( |
| ... | @@ -7110,7 +7106,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7110,7 +7106,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7110 | Effect.mapError((cause) => | 7106 | Effect.mapError((cause) => |
| 7111 | isProviderAdapterRuntimeRequestResponseError(cause) | 7107 | isProviderAdapterRuntimeRequestResponseError(cause) |
| 7112 | ? cause | 7108 | ? cause |
| 7113 | : new ProviderAdapterRuntimeRequestResponseError({ | 7109 | : new ProviderAdapter.ProviderAdapterRuntimeRequestResponseError({ |
| 7114 | driver: CODEX_PROVIDER, | 7110 | driver: CODEX_PROVIDER, |
| 7115 | requestId: requestInput.requestId, | 7111 | requestId: requestInput.requestId, |
| 7116 | cause, | 7112 | cause, |
| ... | @@ -7134,7 +7130,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7134,7 +7130,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7134 | }).pipe( | 7130 | }).pipe( |
| 7135 | Effect.mapError( | 7131 | Effect.mapError( |
| 7136 | (cause) => | 7132 | (cause) => |
| 7137 | new ProviderAdapterProtocolError({ | 7133 | new ProviderAdapter.ProviderAdapterProtocolError({ |
| 7138 | driver: CODEX_PROVIDER, | 7134 | driver: CODEX_PROVIDER, |
| 7139 | detail: "Failed to upload Codex thread feedback.", | 7135 | detail: "Failed to upload Codex thread feedback.", |
| 7140 | payload: cause, | 7136 | payload: cause, |
| ... | @@ -7167,7 +7163,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7167,7 +7163,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7167 | }).pipe( | 7163 | }).pipe( |
| 7168 | Effect.mapError( | 7164 | Effect.mapError( |
| 7169 | (cause) => | 7165 | (cause) => |
| 7170 | new ProviderAdapterReadThreadSnapshotError({ | 7166 | new ProviderAdapter.ProviderAdapterReadThreadSnapshotError({ |
| 7171 | driver: CODEX_PROVIDER, | 7167 | driver: CODEX_PROVIDER, |
| 7172 | providerThreadId: threadInput.providerThread.id, | 7168 | providerThreadId: threadInput.providerThread.id, |
| 7173 | cause, | 7169 | cause, |
| ... | @@ -7200,7 +7196,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7200,7 +7196,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7200 | Effect.andThen(readCodexThreadHistoryMetadata(client.raw, threadId)), | 7196 | Effect.andThen(readCodexThreadHistoryMetadata(client.raw, threadId)), |
| 7201 | ); | 7197 | ); |
| 7202 | if (historyMode !== "paginated") { | 7198 | if (historyMode !== "paginated") { |
| 7203 | return yield* new ProviderAdapterRollbackThreadError({ | 7199 | return yield* new ProviderAdapter.ProviderAdapterRollbackThreadError({ |
| 7204 | driver: CODEX_PROVIDER, | 7200 | driver: CODEX_PROVIDER, |
| 7205 | providerThreadId: threadInput.providerThread.id, | 7201 | providerThreadId: threadInput.providerThread.id, |
| 7206 | cause: `Cannot roll back Codex thread ${threadId}: the thread uses legacy history, which Codex 0.156 cannot revert.`, | 7202 | cause: `Cannot roll back Codex thread ${threadId}: the thread uses legacy history, which Codex 0.156 cannot revert.`, |
| ... | @@ -7244,7 +7240,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7244,7 +7240,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7244 | }).pipe( | 7240 | }).pipe( |
| 7245 | Effect.mapError( | 7241 | Effect.mapError( |
| 7246 | (cause) => | 7242 | (cause) => |
| 7247 | new ProviderAdapterRollbackThreadError({ | 7243 | new ProviderAdapter.ProviderAdapterRollbackThreadError({ |
| 7248 | driver: CODEX_PROVIDER, | 7244 | driver: CODEX_PROVIDER, |
| 7249 | providerThreadId: threadInput.providerThread.id, | 7245 | providerThreadId: threadInput.providerThread.id, |
| 7250 | cause: normalizeCodexCause(cause), | 7246 | cause: normalizeCodexCause(cause), |
| ... | @@ -7275,7 +7271,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7275,7 +7271,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7275 | ), | 7271 | ), |
| 7276 | Effect.mapError( | 7272 | Effect.mapError( |
| 7277 | (cause) => | 7273 | (cause) => |
| 7278 | new ProviderAdapterForkThreadError({ | 7274 | new ProviderAdapter.ProviderAdapterForkThreadError({ |
| 7279 | driver: CODEX_PROVIDER, | 7275 | driver: CODEX_PROVIDER, |
| 7280 | providerThreadId: threadInput.sourceProviderThread.id, | 7276 | providerThreadId: threadInput.sourceProviderThread.id, |
| 7281 | cause: normalizeCodexCause(cause), | 7277 | cause: normalizeCodexCause(cause), |
| ... | @@ -7291,7 +7287,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7291,7 +7287,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7291 | Effect.andThen(readCodexThreadHistoryMetadata(client.raw, response.thread.id)), | 7287 | Effect.andThen(readCodexThreadHistoryMetadata(client.raw, response.thread.id)), |
| 7292 | ); | 7288 | ); |
| 7293 | if (historyMode !== "paginated") { | 7289 | if (historyMode !== "paginated") { |
| 7294 | return yield* new ProviderAdapterForkThreadError({ | 7290 | return yield* new ProviderAdapter.ProviderAdapterForkThreadError({ |
| 7295 | driver: CODEX_PROVIDER, | 7291 | driver: CODEX_PROVIDER, |
| 7296 | providerThreadId: threadInput.sourceProviderThread.id, | 7292 | providerThreadId: threadInput.sourceProviderThread.id, |
| 7297 | cause: `Cannot fork Codex thread ${threadId} at provider turn ${threadInput.providerTurnId}: the source turn has no native Codex turn reference, and the forked thread uses legacy history which Codex 0.156 cannot revert.`, | 7293 | cause: `Cannot fork Codex thread ${threadId} at provider turn ${threadInput.providerTurnId}: the source turn has no native Codex turn reference, and the forked thread uses legacy history which Codex 0.156 cannot revert.`, |
| ... | @@ -7303,7 +7299,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7303,7 +7299,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7303 | ), | 7299 | ), |
| 7304 | Effect.mapError( | 7300 | Effect.mapError( |
| 7305 | (cause) => | 7301 | (cause) => |
| 7306 | new ProviderAdapterForkThreadError({ | 7302 | new ProviderAdapter.ProviderAdapterForkThreadError({ |
| 7307 | driver: CODEX_PROVIDER, | 7303 | driver: CODEX_PROVIDER, |
| 7308 | providerThreadId: threadInput.sourceProviderThread.id, | 7304 | providerThreadId: threadInput.sourceProviderThread.id, |
| 7309 | cause: normalizeCodexCause(cause), | 7305 | cause: normalizeCodexCause(cause), |
| ... | @@ -7328,7 +7324,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7328,7 +7324,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7328 | }).pipe( | 7324 | }).pipe( |
| 7329 | Effect.mapError( | 7325 | Effect.mapError( |
| 7330 | (cause) => | 7326 | (cause) => |
| 7331 | new ProviderAdapterForkThreadError({ | 7327 | new ProviderAdapter.ProviderAdapterForkThreadError({ |
| 7332 | driver: CODEX_PROVIDER, | 7328 | driver: CODEX_PROVIDER, |
| 7333 | providerThreadId: threadInput.sourceProviderThread.id, | 7329 | providerThreadId: threadInput.sourceProviderThread.id, |
| 7334 | cause: normalizeCodexCause(cause), | 7330 | cause: normalizeCodexCause(cause), |
| ... | @@ -7340,7 +7336,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi | ... | @@ -7340,7 +7336,7 @@ export function makeCodexAdapterV2(adapterOptions: CodexAdapterV2Options): Provi |
| 7340 | }).pipe( | 7336 | }).pipe( |
| 7341 | Effect.mapError( | 7337 | Effect.mapError( |
| 7342 | (cause) => | 7338 | (cause) => |
| 7343 | new ProviderAdapterOpenSessionError({ | 7339 | new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 7344 | driver: CODEX_PROVIDER, | 7340 | driver: CODEX_PROVIDER, |
| 7345 | providerSessionId: input.providerSessionId, | 7341 | providerSessionId: input.providerSessionId, |
| 7346 | cause, | 7342 | cause, |
apps/server/src/orchestration-v2/Adapters/CursorAdapterV2.testkit.ts+2-2| ... | @@ -28,7 +28,7 @@ import { | ... | @@ -28,7 +28,7 @@ import { |
| 28 | cursorSdkModelSelection, | 28 | cursorSdkModelSelection, |
| 29 | makeCursorAgentOptions, | 29 | makeCursorAgentOptions, |
| 30 | } from "@t3tools/provider-cursor/testing"; | 30 | } from "@t3tools/provider-cursor/testing"; |
| 31 | import type { ProviderAdapterV2RuntimePolicy } from "@t3tools/provider-core/server/ProviderAdapter"; | 31 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 32 | import type { RuntimePolicyV2Override } from "../RuntimePolicy.ts"; | 32 | import type { RuntimePolicyV2Override } from "../RuntimePolicy.ts"; |
| 33 | 33 | ||
| 34 | const CursorAgentSdkReplayTranscript = Schema.Struct({ | 34 | const CursorAgentSdkReplayTranscript = Schema.Struct({ |
| ... | @@ -625,7 +625,7 @@ function recordingRuntimePolicy(input: { | ... | @@ -625,7 +625,7 @@ function recordingRuntimePolicy(input: { |
| 625 | readonly cwd: string; | 625 | readonly cwd: string; |
| 626 | readonly interactionMode: "default" | "plan"; | 626 | readonly interactionMode: "default" | "plan"; |
| 627 | readonly override?: Pick<RuntimePolicyV2Override, "approvalPolicy" | "sandboxPolicy">; | 627 | readonly override?: Pick<RuntimePolicyV2Override, "approvalPolicy" | "sandboxPolicy">; |
| 628 | }): ProviderAdapterV2RuntimePolicy { | 628 | }): ProviderAdapter.ProviderAdapterV2RuntimePolicy { |
| 629 | return { | 629 | return { |
| 630 | runtimeMode: "full-access", | 630 | runtimeMode: "full-access", |
| 631 | interactionMode: input.interactionMode, | 631 | interactionMode: input.interactionMode, |
apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.test.ts+5-5| ... | @@ -26,7 +26,7 @@ import { buildInitialGrokProviderSnapshot } from "@t3tools/provider-grok/testing | ... | @@ -26,7 +26,7 @@ import { buildInitialGrokProviderSnapshot } from "@t3tools/provider-grok/testing |
| 26 | import type { ProviderInstance } from "@t3tools/provider-core/server/driver"; | 26 | import type { ProviderInstance } from "@t3tools/provider-core/server/driver"; |
| 27 | import * as ProviderInstanceRegistry from "../../provider/ProviderInstanceRegistry.ts"; | 27 | import * as ProviderInstanceRegistry from "../../provider/ProviderInstanceRegistry.ts"; |
| 28 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 28 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 29 | import { ProviderAdapterV2RuntimePolicy } from "@t3tools/provider-core/server/ProviderAdapter"; | 29 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 30 | import * as RuntimePolicy from "../RuntimePolicy.ts"; | 30 | import * as RuntimePolicy from "../RuntimePolicy.ts"; |
| 31 | import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPolicy"; | 31 | import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPolicy"; |
| 32 | import { | 32 | import { |
| ... | @@ -68,7 +68,7 @@ function runtimePolicy(input: { | ... | @@ -68,7 +68,7 @@ function runtimePolicy(input: { |
| 68 | readonly approvalPolicy?: unknown; | 68 | readonly approvalPolicy?: unknown; |
| 69 | readonly sandboxPolicy?: unknown; | 69 | readonly sandboxPolicy?: unknown; |
| 70 | }) { | 70 | }) { |
| 71 | return ProviderAdapterV2RuntimePolicy.make({ | 71 | return ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 72 | runtimeMode: input.runtimeMode, | 72 | runtimeMode: input.runtimeMode, |
| 73 | interactionMode: "default", | 73 | interactionMode: "default", |
| 74 | cwd: "/workspace", | 74 | cwd: "/workspace", |
| ... | @@ -314,7 +314,7 @@ describe("Grok launch permission mode", () => { | ... | @@ -314,7 +314,7 @@ describe("Grok launch permission mode", () => { |
| 314 | // Opens a session through the adapter's own Grok runtime factory and returns | 314 | // Opens a session through the adapter's own Grok runtime factory and returns |
| 315 | // the argv it tried to launch. The spawn fails after recording, so no | 315 | // the argv it tried to launch. The spawn fails after recording, so no |
| 316 | // process starts. | 316 | // process starts. |
| 317 | const launchArgs = (runtimePolicy: ProviderAdapterV2RuntimePolicy) => | 317 | const launchArgs = (runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy) => |
| 318 | Effect.gen(function* () { | 318 | Effect.gen(function* () { |
| 319 | const launches: Array<ReadonlyArray<string>> = []; | 319 | const launches: Array<ReadonlyArray<string>> = []; |
| 320 | const childProcessSpawner = ChildProcessSpawner.make((command) => { | 320 | const childProcessSpawner = ChildProcessSpawner.make((command) => { |
| ... | @@ -352,9 +352,9 @@ describe("Grok launch permission mode", () => { | ... | @@ -352,9 +352,9 @@ describe("Grok launch permission mode", () => { |
| 352 | 352 | ||
| 353 | const policy = ( | 353 | const policy = ( |
| 354 | runtimeMode: RuntimeMode, | 354 | runtimeMode: RuntimeMode, |
| 355 | override: Partial<ProviderAdapterV2RuntimePolicy> = {}, | 355 | override: Partial<ProviderAdapter.ProviderAdapterV2RuntimePolicy> = {}, |
| 356 | ) => | 356 | ) => |
| 357 | ProviderAdapterV2RuntimePolicy.make({ | 357 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 358 | runtimeMode, | 358 | runtimeMode, |
| 359 | interactionMode: "default", | 359 | interactionMode: "default", |
| 360 | cwd: process.cwd(), | 360 | cwd: process.cwd(), |
apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.testkit.ts+1-1| ... | @@ -13,7 +13,7 @@ import { layerTestProviderHost } from "@t3tools/provider-testing/host"; | ... | @@ -13,7 +13,7 @@ import { layerTestProviderHost } from "@t3tools/provider-testing/host"; |
| 13 | import { GROK_ACP_CANCEL_META, GROK_ACP_INITIALIZE_META } from "@t3tools/provider-grok/testing"; | 13 | import { GROK_ACP_CANCEL_META, GROK_ACP_INITIALIZE_META } from "@t3tools/provider-grok/testing"; |
| 14 | import { makeXAiPromptCompletionRuntime } from "@t3tools/provider-grok/testing"; | 14 | import { makeXAiPromptCompletionRuntime } from "@t3tools/provider-grok/testing"; |
| 15 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 15 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 16 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 16 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 17 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 17 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 18 | import type { ProviderReplayGate } from "@t3tools/provider-testing/replayGate"; | 18 | import type { ProviderReplayGate } from "@t3tools/provider-testing/replayGate"; |
| 19 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; | 19 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; |
apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.testkit.ts+1-1| ... | @@ -36,7 +36,7 @@ import { | ... | @@ -36,7 +36,7 @@ import { |
| 36 | } from "@t3tools/provider-muse/testing"; | 36 | } from "@t3tools/provider-muse/testing"; |
| 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 38 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 38 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 39 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 39 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 40 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; | 40 | import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; |
| 41 | import { makeMuseAdapterV2 } from "@t3tools/provider-muse/server"; | 41 | import { makeMuseAdapterV2 } from "@t3tools/provider-muse/server"; |
| 42 | 42 |
apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts+36-24| ... | @@ -38,14 +38,10 @@ import * as Exit from "effect/Exit"; | ... | @@ -38,14 +38,10 @@ import * as Exit from "effect/Exit"; |
| 38 | import { TestClock } from "effect/testing"; | 38 | import { TestClock } from "effect/testing"; |
| 39 | import { describe } from "vite-plus/test"; | 39 | import { describe } from "vite-plus/test"; |
| 40 | 40 | ||
| 41 | import type { | 41 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 42 | ProviderAdapterV2Event, | ||
| 43 | ProviderAdapterV2SessionRuntime, | ||
| 44 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 45 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; | 42 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; |
| 46 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 43 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 47 | import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | 44 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 48 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | ||
| 49 | import { | 45 | import { |
| 50 | OPENCODE_2_STILL_STOPPING, | 46 | OPENCODE_2_STILL_STOPPING, |
| 51 | OPENCODE_PROVIDER, | 47 | OPENCODE_PROVIDER, |
| ... | @@ -347,21 +343,27 @@ const resumed = ( | ... | @@ -347,21 +343,27 @@ const resumed = ( |
| 347 | return { runtime, thread }; | 343 | return { runtime, thread }; |
| 348 | }); | 344 | }); |
| 349 | 345 | ||
| 350 | const requestOf = (runtime: ProviderAdapterV2SessionRuntime) => | 346 | const requestOf = (runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime) => |
| 351 | runtime.events.pipe( | 347 | runtime.events.pipe( |
| 352 | Stream.filter( | 348 | Stream.filter( |
| 353 | (event): event is Extract<ProviderAdapterV2Event, { type: "runtime_request.updated" }> => | 349 | ( |
| 354 | event.type === "runtime_request.updated", | 350 | event, |
| 351 | ): event is Extract< | ||
| 352 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 353 | { type: "runtime_request.updated" } | ||
| 354 | > => event.type === "runtime_request.updated", | ||
| 355 | ), | 355 | ), |
| 356 | Stream.map((event) => event.runtimeRequest), | 356 | Stream.map((event) => event.runtimeRequest), |
| 357 | Stream.runHead, | 357 | Stream.runHead, |
| 358 | Effect.map(Option.getOrUndefined), | 358 | Effect.map(Option.getOrUndefined), |
| 359 | ); | 359 | ); |
| 360 | 360 | ||
| 361 | const terminalOf = (runtime: ProviderAdapterV2SessionRuntime) => | 361 | const terminalOf = (runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime) => |
| 362 | runtime.events.pipe( | 362 | runtime.events.pipe( |
| 363 | Stream.filter( | 363 | Stream.filter( |
| 364 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 364 | ( |
| 365 | event, | ||
| 366 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 365 | event.type === "turn.terminal", | 367 | event.type === "turn.terminal", |
| 366 | ), | 368 | ), |
| 367 | Stream.runHead, | 369 | Stream.runHead, |
| ... | @@ -637,7 +639,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -637,7 +639,7 @@ describe("OpenCode2 adapter", () => { |
| 637 | * The single reader of the runtime's events: resolves `attached` once the | 639 | * The single reader of the runtime's events: resolves `attached` once the |
| 638 | * running background child has its thread, then returns the turn's terminal. | 640 | * running background child has its thread, then returns the turn's terminal. |
| 639 | */ | 641 | */ |
| 640 | const watchBackgroundTurn = (runtime: ProviderAdapterV2SessionRuntime) => | 642 | const watchBackgroundTurn = (runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime) => |
| 641 | Effect.gen(function* () { | 643 | Effect.gen(function* () { |
| 642 | const attached = yield* Deferred.make<void>(); | 644 | const attached = yield* Deferred.make<void>(); |
| 643 | const terminal = yield* runtime.events.pipe( | 645 | const terminal = yield* runtime.events.pipe( |
| ... | @@ -647,7 +649,9 @@ describe("OpenCode2 adapter", () => { | ... | @@ -647,7 +649,9 @@ describe("OpenCode2 adapter", () => { |
| 647 | : Effect.void, | 649 | : Effect.void, |
| 648 | ), | 650 | ), |
| 649 | Stream.filter( | 651 | Stream.filter( |
| 650 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 652 | ( |
| 653 | event, | ||
| 654 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 651 | event.type === "turn.terminal", | 655 | event.type === "turn.terminal", |
| 652 | ), | 656 | ), |
| 653 | Stream.runHead, | 657 | Stream.runHead, |
| ... | @@ -767,7 +771,9 @@ describe("OpenCode2 adapter", () => { | ... | @@ -767,7 +771,9 @@ describe("OpenCode2 adapter", () => { |
| 767 | : Effect.void, | 771 | : Effect.void, |
| 768 | ), | 772 | ), |
| 769 | Stream.filter( | 773 | Stream.filter( |
| 770 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 774 | ( |
| 775 | event, | ||
| 776 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 771 | event.type === "turn.terminal", | 777 | event.type === "turn.terminal", |
| 772 | ), | 778 | ), |
| 773 | Stream.runHead, | 779 | Stream.runHead, |
| ... | @@ -809,7 +815,9 @@ describe("OpenCode2 adapter", () => { | ... | @@ -809,7 +815,9 @@ describe("OpenCode2 adapter", () => { |
| 809 | const firstEnded = yield* Deferred.make<void>(); | 815 | const firstEnded = yield* Deferred.make<void>(); |
| 810 | const ended = yield* runtime.events.pipe( | 816 | const ended = yield* runtime.events.pipe( |
| 811 | Stream.filter( | 817 | Stream.filter( |
| 812 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 818 | ( |
| 819 | event, | ||
| 820 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 813 | event.type === "turn.terminal", | 821 | event.type === "turn.terminal", |
| 814 | ), | 822 | ), |
| 815 | Stream.tap(() => Deferred.succeed(firstEnded, undefined)), | 823 | Stream.tap(() => Deferred.succeed(firstEnded, undefined)), |
| ... | @@ -1110,7 +1118,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -1110,7 +1118,7 @@ describe("OpenCode2 adapter", () => { |
| 1110 | event("session.execution.succeeded", { sessionID: SESSION }), | 1118 | event("session.execution.succeeded", { sessionID: SESSION }), |
| 1111 | ]; | 1119 | ]; |
| 1112 | /** The runtime's events, with the background subagent's statuses and the middle session's turns. */ | 1120 | /** The runtime's events, with the background subagent's statuses and the middle session's turns. */ |
| 1113 | const watchNested = (runtime: ProviderAdapterV2SessionRuntime) => | 1121 | const watchNested = (runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime) => |
| 1114 | Effect.gen(function* () { | 1122 | Effect.gen(function* () { |
| 1115 | const deep: Array<string> = []; | 1123 | const deep: Array<string> = []; |
| 1116 | const middleTurns = new Map<string, string>(); | 1124 | const middleTurns = new Map<string, string>(); |
| ... | @@ -1325,7 +1333,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -1325,7 +1333,7 @@ describe("OpenCode2 adapter", () => { |
| 1325 | attemptId: RunAttemptId.make("attempt:opencode2-adapter:2"), | 1333 | attemptId: RunAttemptId.make("attempt:opencode2-adapter:2"), |
| 1326 | }); | 1334 | }); |
| 1327 | const stopFirstTurn = ( | 1335 | const stopFirstTurn = ( |
| 1328 | runtime: ProviderAdapterV2SessionRuntime, | 1336 | runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1329 | thread: OrchestrationV2ProviderThread, | 1337 | thread: OrchestrationV2ProviderThread, |
| 1330 | ) => | 1338 | ) => |
| 1331 | Effect.gen(function* () { | 1339 | Effect.gen(function* () { |
| ... | @@ -1336,10 +1344,12 @@ describe("OpenCode2 adapter", () => { | ... | @@ -1336,10 +1344,12 @@ describe("OpenCode2 adapter", () => { |
| 1336 | yield* TestClock.adjust("11 seconds"); | 1344 | yield* TestClock.adjust("11 seconds"); |
| 1337 | yield* Fiber.join(interrupt); | 1345 | yield* Fiber.join(interrupt); |
| 1338 | }); | 1346 | }); |
| 1339 | const terminals = (runtime: ProviderAdapterV2SessionRuntime, count: number) => | 1347 | const terminals = (runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime, count: number) => |
| 1340 | runtime.events.pipe( | 1348 | runtime.events.pipe( |
| 1341 | Stream.filter( | 1349 | Stream.filter( |
| 1342 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 1350 | ( |
| 1351 | event, | ||
| 1352 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 1343 | event.type === "turn.terminal", | 1353 | event.type === "turn.terminal", |
| 1344 | ), | 1354 | ), |
| 1345 | Stream.take(count), | 1355 | Stream.take(count), |
| ... | @@ -2113,7 +2123,9 @@ describe("OpenCode2 adapter", () => { | ... | @@ -2113,7 +2123,9 @@ describe("OpenCode2 adapter", () => { |
| 2113 | }), | 2123 | }), |
| 2114 | ), | 2124 | ), |
| 2115 | Stream.filter( | 2125 | Stream.filter( |
| 2116 | (event): event is Extract<ProviderAdapterV2Event, { type: "turn.terminal" }> => | 2126 | ( |
| 2127 | event, | ||
| 2128 | ): event is Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn.terminal" }> => | ||
| 2117 | event.type === "turn.terminal", | 2129 | event.type === "turn.terminal", |
| 2118 | ), | 2130 | ), |
| 2119 | Stream.tap(() => Deferred.succeed(firstEnded, undefined)), | 2131 | Stream.tap(() => Deferred.succeed(firstEnded, undefined)), |
| ... | @@ -2331,7 +2343,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -2331,7 +2343,7 @@ describe("OpenCode2 adapter", () => { |
| 2331 | replyData("session.form.list", forms), | 2343 | replyData("session.form.list", forms), |
| 2332 | ]; | 2344 | ]; |
| 2333 | 2345 | ||
| 2334 | const turnItems = (collected: ReadonlyArray<ProviderAdapterV2Event>) => | 2346 | const turnItems = (collected: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>) => |
| 2335 | collected.flatMap((event) => | 2347 | collected.flatMap((event) => |
| 2336 | event.type === "turn_item.updated" ? [`${event.turnItem.type}:${event.turnItem.status}`] : [], | 2348 | event.type === "turn_item.updated" ? [`${event.turnItem.type}:${event.turnItem.status}`] : [], |
| 2337 | ); | 2349 | ); |
| ... | @@ -3043,7 +3055,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -3043,7 +3055,7 @@ describe("OpenCode2 adapter", () => { |
| 3043 | Effect.gen(function* () { | 3055 | Effect.gen(function* () { |
| 3044 | const kept = "msg_t3_turn_run-attempt:kept:1"; | 3056 | const kept = "msg_t3_turn_run-attempt:kept:1"; |
| 3045 | const dropped = "msg_t3_turn_run-attempt:dropped:1"; | 3057 | const dropped = "msg_t3_turn_run-attempt:dropped:1"; |
| 3046 | const offers: Array<ProviderContinuationRequest> = []; | 3058 | const offers: Array<ProviderContinuationRequests.ProviderContinuationRequest> = []; |
| 3047 | const { runtime, thread } = yield* resumed([ | 3059 | const { runtime, thread } = yield* resumed([ |
| 3048 | out("message.list", "<any>"), | 3060 | out("message.list", "<any>"), |
| 3049 | reply("message.list", { | 3061 | reply("message.list", { |
| ... | @@ -3727,7 +3739,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -3727,7 +3739,7 @@ describe("OpenCode2 adapter", () => { |
| 3727 | */ | 3739 | */ |
| 3728 | const continued = (after: ReadonlyArray<ProviderReplayEntry>) => | 3740 | const continued = (after: ReadonlyArray<ProviderReplayEntry>) => |
| 3729 | Effect.gen(function* () { | 3741 | Effect.gen(function* () { |
| 3730 | const offers: Array<ProviderContinuationRequest> = []; | 3742 | const offers: Array<ProviderContinuationRequests.ProviderContinuationRequest> = []; |
| 3731 | const { runtime, thread } = yield* resumed([ | 3743 | const { runtime, thread } = yield* resumed([ |
| 3732 | ...backgroundLaunch(CHILD), | 3744 | ...backgroundLaunch(CHILD), |
| 3733 | event("session.execution.succeeded", { sessionID: SESSION }), | 3745 | event("session.execution.succeeded", { sessionID: SESSION }), |
| ... | @@ -3867,7 +3879,7 @@ describe("OpenCode2 adapter", () => { | ... | @@ -3867,7 +3879,7 @@ describe("OpenCode2 adapter", () => { |
| 3867 | Effect.gen(function* () { | 3879 | Effect.gen(function* () { |
| 3868 | const reportText = `<subagent sessionID="${CHILD}" state="completed" description="Sleep">\nCHILD_OK\n</subagent>`; | 3880 | const reportText = `<subagent sessionID="${CHILD}" state="completed" description="Sleep">\nCHILD_OK\n</subagent>`; |
| 3869 | const steerId = `msg_t3_steer_${SESSION}:message:opencode2-adapter:steer`; | 3881 | const steerId = `msg_t3_steer_${SESSION}:message:opencode2-adapter:steer`; |
| 3870 | const offers: Array<ProviderContinuationRequest> = []; | 3882 | const offers: Array<ProviderContinuationRequests.ProviderContinuationRequest> = []; |
| 3871 | const { runtime, thread } = yield* resumed([ | 3883 | const { runtime, thread } = yield* resumed([ |
| 3872 | ...backgroundLaunch(CHILD), | 3884 | ...backgroundLaunch(CHILD), |
| 3873 | event("session.execution.succeeded", { sessionID: SESSION }), | 3885 | event("session.execution.succeeded", { sessionID: SESSION }), |
apps/server/src/orchestration-v2/Adapters/OpenCodeAdapterV2.testkit.ts+1-1| ... | @@ -9,7 +9,7 @@ import * as Schema from "effect/Schema"; | ... | @@ -9,7 +9,7 @@ import * as Schema from "effect/Schema"; |
| 9 | import { OpenCodeAdapterV2Driver } from "@t3tools/provider-opencode/server"; | 9 | import { OpenCodeAdapterV2Driver } from "@t3tools/provider-opencode/server"; |
| 10 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 10 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 11 | import { layerTestProviderHost } from "@t3tools/provider-testing/host"; | 11 | import { layerTestProviderHost } from "@t3tools/provider-testing/host"; |
| 12 | import * as ProviderEventLoggers from "../../provider/ProviderEventLoggers.ts"; | 12 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 13 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 13 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 14 | import { ProviderAdapterDriverCreateError } from "@t3tools/provider-core/server/adapterDriver"; | 14 | import { ProviderAdapterDriverCreateError } from "@t3tools/provider-core/server/adapterDriver"; |
| 15 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 15 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
apps/server/src/orchestration-v2/BackgroundWorkStop.integration.test.ts+5-10| ... | @@ -24,16 +24,11 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -24,16 +24,11 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 24 | import * as EffectWorker from "./EffectWorker.ts"; | 24 | import * as EffectWorker from "./EffectWorker.ts"; |
| 25 | import * as EventSink from "./EventSink.ts"; | 25 | import * as EventSink from "./EventSink.ts"; |
| 26 | import * as Orchestrator from "./Orchestrator.ts"; | 26 | import * as Orchestrator from "./Orchestrator.ts"; |
| 27 | import type { | ||
| 28 | ProviderAdapterV2Event, | ||
| 29 | ProviderAdapterV2InterruptInput, | ||
| 30 | ProviderAdapterV2Shape, | ||
| 31 | ProviderAdapterV2TurnInput, | ||
| 32 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 33 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 27 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 34 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 28 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 35 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 29 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 36 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 30 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 31 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 37 | 32 | ||
| 38 | const driver = ProviderDriverKind.make("codex"); | 33 | const driver = ProviderDriverKind.make("codex"); |
| 39 | const instanceId = ProviderInstanceId.make("codex"); | 34 | const instanceId = ProviderInstanceId.make("codex"); |
| ... | @@ -61,10 +56,10 @@ const stopEarlierBackgroundWork = ({ | ... | @@ -61,10 +56,10 @@ const stopEarlierBackgroundWork = ({ |
| 61 | Effect.scoped( | 56 | Effect.scoped( |
| 62 | Effect.gen(function* () { | 57 | Effect.gen(function* () { |
| 63 | const cwd = yield* checkpointWorkspace("background-work-stop"); | 58 | const cwd = yield* checkpointWorkspace("background-work-stop"); |
| 64 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 59 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 65 | const started: ProviderAdapterV2TurnInput[] = []; | 60 | const started: ProviderAdapter.ProviderAdapterV2TurnInput[] = []; |
| 66 | const interrupts: ProviderAdapterV2InterruptInput[] = []; | 61 | const interrupts: ProviderAdapter.ProviderAdapterV2InterruptInput[] = []; |
| 67 | const adapter: ProviderAdapterV2Shape = { | 62 | const adapter: ProviderAdapter.ProviderAdapterV2["Service"] = { |
| 68 | instanceId, | 63 | instanceId, |
| 69 | driver, | 64 | driver, |
| 70 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 65 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
apps/server/src/orchestration-v2/CheckpointCaptureService.ts+1-1| ... | @@ -252,7 +252,7 @@ export const layer: Layer.Layer< | ... | @@ -252,7 +252,7 @@ export const layer: Layer.Layer< |
| 252 | ); | 252 | ); |
| 253 | 253 | ||
| 254 | function makeCheckpointTurnItem(input: { | 254 | function makeCheckpointTurnItem(input: { |
| 255 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 255 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 256 | readonly run: OrchestrationV2Run; | 256 | readonly run: OrchestrationV2Run; |
| 257 | readonly rootNode: OrchestrationV2ExecutionNode; | 257 | readonly rootNode: OrchestrationV2ExecutionNode; |
| 258 | readonly providerThread: OrchestrationV2ProviderThread; | 258 | readonly providerThread: OrchestrationV2ProviderThread; |
apps/server/src/orchestration-v2/CheckpointRollbackService.test.ts+2-2| ... | @@ -26,7 +26,7 @@ import * as EventSink from "./EventSink.ts"; | ... | @@ -26,7 +26,7 @@ import * as EventSink from "./EventSink.ts"; |
| 26 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 26 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 27 | import * as ProjectionStore from "./ProjectionStore.ts"; | 27 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 28 | import * as ProjectStore from "./ProjectStore.ts"; | 28 | import * as ProjectStore from "./ProjectStore.ts"; |
| 29 | import type { ProviderAdapterV2RollbackThreadInput } from "@t3tools/provider-core/server/ProviderAdapter"; | 29 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 30 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 30 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 31 | import * as RuntimePolicy from "./RuntimePolicy.ts"; | 31 | import * as RuntimePolicy from "./RuntimePolicy.ts"; |
| 32 | 32 | ||
| ... | @@ -457,7 +457,7 @@ it.effect.each([ | ... | @@ -457,7 +457,7 @@ it.effect.each([ |
| 457 | Layer.mock(ProviderSessionManager.ProviderSessionManagerV2)({ | 457 | Layer.mock(ProviderSessionManager.ProviderSessionManagerV2)({ |
| 458 | open: () => | 458 | open: () => |
| 459 | Effect.succeed({ | 459 | Effect.succeed({ |
| 460 | rollbackThread: (input: ProviderAdapterV2RollbackThreadInput) => | 460 | rollbackThread: (input: ProviderAdapter.ProviderAdapterV2RollbackThreadInput) => |
| 461 | Effect.gen(function* () { | 461 | Effect.gen(function* () { |
| 462 | const count = yield* resolveCodexRollbackTurnCount(input); | 462 | const count = yield* resolveCodexRollbackTurnCount(input); |
| 463 | assert.equal(count, 2 - targetOrdinal); | 463 | assert.equal(count, 2 - targetOrdinal); |
apps/server/src/orchestration-v2/CheckpointRollbackService.ts+5-5| ... | @@ -20,10 +20,10 @@ import { | ... | @@ -20,10 +20,10 @@ import { |
| 20 | } from "./CheckpointRestoreSafety.ts"; | 20 | } from "./CheckpointRestoreSafety.ts"; |
| 21 | import { CheckpointServiceV2 } from "./CheckpointService.ts"; | 21 | import { CheckpointServiceV2 } from "./CheckpointService.ts"; |
| 22 | import { EventSinkV2 } from "./EventSink.ts"; | 22 | import { EventSinkV2 } from "./EventSink.ts"; |
| 23 | import { IdAllocatorV2 } from "@t3tools/provider-core/server/IdAllocator"; | 23 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 24 | import { ProjectionStoreV2 } from "./ProjectionStore.ts"; | 24 | import { ProjectionStoreV2 } from "./ProjectionStore.ts"; |
| 25 | import * as ProjectStore from "./ProjectStore.ts"; | 25 | import * as ProjectStore from "./ProjectStore.ts"; |
| 26 | import type { ProviderAdapterV2RollbackTarget } from "@t3tools/provider-core/server/ProviderAdapter"; | 26 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 27 | import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; | 27 | import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; |
| 28 | import { RuntimePolicyV2 } from "./RuntimePolicy.ts"; | 28 | import { RuntimePolicyV2 } from "./RuntimePolicy.ts"; |
| 29 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; | 29 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; |
| ... | @@ -85,7 +85,7 @@ export const layer: Layer.Layer< | ... | @@ -85,7 +85,7 @@ export const layer: Layer.Layer< |
| 85 | never, | 85 | never, |
| 86 | | CheckpointServiceV2 | 86 | | CheckpointServiceV2 |
| 87 | | EventSinkV2 | 87 | | EventSinkV2 |
| 88 | | IdAllocatorV2 | 88 | | IdAllocator.IdAllocatorV2 |
| 89 | | ProjectionStoreV2 | 89 | | ProjectionStoreV2 |
| 90 | | ProviderSessionManagerV2 | 90 | | ProviderSessionManagerV2 |
| 91 | | RuntimePolicyV2 | 91 | | RuntimePolicyV2 |
| ... | @@ -98,7 +98,7 @@ export const layer: Layer.Layer< | ... | @@ -98,7 +98,7 @@ export const layer: Layer.Layer< |
| 98 | Effect.gen(function* () { | 98 | Effect.gen(function* () { |
| 99 | const checkpoints = yield* CheckpointServiceV2; | 99 | const checkpoints = yield* CheckpointServiceV2; |
| 100 | const eventSink = yield* EventSinkV2; | 100 | const eventSink = yield* EventSinkV2; |
| 101 | const ids = yield* IdAllocatorV2; | 101 | const ids = yield* IdAllocator.IdAllocatorV2; |
| 102 | const projections = yield* ProjectionStoreV2; | 102 | const projections = yield* ProjectionStoreV2; |
| 103 | const sessions = yield* ProviderSessionManagerV2; | 103 | const sessions = yield* ProviderSessionManagerV2; |
| 104 | const runtimePolicy = yield* RuntimePolicyV2; | 104 | const runtimePolicy = yield* RuntimePolicyV2; |
| ... | @@ -225,7 +225,7 @@ export const layer: Layer.Layer< | ... | @@ -225,7 +225,7 @@ export const layer: Layer.Layer< |
| 225 | turn.providerThreadId === providerThread.id && | 225 | turn.providerThreadId === providerThread.id && |
| 226 | (turn.runAttemptId === null || !rolledBackAttemptIds.has(turn.runAttemptId)), | 226 | (turn.runAttemptId === null || !rolledBackAttemptIds.has(turn.runAttemptId)), |
| 227 | ); | 227 | ); |
| 228 | const rollbackTarget: ProviderAdapterV2RollbackTarget = | 228 | const rollbackTarget: ProviderAdapter.ProviderAdapterV2RollbackTarget = |
| 229 | targetOrdinal === 0 | 229 | targetOrdinal === 0 |
| 230 | ? { | 230 | ? { |
| 231 | type: "thread_start", | 231 | type: "thread_start", |
apps/server/src/orchestration-v2/CheckpointService.ts+2-2| ... | @@ -172,7 +172,7 @@ export const checkpointRefForScopeOrdinal = Effect.fn("checkpointRefForScopeOrdi | ... | @@ -172,7 +172,7 @@ export const checkpointRefForScopeOrdinal = Effect.fn("checkpointRefForScopeOrdi |
| 172 | ); | 172 | ); |
| 173 | 173 | ||
| 174 | function checkpointIdForScopeOrdinal( | 174 | function checkpointIdForScopeOrdinal( |
| 175 | idAllocator: IdAllocator.IdAllocatorV2Shape, | 175 | idAllocator: IdAllocator.IdAllocatorV2["Service"], |
| 176 | input: { | 176 | input: { |
| 177 | readonly scopeId: CheckpointScopeId; | 177 | readonly scopeId: CheckpointScopeId; |
| 178 | readonly ordinalWithinScope: number; | 178 | readonly ordinalWithinScope: number; |
| ... | @@ -185,7 +185,7 @@ function checkpointIdForScopeOrdinal( | ... | @@ -185,7 +185,7 @@ function checkpointIdForScopeOrdinal( |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | function makeRootRunScope(input: { | 187 | function makeRootRunScope(input: { |
| 188 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 188 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 189 | readonly threadId: ThreadId; | 189 | readonly threadId: ThreadId; |
| 190 | readonly runId: RunId; | 190 | readonly runId: RunId; |
| 191 | readonly rootNodeId: NodeId; | 191 | readonly rootNodeId: NodeId; |
apps/server/src/orchestration-v2/ContextHandoffBudget.test.ts+3-3| ... | @@ -1,4 +1,4 @@ | ... | @@ -1,4 +1,4 @@ |
| 1 | import type { ProviderAdapterV2HistoricalContext } from "@t3tools/provider-core/server/ProviderAdapter"; | 1 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 2 | import { assert, describe, it } from "@effect/vitest"; | 2 | import { assert, describe, it } from "@effect/vitest"; |
| 3 | import { | 3 | import { |
| 4 | ContextHandoffId, | 4 | ContextHandoffId, |
| ... | @@ -501,7 +501,7 @@ describe("handoff delivery", () => { | ... | @@ -501,7 +501,7 @@ describe("handoff delivery", () => { |
| 501 | providerThread, | 501 | providerThread, |
| 502 | budget: 16_000, | 502 | budget: 16_000, |
| 503 | alreadyDeliveredItemIds: new Set<string>(), | 503 | alreadyDeliveredItemIds: new Set<string>(), |
| 504 | inject: (value: ProviderAdapterV2HistoricalContext) => | 504 | inject: (value: ProviderAdapter.ProviderAdapterV2HistoricalContext) => |
| 505 | Effect.sync(() => { | 505 | Effect.sync(() => { |
| 506 | history.push(...historyResponseItems(value.messages, value.context)); | 506 | history.push(...historyResponseItems(value.messages, value.context)); |
| 507 | return true; | 507 | return true; |
| ... | @@ -588,7 +588,7 @@ describe("handoff delivery", () => { | ... | @@ -588,7 +588,7 @@ describe("handoff delivery", () => { |
| 588 | ...handoff, | 588 | ...handoff, |
| 589 | id: ContextHandoffId.make(`handoff:retry:${index}`), | 589 | id: ContextHandoffId.make(`handoff:retry:${index}`), |
| 590 | })); | 590 | })); |
| 591 | let captured: ProviderAdapterV2HistoricalContext | undefined; | 591 | let captured: ProviderAdapter.ProviderAdapterV2HistoricalContext | undefined; |
| 592 | const result = yield* deliverContextHandoffs({ | 592 | const result = yield* deliverContextHandoffs({ |
| 593 | handoffs: many, | 593 | handoffs: many, |
| 594 | providerThread, | 594 | providerThread, |
apps/server/src/orchestration-v2/ContextHandoffDelivery.ts+2-2| ... | @@ -2,7 +2,7 @@ import type { | ... | @@ -2,7 +2,7 @@ import type { |
| 2 | OrchestrationV2ContextHandoff, | 2 | OrchestrationV2ContextHandoff, |
| 3 | OrchestrationV2ProviderThread, | 3 | OrchestrationV2ProviderThread, |
| 4 | } from "@t3tools/contracts"; | 4 | } from "@t3tools/contracts"; |
| 5 | import type { ProviderAdapterV2HistoricalContext } from "@t3tools/provider-core/server/ProviderAdapter"; | 5 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 6 | import { ContextHandoffBudgetError } from "@t3tools/provider-core/server/failure"; | 6 | import { ContextHandoffBudgetError } from "@t3tools/provider-core/server/failure"; |
| 7 | import * as Effect from "effect/Effect"; | 7 | import * as Effect from "effect/Effect"; |
| 8 | import * as Schema from "effect/Schema"; | 8 | import * as Schema from "effect/Schema"; |
| ... | @@ -25,7 +25,7 @@ export const deliverContextHandoffs = Effect.fn("orchestrationV2.deliverContextH | ... | @@ -25,7 +25,7 @@ export const deliverContextHandoffs = Effect.fn("orchestrationV2.deliverContextH |
| 25 | readonly deferInline?: boolean; | 25 | readonly deferInline?: boolean; |
| 26 | readonly alreadyDeliveredItemIds: ReadonlySet<string>; | 26 | readonly alreadyDeliveredItemIds: ReadonlySet<string>; |
| 27 | readonly inject?: ( | 27 | readonly inject?: ( |
| 28 | history: ProviderAdapterV2HistoricalContext, | 28 | history: ProviderAdapter.ProviderAdapterV2HistoricalContext, |
| 29 | ) => Effect.Effect<boolean, InjectError>; | 29 | ) => Effect.Effect<boolean, InjectError>; |
| 30 | readonly persist: (handoff: OrchestrationV2ContextHandoff) => Effect.Effect<void, PersistError>; | 30 | readonly persist: (handoff: OrchestrationV2ContextHandoff) => Effect.Effect<void, PersistError>; |
| 31 | }) { | 31 | }) { |
apps/server/src/orchestration-v2/CursorOrchestratorV2.live.test.ts+1-1| ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; | ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; |
| 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; | 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; |
| 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; | 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; |
| 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; | 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; |
| 32 | import * as ProviderEventLoggers from "../provider/ProviderEventLoggers.ts"; | 32 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 35 | import * as ServerSettings from "../serverSettings.ts"; | 35 | import * as ServerSettings from "../serverSettings.ts"; |
apps/server/src/orchestration-v2/DelegatedCompletionDelivery.test.ts+2-2| ... | @@ -36,10 +36,10 @@ import * as WorkspacePaths from "../workspace/WorkspacePaths.ts"; | ... | @@ -36,10 +36,10 @@ import * as WorkspacePaths from "../workspace/WorkspacePaths.ts"; |
| 36 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 36 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 37 | import * as EventSink from "./EventSink.ts"; | 37 | import * as EventSink from "./EventSink.ts"; |
| 38 | import * as Orchestrator from "./Orchestrator.ts"; | 38 | import * as Orchestrator from "./Orchestrator.ts"; |
| 39 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 40 | import { continueRestartedRun } from "./RestartContinuation.ts"; | 39 | import { continueRestartedRun } from "./RestartContinuation.ts"; |
| 41 | import * as RuntimeLayer from "./runtimeLayer.ts"; | 40 | import * as RuntimeLayer from "./runtimeLayer.ts"; |
| 42 | import * as ProviderTurnStartServiceTestkit from "./ProviderTurnStartService.testkit.ts"; | 41 | import * as ProviderTurnStartServiceTestkit from "./ProviderTurnStartService.testkit.ts"; |
| 42 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 43 | 43 | ||
| 44 | const layerPlatformTest = Layer.merge( | 44 | const layerPlatformTest = Layer.merge( |
| 45 | NodeServices.layer, | 45 | NodeServices.layer, |
| ... | @@ -74,7 +74,7 @@ const orchestrationAdapter = { | ... | @@ -74,7 +74,7 @@ const orchestrationAdapter = { |
| 74 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 74 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 75 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 75 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 76 | openSession: () => Effect.die("sessions are not used by delegated completion tests"), | 76 | openSession: () => Effect.die("sessions are not used by delegated completion tests"), |
| 77 | } as ProviderAdapterV2Shape; | 77 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 78 | const providerInstance = { | 78 | const providerInstance = { |
| 79 | instanceId: modelSelection.instanceId, | 79 | instanceId: modelSelection.instanceId, |
| 80 | driverKind: driver, | 80 | driverKind: driver, |
apps/server/src/orchestration-v2/DispatchModeLimit.test.ts+2-2| ... | @@ -13,9 +13,9 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -13,9 +13,9 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 13 | import { DispatchModeLimit } from "./DispatchModeLimit.ts"; | 13 | import { DispatchModeLimit } from "./DispatchModeLimit.ts"; |
| 14 | import * as Orchestrator from "./Orchestrator.ts"; | 14 | import * as Orchestrator from "./Orchestrator.ts"; |
| 15 | import * as ProjectionStore from "./ProjectionStore.ts"; | 15 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 16 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 17 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 16 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 18 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 17 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 18 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 19 | 19 | ||
| 20 | const instanceId = ProviderInstanceId.make("codex"); | 20 | const instanceId = ProviderInstanceId.make("codex"); |
| 21 | const adapter = { | 21 | const adapter = { |
| ... | @@ -24,7 +24,7 @@ const adapter = { | ... | @@ -24,7 +24,7 @@ const adapter = { |
| 24 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 24 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 25 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 25 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 26 | openSession: () => Effect.die("No provider process needed for metadata commands"), | 26 | openSession: () => Effect.die("No provider process needed for metadata commands"), |
| 27 | } as ProviderAdapterV2Shape; | 27 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 28 | const layerDatabase = SqlitePersistence.layerMemory; | 28 | const layerDatabase = SqlitePersistence.layerMemory; |
| 29 | const layerTest = Layer.mergeAll( | 29 | const layerTest = Layer.mergeAll( |
| 30 | layerDatabase, | 30 | layerDatabase, |
apps/server/src/orchestration-v2/GrokOrchestratorV2.live.test.ts+1-1| ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; | ... | @@ -29,7 +29,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; |
| 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; | 29 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; |
| 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; | 30 | import * as ModelManifest from "../provider/ModelManifest.ts"; |
| 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; | 31 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; |
| 32 | import * as ProviderEventLoggers from "../provider/ProviderEventLoggers.ts"; | 32 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 33 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 34 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 35 | import * as ServerSettings from "../serverSettings.ts"; | 35 | import * as ServerSettings from "../serverSettings.ts"; |
apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.live.test.ts+2-2| ... | @@ -54,7 +54,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; | ... | @@ -54,7 +54,7 @@ import * as CodexInstallation from "../provider/CodexInstallation.ts"; |
| 54 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; | 54 | import * as ServerEnvironment from "../environment/ServerEnvironment.ts"; |
| 55 | import * as ModelManifest from "../provider/ModelManifest.ts"; | 55 | import * as ModelManifest from "../provider/ModelManifest.ts"; |
| 56 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; | 56 | import * as ProviderInstanceRegistryHydration from "../provider/ProviderInstanceRegistryHydration.ts"; |
| 57 | import * as ProviderEventLoggers from "../provider/ProviderEventLoggers.ts"; | 57 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 58 | import * as OpenCode2Client from "@t3tools/provider-opencode/server/v2/OpenCode2Client"; | 58 | import * as OpenCode2Client from "@t3tools/provider-opencode/server/v2/OpenCode2Client"; |
| 59 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 59 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 60 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 60 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| ... | @@ -67,7 +67,7 @@ import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry. | ... | @@ -67,7 +67,7 @@ import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry. |
| 67 | import * as ProviderTurnStartServiceTestkit from "./ProviderTurnStartService.testkit.ts"; | 67 | import * as ProviderTurnStartServiceTestkit from "./ProviderTurnStartService.testkit.ts"; |
| 68 | import * as RuntimeLayer from "./runtimeLayer.ts"; | 68 | import * as RuntimeLayer from "./runtimeLayer.ts"; |
| 69 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 69 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 70 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 70 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 71 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; | 71 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; |
| 72 | import * as ThreadManagementService from "./ThreadManagementService.ts"; | 72 | import * as ThreadManagementService from "./ThreadManagementService.ts"; |
| 73 | import * as McpSessionRegistry from "../mcp/McpSessionRegistry.ts"; | 73 | import * as McpSessionRegistry from "../mcp/McpSessionRegistry.ts"; |
apps/server/src/orchestration-v2/Orchestrator.control-reads.test.ts+2-2| ... | @@ -25,9 +25,9 @@ import * as SqlitePersistence from "../persistence/Sqlite.ts"; | ... | @@ -25,9 +25,9 @@ import * as SqlitePersistence from "../persistence/Sqlite.ts"; |
| 25 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 25 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 26 | import * as Orchestrator from "./Orchestrator.ts"; | 26 | import * as Orchestrator from "./Orchestrator.ts"; |
| 27 | import * as ProjectionStore from "./ProjectionStore.ts"; | 27 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 28 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 29 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 28 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 30 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 29 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 30 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 31 | 31 | ||
| 32 | const instanceId = ProviderInstanceId.make("codex"); | 32 | const instanceId = ProviderInstanceId.make("codex"); |
| 33 | const modelSelection = { instanceId, model: "gpt-5.1-codex" }; | 33 | const modelSelection = { instanceId, model: "gpt-5.1-codex" }; |
| ... | @@ -37,7 +37,7 @@ const adapter = { | ... | @@ -37,7 +37,7 @@ const adapter = { |
| 37 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 37 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 38 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 38 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 39 | openSession: () => Effect.die("No provider process needed for metadata controls"), | 39 | openSession: () => Effect.die("No provider process needed for metadata controls"), |
| 40 | } as ProviderAdapterV2Shape; | 40 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 41 | const layerDatabase = SqlitePersistence.layerMemory; | 41 | const layerDatabase = SqlitePersistence.layerMemory; |
| 42 | const layerTest = Layer.mergeAll( | 42 | const layerTest = Layer.mergeAll( |
| 43 | layerDatabase, | 43 | layerDatabase, |
apps/server/src/orchestration-v2/Orchestrator.ts+7-7| ... | @@ -91,7 +91,7 @@ import { isUndeliveredMailboxSteer } from "./NotificationMailbox.ts"; | ... | @@ -91,7 +91,7 @@ import { isUndeliveredMailboxSteer } from "./NotificationMailbox.ts"; |
| 91 | import { EventSinkV2 } from "./EventSink.ts"; | 91 | import { EventSinkV2 } from "./EventSink.ts"; |
| 92 | import * as EffectOutbox from "./EffectOutbox.ts"; | 92 | import * as EffectOutbox from "./EffectOutbox.ts"; |
| 93 | import type { OrchestrationEffectRequestV2, PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; | 93 | import type { OrchestrationEffectRequestV2, PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; |
| 94 | import { IdAllocatorV2 } from "@t3tools/provider-core/server/IdAllocator"; | 94 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 95 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; | 95 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; |
| 96 | import { DispatchModeLimit, exceededDispatchModeLimit } from "./DispatchModeLimit.ts"; | 96 | import { DispatchModeLimit, exceededDispatchModeLimit } from "./DispatchModeLimit.ts"; |
| 97 | import { | 97 | import { |
| ... | @@ -107,9 +107,8 @@ import { | ... | @@ -107,9 +107,8 @@ import { |
| 107 | type ProjectionCheckpointContext, | 107 | type ProjectionCheckpointContext, |
| 108 | type ShellSnapshotOptions, | 108 | type ShellSnapshotOptions, |
| 109 | } from "./ProjectionStore.ts"; | 109 | } from "./ProjectionStore.ts"; |
| 110 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 111 | import { ProviderAdapterRegistryV2 } from "./ProviderAdapterRegistry.ts"; | 110 | import { ProviderAdapterRegistryV2 } from "./ProviderAdapterRegistry.ts"; |
| 112 | import { ProviderContinuationRequests } from "@t3tools/provider-core/server/continuationRequests"; | 111 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 113 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; | 112 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; |
| 114 | import * as RunExecutionService from "./RunExecutionService.ts"; | 113 | import * as RunExecutionService from "./RunExecutionService.ts"; |
| 115 | import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; | 114 | import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; |
| ... | @@ -128,6 +127,7 @@ import { | ... | @@ -128,6 +127,7 @@ import { |
| 128 | ThreadForkServiceV2, | 127 | ThreadForkServiceV2, |
| 129 | } from "./ThreadForkService.ts"; | 128 | } from "./ThreadForkService.ts"; |
| 130 | import { planThreadDeletion } from "./ThreadDeletion.ts"; | 129 | import { planThreadDeletion } from "./ThreadDeletion.ts"; |
| 130 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 131 | 131 | ||
| 132 | export class OrchestratorDispatchError extends Schema.TaggedError<OrchestratorDispatchError>()( | 132 | export class OrchestratorDispatchError extends Schema.TaggedError<OrchestratorDispatchError>()( |
| 133 | "OrchestratorDispatchError", | 133 | "OrchestratorDispatchError", |
| ... | @@ -800,7 +800,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio | ... | @@ -800,7 +800,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio |
| 800 | const contextHandoffService = yield* ContextHandoffServiceV2; | 800 | const contextHandoffService = yield* ContextHandoffServiceV2; |
| 801 | const eventSink = yield* EventSinkV2; | 801 | const eventSink = yield* EventSinkV2; |
| 802 | const commandReceipts = yield* CommandReceiptStoreV2; | 802 | const commandReceipts = yield* CommandReceiptStoreV2; |
| 803 | const idAllocator = yield* IdAllocatorV2; | 803 | const idAllocator = yield* IdAllocator.IdAllocatorV2; |
| 804 | const projects = yield* ProjectStore.ProjectStoreV2; | 804 | const projects = yield* ProjectStore.ProjectStoreV2; |
| 805 | const projectionStore = yield* ProjectionStoreV2; | 805 | const projectionStore = yield* ProjectionStoreV2; |
| 806 | const effectOutbox = yield* EffectOutbox.EffectOutboxV2; | 806 | const effectOutbox = yield* EffectOutbox.EffectOutboxV2; |
| ... | @@ -823,7 +823,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio | ... | @@ -823,7 +823,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio |
| 823 | const fileSystem = yield* FileSystem.FileSystem; | 823 | const fileSystem = yield* FileSystem.FileSystem; |
| 824 | const path = yield* Path.Path; | 824 | const path = yield* Path.Path; |
| 825 | const providerAdapters = yield* ProviderAdapterRegistryV2; | 825 | const providerAdapters = yield* ProviderAdapterRegistryV2; |
| 826 | const continuationRequests = yield* ProviderContinuationRequests; | 826 | const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests; |
| 827 | const providerSessions = yield* ProviderSessionManagerV2; | 827 | const providerSessions = yield* ProviderSessionManagerV2; |
| 828 | const providerSwitchService = yield* ProviderSwitchServiceV2; | 828 | const providerSwitchService = yield* ProviderSwitchServiceV2; |
| 829 | const runtimePolicy = yield* RuntimePolicyV2; | 829 | const runtimePolicy = yield* RuntimePolicyV2; |
| ... | @@ -857,7 +857,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio | ... | @@ -857,7 +857,7 @@ const makeOrchestrator = Effect.fn("orchestrationV2.Orchestrator.layer")(functio |
| 857 | ); | 857 | ); |
| 858 | 858 | ||
| 859 | const providerSessionIdFor = (input: { | 859 | const providerSessionIdFor = (input: { |
| 860 | readonly adapter: ProviderAdapterV2Shape; | 860 | readonly adapter: ProviderAdapter.ProviderAdapterV2["Service"]; |
| 861 | readonly providerInstanceId: ProviderInstanceId; | 861 | readonly providerInstanceId: ProviderInstanceId; |
| 862 | readonly threadId: ThreadId; | 862 | readonly threadId: ThreadId; |
| 863 | }) => | 863 | }) => |
| ... | @@ -10955,7 +10955,7 @@ export const layer: Layer.Layer< | ... | @@ -10955,7 +10955,7 @@ export const layer: Layer.Layer< |
| 10955 | | ContextHandoffServiceV2 | 10955 | | ContextHandoffServiceV2 |
| 10956 | | EffectOutbox.EffectOutboxV2 | 10956 | | EffectOutbox.EffectOutboxV2 |
| 10957 | | EventSinkV2 | 10957 | | EventSinkV2 |
| 10958 | | IdAllocatorV2 | 10958 | | IdAllocator.IdAllocatorV2 |
| 10959 | | ProjectStore.ProjectStoreV2 | 10959 | | ProjectStore.ProjectStoreV2 |
| 10960 | | ProviderAdapterRegistryV2 | 10960 | | ProviderAdapterRegistryV2 |
| 10961 | | ProviderSessionManagerV2 | 10961 | | ProviderSessionManagerV2 |
apps/server/src/orchestration-v2/ProviderAdapterRegistry.test.ts+14-11| ... | @@ -18,36 +18,35 @@ import * as Schema from "effect/Schema"; | ... | @@ -18,36 +18,35 @@ import * as Schema from "effect/Schema"; |
| 18 | import type * as Scope from "effect/Scope"; | 18 | import type * as Scope from "effect/Scope"; |
| 19 | import * as Stream from "effect/Stream"; | 19 | import * as Stream from "effect/Stream"; |
| 20 | 20 | ||
| 21 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/ProviderAuthFlow"; | 21 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/providerAuthFlow"; |
| 22 | import type { ProviderAuthController } from "../provider/ProviderAuthService.ts"; | 22 | import type { ProviderAuthController } from "../provider/ProviderAuthService.ts"; |
| 23 | import type { ProviderInstance } from "@t3tools/provider-core/server/driver"; | 23 | import type { ProviderInstance } from "@t3tools/provider-core/server/driver"; |
| 24 | import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry.ts"; | 24 | import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry.ts"; |
| 25 | import { | ||
| 26 | ProviderAdapterOpenSessionError, | ||
| 27 | type ProviderAdapterV2Shape, | ||
| 28 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 29 | import { | 25 | import { |
| 30 | ProviderAdapterDriverCreateError, | 26 | ProviderAdapterDriverCreateError, |
| 31 | type ProviderAdapterDriver, | 27 | type ProviderAdapterDriver, |
| 32 | } from "@t3tools/provider-core/server/adapterDriver"; | 28 | } from "@t3tools/provider-core/server/adapterDriver"; |
| 33 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 29 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 30 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 34 | 31 | ||
| 35 | const driver = ProviderDriverKind.make("codex"); | 32 | const driver = ProviderDriverKind.make("codex"); |
| 36 | const personalId = ProviderInstanceId.make("codex_personal"); | 33 | const personalId = ProviderInstanceId.make("codex_personal"); |
| 37 | const workId = ProviderInstanceId.make("codex_work"); | 34 | const workId = ProviderInstanceId.make("codex_work"); |
| 38 | 35 | ||
| 39 | const makeAdapter = (instanceId: ProviderInstanceId): ProviderAdapterV2Shape => | 36 | const makeAdapter = ( |
| 37 | instanceId: ProviderInstanceId, | ||
| 38 | ): ProviderAdapter.ProviderAdapterV2["Service"] => | ||
| 40 | ({ | 39 | ({ |
| 41 | instanceId, | 40 | instanceId, |
| 42 | driver, | 41 | driver, |
| 43 | getCapabilities: () => Effect.die("capabilities are not used by this registry test"), | 42 | getCapabilities: () => Effect.die("capabilities are not used by this registry test"), |
| 44 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 43 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 45 | openSession: () => Effect.die("sessions are not used by this registry test"), | 44 | openSession: () => Effect.die("sessions are not used by this registry test"), |
| 46 | }) as ProviderAdapterV2Shape; | 45 | }) as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 47 | 46 | ||
| 48 | const makeInstance = ( | 47 | const makeInstance = ( |
| 49 | instanceId: ProviderInstanceId, | 48 | instanceId: ProviderInstanceId, |
| 50 | orchestrationAdapter: ProviderAdapterV2Shape, | 49 | orchestrationAdapter: ProviderAdapter.ProviderAdapterV2["Service"], |
| 51 | ): ProviderInstance => ({ | 50 | ): ProviderInstance => ({ |
| 52 | instanceId, | 51 | instanceId, |
| 53 | driverKind: driver, | 52 | driverKind: driver, |
| ... | @@ -101,7 +100,11 @@ const lifecycleConfigMap: ProviderInstanceConfigMap = { | ... | @@ -101,7 +100,11 @@ const lifecycleConfigMap: ProviderInstanceConfigMap = { |
| 101 | const lifecycleAdapter = makeAdapter(lifecycleInstanceId); | 100 | const lifecycleAdapter = makeAdapter(lifecycleInstanceId); |
| 102 | 101 | ||
| 103 | const makeLifecycleDriver = ( | 102 | const makeLifecycleDriver = ( |
| 104 | create: Effect.Effect<ProviderAdapterV2Shape, ProviderAdapterDriverCreateError, Scope.Scope>, | 103 | create: Effect.Effect< |
| 104 | ProviderAdapter.ProviderAdapterV2["Service"], | ||
| 105 | ProviderAdapterDriverCreateError, | ||
| 106 | Scope.Scope | ||
| 107 | >, | ||
| 105 | ): ProviderAdapterDriver<Record<string, never>> => ({ | 108 | ): ProviderAdapterDriver<Record<string, never>> => ({ |
| 106 | driverKind: lifecycleDriver, | 109 | driverKind: lifecycleDriver, |
| 107 | configSchema: Schema.Struct({}), | 110 | configSchema: Schema.Struct({}), |
| ... | @@ -263,7 +266,7 @@ it.effect( | ... | @@ -263,7 +266,7 @@ it.effect( |
| 263 | }, | 266 | }, |
| 264 | }) | 267 | }) |
| 265 | .pipe(Effect.flip); | 268 | .pipe(Effect.flip); |
| 266 | assert.instanceOf(error, ProviderAdapterOpenSessionError); | 269 | assert.instanceOf(error, ProviderAdapter.ProviderAdapterOpenSessionError); |
| 267 | assert.instanceOf(error.cause, ProviderSetupError); | 270 | assert.instanceOf(error.cause, ProviderSetupError); |
| 268 | }), | 271 | }), |
| 269 | ); | 272 | ); |
| ... | @@ -287,7 +290,7 @@ it.effect("interrupts admitted session startup when a shared peer signs out", () | ... | @@ -287,7 +290,7 @@ it.effect("interrupts admitted session startup when a shared peer signs out", () |
| 287 | authenticate: () => Effect.void, | 290 | authenticate: () => Effect.void, |
| 288 | logout: Effect.void, | 291 | logout: Effect.void, |
| 289 | }); | 292 | }); |
| 290 | const adapter: ProviderAdapterV2Shape = { | 293 | const adapter: ProviderAdapter.ProviderAdapterV2["Service"] = { |
| 291 | ...workAdapter, | 294 | ...workAdapter, |
| 292 | openSession: () => | 295 | openSession: () => |
| 293 | Effect.gen(function* () { | 296 | Effect.gen(function* () { |
apps/server/src/orchestration-v2/ProviderAdapterRegistry.ts+8-8| ... | @@ -48,11 +48,11 @@ export type ProviderAdapterRegistryV2Error = typeof ProviderAdapterRegistryV2Err | ... | @@ -48,11 +48,11 @@ export type ProviderAdapterRegistryV2Error = typeof ProviderAdapterRegistryV2Err |
| 48 | export interface ProviderAdapterRegistryV2Shape { | 48 | export interface ProviderAdapterRegistryV2Shape { |
| 49 | readonly get: ( | 49 | readonly get: ( |
| 50 | instanceId: ProviderInstanceId, | 50 | instanceId: ProviderInstanceId, |
| 51 | ) => Effect.Effect<ProviderAdapter.ProviderAdapterV2Shape, ProviderAdapterRegistryV2Error>; | 51 | ) => Effect.Effect<ProviderAdapter.ProviderAdapterV2["Service"], ProviderAdapterRegistryV2Error>; |
| 52 | readonly list: () => Effect.Effect<ReadonlyArray<ProviderInstanceId>>; | 52 | readonly list: () => Effect.Effect<ReadonlyArray<ProviderInstanceId>>; |
| 53 | readonly getMetadata?: (instanceId: ProviderInstanceId) => Effect.Effect< | 53 | readonly getMetadata?: (instanceId: ProviderInstanceId) => Effect.Effect< |
| 54 | { | 54 | { |
| 55 | readonly driver: ProviderAdapter.ProviderAdapterV2Shape["driver"]; | 55 | readonly driver: ProviderAdapter.ProviderAdapterV2["Service"]["driver"]; |
| 56 | readonly continuationKey: string; | 56 | readonly continuationKey: string; |
| 57 | readonly enabled: boolean; | 57 | readonly enabled: boolean; |
| 58 | readonly capabilities: OrchestrationV2ProviderCapabilities; | 58 | readonly capabilities: OrchestrationV2ProviderCapabilities; |
| ... | @@ -134,7 +134,7 @@ export const layerFromProviderInstanceRegistry: Layer.Layer< | ... | @@ -134,7 +134,7 @@ export const layerFromProviderInstanceRegistry: Layer.Layer< |
| 134 | ), | 134 | ), |
| 135 | ); | 135 | ); |
| 136 | }, | 136 | }, |
| 137 | } satisfies ProviderAdapter.ProviderAdapterV2Shape); | 137 | } satisfies ProviderAdapter.ProviderAdapterV2["Service"]); |
| 138 | }), | 138 | }), |
| 139 | ), | 139 | ), |
| 140 | list: () => | 140 | list: () => |
| ... | @@ -169,7 +169,7 @@ export const ProviderAdapterRegistryBuildError = Schema.Union([ProviderAdapterDr | ... | @@ -169,7 +169,7 @@ export const ProviderAdapterRegistryBuildError = Schema.Union([ProviderAdapterDr |
| 169 | export type ProviderAdapterRegistryBuildError = typeof ProviderAdapterRegistryBuildError.Type; | 169 | export type ProviderAdapterRegistryBuildError = typeof ProviderAdapterRegistryBuildError.Type; |
| 170 | 170 | ||
| 171 | function makeRegistry( | 171 | function makeRegistry( |
| 172 | adapters: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Shape>, | 172 | adapters: ReadonlyArray<ProviderAdapter.ProviderAdapterV2["Service"]>, |
| 173 | ): ProviderAdapterRegistryV2Shape { | 173 | ): ProviderAdapterRegistryV2Shape { |
| 174 | return { | 174 | return { |
| 175 | get: (instanceId) => | 175 | get: (instanceId) => |
| ... | @@ -185,7 +185,7 @@ function makeRegistry( | ... | @@ -185,7 +185,7 @@ function makeRegistry( |
| 185 | } | 185 | } |
| 186 | 186 | ||
| 187 | export function layerFromAdapters( | 187 | export function layerFromAdapters( |
| 188 | adapters: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Shape>, | 188 | adapters: ReadonlyArray<ProviderAdapter.ProviderAdapterV2["Service"]>, |
| 189 | ): Layer.Layer<ProviderAdapterRegistryV2> { | 189 | ): Layer.Layer<ProviderAdapterRegistryV2> { |
| 190 | return Layer.succeed( | 190 | return Layer.succeed( |
| 191 | ProviderAdapterRegistryV2, | 191 | ProviderAdapterRegistryV2, |
| ... | @@ -194,7 +194,7 @@ export function layerFromAdapters( | ... | @@ -194,7 +194,7 @@ export function layerFromAdapters( |
| 194 | } | 194 | } |
| 195 | 195 | ||
| 196 | export function layerFromAdaptersEffect<R, E>( | 196 | export function layerFromAdaptersEffect<R, E>( |
| 197 | adapters: Effect.Effect<ReadonlyArray<ProviderAdapter.ProviderAdapterV2Shape>, E, R>, | 197 | adapters: Effect.Effect<ReadonlyArray<ProviderAdapter.ProviderAdapterV2["Service"]>, E, R>, |
| 198 | ): Layer.Layer<ProviderAdapterRegistryV2, E, R> { | 198 | ): Layer.Layer<ProviderAdapterRegistryV2, E, R> { |
| 199 | return Layer.effect( | 199 | return Layer.effect( |
| 200 | ProviderAdapterRegistryV2, | 200 | ProviderAdapterRegistryV2, |
| ... | @@ -203,7 +203,7 @@ export function layerFromAdaptersEffect<R, E>( | ... | @@ -203,7 +203,7 @@ export function layerFromAdaptersEffect<R, E>( |
| 203 | } | 203 | } |
| 204 | 204 | ||
| 205 | export function layerSingle( | 205 | export function layerSingle( |
| 206 | adapter: ProviderAdapter.ProviderAdapterV2Shape, | 206 | adapter: ProviderAdapter.ProviderAdapterV2["Service"], |
| 207 | ): Layer.Layer<ProviderAdapterRegistryV2> { | 207 | ): Layer.Layer<ProviderAdapterRegistryV2> { |
| 208 | return layerFromAdapters([adapter]); | 208 | return layerFromAdapters([adapter]); |
| 209 | } | 209 | } |
| ... | @@ -217,7 +217,7 @@ const decodedConfigEnabled = (config: unknown): boolean | undefined => { | ... | @@ -217,7 +217,7 @@ const decodedConfigEnabled = (config: unknown): boolean | undefined => { |
| 217 | }; | 217 | }; |
| 218 | 218 | ||
| 219 | interface LiveAdapterEntry { | 219 | interface LiveAdapterEntry { |
| 220 | readonly adapter: ProviderAdapter.ProviderAdapterV2Shape; | 220 | readonly adapter: ProviderAdapter.ProviderAdapterV2["Service"]; |
| 221 | readonly scope: Scope.Closeable; | 221 | readonly scope: Scope.Closeable; |
| 222 | readonly entry: ProviderInstanceConfig; | 222 | readonly entry: ProviderInstanceConfig; |
| 223 | } | 223 | } |
apps/server/src/orchestration-v2/ProviderContinuationService.test.ts+1-1| ... | @@ -19,7 +19,7 @@ import * as Semaphore from "effect/Semaphore"; | ... | @@ -19,7 +19,7 @@ import * as Semaphore from "effect/Semaphore"; |
| 19 | import * as TestClock from "effect/testing/TestClock"; | 19 | import * as TestClock from "effect/testing/TestClock"; |
| 20 | 20 | ||
| 21 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 21 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 22 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 22 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 23 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; | 23 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; |
| 24 | import * as ThreadManagementService from "./ThreadManagementService.ts"; | 24 | import * as ThreadManagementService from "./ThreadManagementService.ts"; |
| 25 | 25 |
apps/server/src/orchestration-v2/ProviderContinuationService.ts+1-1| ... | @@ -4,7 +4,7 @@ import * as Layer from "effect/Layer"; | ... | @@ -4,7 +4,7 @@ import * as Layer from "effect/Layer"; |
| 4 | import * as Ref from "effect/Ref"; | 4 | import * as Ref from "effect/Ref"; |
| 5 | 5 | ||
| 6 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 6 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 7 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 7 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 8 | import * as ThreadManagementService from "./ThreadManagementService.ts"; | 8 | import * as ThreadManagementService from "./ThreadManagementService.ts"; |
| 9 | import { isUndeliveredMailboxSteer } from "./NotificationMailbox.ts"; | 9 | import { isUndeliveredMailboxSteer } from "./NotificationMailbox.ts"; |
| 10 | 10 |
apps/server/src/orchestration-v2/ProviderEventIngestor.ts+4-5| ... | @@ -31,7 +31,7 @@ import * as AnalyticsService from "../telemetry/AnalyticsService.ts"; | ... | @@ -31,7 +31,7 @@ import * as AnalyticsService from "../telemetry/AnalyticsService.ts"; |
| 31 | import * as EventSink from "./EventSink.ts"; | 31 | import * as EventSink from "./EventSink.ts"; |
| 32 | import * as ProjectionStore from "./ProjectionStore.ts"; | 32 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 33 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 33 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 34 | import { ProviderAdapterV2Event } from "@t3tools/provider-core/server/ProviderAdapter"; | 34 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 35 | import { makeProviderFailureTurnItem } from "@t3tools/provider-core/server/failure"; | 35 | import { makeProviderFailureTurnItem } from "@t3tools/provider-core/server/failure"; |
| 36 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; | 36 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; |
| 37 | import { stripUnservedToolOutputImageBytes } from "./toolOutputImageBytes.ts"; | 37 | import { stripUnservedToolOutputImageBytes } from "./toolOutputImageBytes.ts"; |
| ... | @@ -41,7 +41,7 @@ export class ProviderEventNormalizeError extends Schema.TaggedError<ProviderEven | ... | @@ -41,7 +41,7 @@ export class ProviderEventNormalizeError extends Schema.TaggedError<ProviderEven |
| 41 | { | 41 | { |
| 42 | providerSessionId: ProviderSessionId, | 42 | providerSessionId: ProviderSessionId, |
| 43 | threadId: ThreadId, | 43 | threadId: ThreadId, |
| 44 | providerEvent: ProviderAdapterV2Event, | 44 | providerEvent: ProviderAdapter.ProviderAdapterV2Event, |
| 45 | cause: Schema.optional(Schema.Defect()), | 45 | cause: Schema.optional(Schema.Defect()), |
| 46 | }, | 46 | }, |
| 47 | ) { | 47 | ) { |
| ... | @@ -93,7 +93,7 @@ export const layerAnalytics = Layer.effect( | ... | @@ -93,7 +93,7 @@ export const layerAnalytics = Layer.effect( |
| 93 | ); | 93 | ); |
| 94 | 94 | ||
| 95 | function providerTurnAnalyticsProperties(input: { | 95 | function providerTurnAnalyticsProperties(input: { |
| 96 | readonly driver: ProviderAdapterV2Event["driver"]; | 96 | readonly driver: ProviderAdapter.ProviderAdapterV2Event["driver"]; |
| 97 | readonly providerTurn: OrchestrationV2ProviderTurn; | 97 | readonly providerTurn: OrchestrationV2ProviderTurn; |
| 98 | readonly context?: ProviderTurnAnalyticsContext; | 98 | readonly context?: ProviderTurnAnalyticsContext; |
| 99 | }): Readonly<Record<string, unknown>> { | 99 | }): Readonly<Record<string, unknown>> { |
| ... | @@ -257,7 +257,7 @@ export interface ProviderEventIngestInput { | ... | @@ -257,7 +257,7 @@ export interface ProviderEventIngestInput { |
| 257 | readonly runId?: RunId; | 257 | readonly runId?: RunId; |
| 258 | readonly nodeId?: NodeId; | 258 | readonly nodeId?: NodeId; |
| 259 | readonly rawEventId?: RawEventId; | 259 | readonly rawEventId?: RawEventId; |
| 260 | readonly event: ProviderAdapterV2Event; | 260 | readonly event: ProviderAdapter.ProviderAdapterV2Event; |
| 261 | readonly analyticsContext?: ProviderTurnAnalyticsContext; | 261 | readonly analyticsContext?: ProviderTurnAnalyticsContext; |
| 262 | } | 262 | } |
| 263 | 263 | ||
| ... | @@ -657,7 +657,6 @@ export const layer: Layer.Layer< | ... | @@ -657,7 +657,6 @@ export const layer: Layer.Layer< |
| 657 | yield* makeDomainEvent(input, { | 657 | yield* makeDomainEvent(input, { |
| 658 | type: "turn-item.updated", | 658 | type: "turn-item.updated", |
| 659 | payload: makeProviderFailureTurnItem({ | 659 | payload: makeProviderFailureTurnItem({ |
| 660 | idAllocator, | ||
| 661 | driver: input.event.driver, | 660 | driver: input.event.driver, |
| 662 | threadId: input.threadId, | 661 | threadId: input.threadId, |
| 663 | runId: input.runId ?? null, | 662 | runId: input.runId ?? null, |
apps/server/src/orchestration-v2/ProviderSessionManager.test.ts+15-19| ... | @@ -44,18 +44,11 @@ import * as EventSink from "./EventSink.ts"; | ... | @@ -44,18 +44,11 @@ import * as EventSink from "./EventSink.ts"; |
| 44 | import * as EventStore from "./EventStore.ts"; | 44 | import * as EventStore from "./EventStore.ts"; |
| 45 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 45 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 46 | import * as ProjectionStore from "./ProjectionStore.ts"; | 46 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 47 | import { | ||
| 48 | ProviderAdapterEventStreamError, | ||
| 49 | type ProviderAdapterV2Event, | ||
| 50 | ProviderAdapterProtocolError, | ||
| 51 | type ProviderAdapterV2RuntimePolicy, | ||
| 52 | type ProviderAdapterV2SessionRuntime, | ||
| 53 | type ProviderAdapterV2Shape, | ||
| 54 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 55 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 47 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 56 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; | 48 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; |
| 57 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; | 49 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; |
| 58 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 50 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 51 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 59 | 52 | ||
| 60 | const layerTestDatabase = SqlitePersistence.layerMemory; | 53 | const layerTestDatabase = SqlitePersistence.layerMemory; |
| 61 | const layerTestStores = Layer.merge(EventStore.layer, ProjectionStore.layer).pipe( | 54 | const layerTestStores = Layer.merge(EventStore.layer, ProjectionStore.layer).pipe( |
| ... | @@ -167,7 +160,10 @@ interface TestProviderRuntimeState { | ... | @@ -167,7 +160,10 @@ interface TestProviderRuntimeState { |
| 167 | readonly interruptCount: number; | 160 | readonly interruptCount: number; |
| 168 | readonly resumeCount: number; | 161 | readonly resumeCount: number; |
| 169 | readonly unloadedNativeThreadIds: ReadonlyArray<string>; | 162 | readonly unloadedNativeThreadIds: ReadonlyArray<string>; |
| 170 | readonly eventQueues: ReadonlyMap<string, Queue.Queue<ProviderAdapterV2Event, Cause.Done>>; | 163 | readonly eventQueues: ReadonlyMap< |
| 164 | string, | ||
| 165 | Queue.Queue<ProviderAdapter.ProviderAdapterV2Event, Cause.Done> | ||
| 166 | >; | ||
| 171 | } | 167 | } |
| 172 | 168 | ||
| 173 | const emptyState: TestProviderRuntimeState = { | 169 | const emptyState: TestProviderRuntimeState = { |
| ... | @@ -189,7 +185,7 @@ const runtimePolicy = { | ... | @@ -189,7 +185,7 @@ const runtimePolicy = { |
| 189 | runtimeMode: "full-access", | 185 | runtimeMode: "full-access", |
| 190 | interactionMode: "default", | 186 | interactionMode: "default", |
| 191 | cwd: process.cwd(), | 187 | cwd: process.cwd(), |
| 192 | } satisfies ProviderAdapterV2RuntimePolicy; | 188 | } satisfies ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 193 | 189 | ||
| 194 | function makeProviderSession(input: { | 190 | function makeProviderSession(input: { |
| 195 | readonly providerSessionId: ProviderSessionId; | 191 | readonly providerSessionId: ProviderSessionId; |
| ... | @@ -211,7 +207,7 @@ function makeProviderSession(input: { | ... | @@ -211,7 +207,7 @@ function makeProviderSession(input: { |
| 211 | } | 207 | } |
| 212 | 208 | ||
| 213 | function makeThreadCreatedEvent(input: { | 209 | function makeThreadCreatedEvent(input: { |
| 214 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 210 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 215 | readonly threadId: ThreadId; | 211 | readonly threadId: ThreadId; |
| 216 | readonly now: DateTime.Utc; | 212 | readonly now: DateTime.Utc; |
| 217 | readonly projectId?: ProjectId; | 213 | readonly projectId?: ProjectId; |
| ... | @@ -264,7 +260,7 @@ function makeThreadCreatedEvent(input: { | ... | @@ -264,7 +260,7 @@ function makeThreadCreatedEvent(input: { |
| 264 | } | 260 | } |
| 265 | 261 | ||
| 266 | function makeProviderThread(input: { | 262 | function makeProviderThread(input: { |
| 267 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 263 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 268 | readonly threadId: ThreadId; | 264 | readonly threadId: ThreadId; |
| 269 | readonly providerSessionId: ProviderSessionId; | 265 | readonly providerSessionId: ProviderSessionId; |
| 270 | readonly now: DateTime.Utc; | 266 | readonly now: DateTime.Utc; |
| ... | @@ -299,7 +295,7 @@ function makeProviderThread(input: { | ... | @@ -299,7 +295,7 @@ function makeProviderThread(input: { |
| 299 | 295 | ||
| 300 | function unimplemented(detail: string) { | 296 | function unimplemented(detail: string) { |
| 301 | return Effect.fail( | 297 | return Effect.fail( |
| 302 | new ProviderAdapterProtocolError({ | 298 | new ProviderAdapter.ProviderAdapterProtocolError({ |
| 303 | driver: CODEX_DRIVER, | 299 | driver: CODEX_DRIVER, |
| 304 | detail, | 300 | detail, |
| 305 | }), | 301 | }), |
| ... | @@ -328,7 +324,7 @@ function makeProviderAdapter( | ... | @@ -328,7 +324,7 @@ function makeProviderAdapter( |
| 328 | /** Completed when a hanging scope close reaches its wedged finalizer. */ | 324 | /** Completed when a hanging scope close reaches its wedged finalizer. */ |
| 329 | readonly scopeCloseReached?: Deferred.Deferred<void>; | 325 | readonly scopeCloseReached?: Deferred.Deferred<void>; |
| 330 | } = {}, | 326 | } = {}, |
| 331 | ): ProviderAdapterV2Shape { | 327 | ): ProviderAdapter.ProviderAdapterV2["Service"] { |
| 332 | const countClose = Effect.addFinalizer(() => | 328 | const countClose = Effect.addFinalizer(() => |
| 333 | Ref.update(state, (current) => ({ | 329 | Ref.update(state, (current) => ({ |
| 334 | ...current, | 330 | ...current, |
| ... | @@ -371,7 +367,7 @@ function makeProviderAdapter( | ... | @@ -371,7 +367,7 @@ function makeProviderAdapter( |
| 371 | ]); | 367 | ]); |
| 372 | } | 368 | } |
| 373 | const now = yield* DateTime.now; | 369 | const now = yield* DateTime.now; |
| 374 | const events = yield* Queue.unbounded<ProviderAdapterV2Event, Cause.Done>(); | 370 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event, Cause.Done>(); |
| 375 | const session = makeProviderSession({ | 371 | const session = makeProviderSession({ |
| 376 | providerSessionId: input.providerSessionId, | 372 | providerSessionId: input.providerSessionId, |
| 377 | now, | 373 | now, |
| ... | @@ -398,7 +394,7 @@ function makeProviderAdapter( | ... | @@ -398,7 +394,7 @@ function makeProviderAdapter( |
| 398 | providerSession: session, | 394 | providerSession: session, |
| 399 | events: options.failEventStream | 395 | events: options.failEventStream |
| 400 | ? Stream.fail( | 396 | ? Stream.fail( |
| 401 | new ProviderAdapterEventStreamError({ | 397 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 402 | driver: CODEX_DRIVER, | 398 | driver: CODEX_DRIVER, |
| 403 | providerSessionId: input.providerSessionId, | 399 | providerSessionId: input.providerSessionId, |
| 404 | cause: "process exited", | 400 | cause: "process exited", |
| ... | @@ -442,7 +438,7 @@ function makeProviderAdapter( | ... | @@ -442,7 +438,7 @@ function makeProviderAdapter( |
| 442 | readThreadSnapshot: () => unimplemented("readThreadSnapshot unused in test"), | 438 | readThreadSnapshot: () => unimplemented("readThreadSnapshot unused in test"), |
| 443 | rollbackThread: () => unimplemented("rollbackThread unused in test"), | 439 | rollbackThread: () => unimplemented("rollbackThread unused in test"), |
| 444 | forkThread: () => unimplemented("forkThread unused in test"), | 440 | forkThread: () => unimplemented("forkThread unused in test"), |
| 445 | } satisfies ProviderAdapterV2SessionRuntime; | 441 | } satisfies ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 446 | }), | 442 | }), |
| 447 | }; | 443 | }; |
| 448 | } | 444 | } |
| ... | @@ -674,7 +670,7 @@ function runBrowserAccessScenario(input: { | ... | @@ -674,7 +670,7 @@ function runBrowserAccessScenario(input: { |
| 674 | } | 670 | } |
| 675 | 671 | ||
| 676 | function makePendingRuntimeRequestEvents(input: { | 672 | function makePendingRuntimeRequestEvents(input: { |
| 677 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 673 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 678 | readonly threadId: ThreadId; | 674 | readonly threadId: ThreadId; |
| 679 | readonly providerSessionId: ProviderSessionId; | 675 | readonly providerSessionId: ProviderSessionId; |
| 680 | readonly providerThread: OrchestrationV2ProviderThread; | 676 | readonly providerThread: OrchestrationV2ProviderThread; |
| ... | @@ -795,7 +791,7 @@ function makePendingRuntimeRequestEvents(input: { | ... | @@ -795,7 +791,7 @@ function makePendingRuntimeRequestEvents(input: { |
| 795 | driver: CODEX_DRIVER, | 791 | driver: CODEX_DRIVER, |
| 796 | turnItem, | 792 | turnItem, |
| 797 | }, | 793 | }, |
| 798 | ] satisfies ReadonlyArray<ProviderAdapterV2Event>; | 794 | ] satisfies ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>; |
| 799 | return { events, providerEvents, requestId, nodeId }; | 795 | return { events, providerEvents, requestId, nodeId }; |
| 800 | }); | 796 | }); |
| 801 | } | 797 | } |
apps/server/src/orchestration-v2/ProviderSessionManager.ts+37-31| ... | @@ -46,14 +46,7 @@ import * as McpSessionRegistry from "../mcp/McpSessionRegistry.ts"; | ... | @@ -46,14 +46,7 @@ import * as McpSessionRegistry from "../mcp/McpSessionRegistry.ts"; |
| 46 | import * as EventSink from "./EventSink.ts"; | 46 | import * as EventSink from "./EventSink.ts"; |
| 47 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 47 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 48 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; | 48 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; |
| 49 | import { | 49 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 50 | ProviderAdapterEventStreamError, | ||
| 51 | ProviderAdapterV2RuntimePolicy, | ||
| 52 | type ProviderAdapterV2Error, | ||
| 53 | type ProviderAdapterV2Event, | ||
| 54 | type ProviderAdapterV2EventSubscription, | ||
| 55 | type ProviderAdapterV2SessionRuntime, | ||
| 56 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 57 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 50 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 58 | import * as ProjectionStore from "./ProjectionStore.ts"; | 51 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 59 | 52 | ||
| ... | @@ -161,14 +154,20 @@ export interface ProviderSessionManagerV2Shape { | ... | @@ -161,14 +154,20 @@ export interface ProviderSessionManagerV2Shape { |
| 161 | readonly threadId: ThreadId; | 154 | readonly threadId: ThreadId; |
| 162 | readonly providerSessionId: ProviderSessionId; | 155 | readonly providerSessionId: ProviderSessionId; |
| 163 | readonly modelSelection: ModelSelection; | 156 | readonly modelSelection: ModelSelection; |
| 164 | readonly runtimePolicy: ProviderAdapterV2RuntimePolicy; | 157 | readonly runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 165 | readonly resumeFromSession?: OrchestrationV2ProviderSession; | 158 | readonly resumeFromSession?: OrchestrationV2ProviderSession; |
| 166 | readonly initialNativeThreadId?: string; | 159 | readonly initialNativeThreadId?: string; |
| 167 | readonly initialProviderItemIdentityVersion?: 2; | 160 | readonly initialProviderItemIdentityVersion?: 2; |
| 168 | }) => Effect.Effect<ProviderAdapterV2SessionRuntime, ProviderSessionManagerV2Error>; | 161 | }) => Effect.Effect< |
| 162 | ProviderAdapter.ProviderAdapterV2SessionRuntime, | ||
| 163 | ProviderSessionManagerV2Error | ||
| 164 | >; | ||
| 169 | readonly get: ( | 165 | readonly get: ( |
| 170 | providerSessionId: ProviderSessionId, | 166 | providerSessionId: ProviderSessionId, |
| 171 | ) => Effect.Effect<Option.Option<ProviderAdapterV2SessionRuntime>, ProviderSessionManagerV2Error>; | 167 | ) => Effect.Effect< |
| 168 | Option.Option<ProviderAdapter.ProviderAdapterV2SessionRuntime>, | ||
| 169 | ProviderSessionManagerV2Error | ||
| 170 | >; | ||
| 172 | readonly close: ( | 171 | readonly close: ( |
| 173 | providerSessionId: ProviderSessionId, | 172 | providerSessionId: ProviderSessionId, |
| 174 | ) => Effect.Effect<void, ProviderSessionManagerV2Error>; | 173 | ) => Effect.Effect<void, ProviderSessionManagerV2Error>; |
| ... | @@ -211,8 +210,8 @@ interface LiveSessionEntry { | ... | @@ -211,8 +210,8 @@ interface LiveSessionEntry { |
| 211 | */ | 210 | */ |
| 212 | readonly mcpCredentialIdByThread: ReadonlyMap<ThreadId, string>; | 211 | readonly mcpCredentialIdByThread: ReadonlyMap<ThreadId, string>; |
| 213 | readonly supportsMultipleProviderThreads: boolean; | 212 | readonly supportsMultipleProviderThreads: boolean; |
| 214 | readonly runtime: ProviderAdapterV2SessionRuntime; | 213 | readonly runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 215 | readonly exposedRuntime: ProviderAdapterV2SessionRuntime; | 214 | readonly exposedRuntime: ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 216 | readonly eventSubscribers: Ref.Ref< | 215 | readonly eventSubscribers: Ref.Ref< |
| 217 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> | 216 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> |
| 218 | >; | 217 | >; |
| ... | @@ -244,10 +243,10 @@ interface IdleThreadUnload { | ... | @@ -244,10 +243,10 @@ interface IdleThreadUnload { |
| 244 | } | 243 | } |
| 245 | 244 | ||
| 246 | type ProviderSessionEventSignal = | 245 | type ProviderSessionEventSignal = |
| 247 | | { readonly type: "event"; readonly event: ProviderAdapterV2Event } | 246 | | { readonly type: "event"; readonly event: ProviderAdapter.ProviderAdapterV2Event } |
| 248 | | { | 247 | | { |
| 249 | readonly type: "failure"; | 248 | readonly type: "failure"; |
| 250 | readonly cause: Cause.Cause<ProviderAdapterV2Error>; | 249 | readonly cause: Cause.Cause<ProviderAdapter.ProviderAdapterV2Error>; |
| 251 | }; | 250 | }; |
| 252 | 251 | ||
| 253 | export interface ProviderSessionManagerV2LayerOptions { | 252 | export interface ProviderSessionManagerV2LayerOptions { |
| ... | @@ -279,7 +278,9 @@ function sessionKey(providerSessionId: ProviderSessionId): string { | ... | @@ -279,7 +278,9 @@ function sessionKey(providerSessionId: ProviderSessionId): string { |
| 279 | * Their node and transcript item are runless too, so they bypass the normal | 278 | * Their node and transcript item are runless too, so they bypass the normal |
| 280 | * per-run subscriber and are persisted by the session event pump. | 279 | * per-run subscriber and are persisted by the session event pump. |
| 281 | */ | 280 | */ |
| 282 | function sessionScopedRuntimeRequestThreadId(event: ProviderAdapterV2Event): ThreadId | undefined { | 281 | function sessionScopedRuntimeRequestThreadId( |
| 282 | event: ProviderAdapter.ProviderAdapterV2Event, | ||
| 283 | ): ThreadId | undefined { | ||
| 283 | switch (event.type) { | 284 | switch (event.type) { |
| 284 | case "runtime_request.updated": | 285 | case "runtime_request.updated": |
| 285 | return event.runtimeRequest.providerTurnId === null ? event.threadId : undefined; | 286 | return event.runtimeRequest.providerTurnId === null ? event.threadId : undefined; |
| ... | @@ -298,7 +299,9 @@ function sessionScopedRuntimeRequestThreadId(event: ProviderAdapterV2Event): Thr | ... | @@ -298,7 +299,9 @@ function sessionScopedRuntimeRequestThreadId(event: ProviderAdapterV2Event): Thr |
| 298 | } | 299 | } |
| 299 | 300 | ||
| 300 | function providerThreadRuntimeKey( | 301 | function providerThreadRuntimeKey( |
| 301 | providerThread: Parameters<ProviderAdapterV2SessionRuntime["resumeThread"]>[0]["providerThread"], | 302 | providerThread: Parameters< |
| 303 | ProviderAdapter.ProviderAdapterV2SessionRuntime["resumeThread"] | ||
| 304 | >[0]["providerThread"], | ||
| 302 | ): string { | 305 | ): string { |
| 303 | const nativeThreadRef = providerThread.nativeThreadRef; | 306 | const nativeThreadRef = providerThread.nativeThreadRef; |
| 304 | return nativeThreadRef === null | 307 | return nativeThreadRef === null |
| ... | @@ -308,10 +311,10 @@ function providerThreadRuntimeKey( | ... | @@ -308,10 +311,10 @@ function providerThreadRuntimeKey( |
| 308 | 311 | ||
| 309 | function providerThreadLoadKey(input: { | 312 | function providerThreadLoadKey(input: { |
| 310 | readonly providerThread: Parameters< | 313 | readonly providerThread: Parameters< |
| 311 | ProviderAdapterV2SessionRuntime["resumeThread"] | 314 | ProviderAdapter.ProviderAdapterV2SessionRuntime["resumeThread"] |
| 312 | >[0]["providerThread"]; | 315 | >[0]["providerThread"]; |
| 313 | readonly modelSelection?: ModelSelection; | 316 | readonly modelSelection?: ModelSelection; |
| 314 | readonly runtimePolicy?: ProviderAdapterV2RuntimePolicy; | 317 | readonly runtimePolicy?: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 315 | }): string { | 318 | }): string { |
| 316 | return JSON.stringify({ | 319 | return JSON.stringify({ |
| 317 | providerThread: providerThreadRuntimeKey(input.providerThread), | 320 | providerThread: providerThreadRuntimeKey(input.providerThread), |
| ... | @@ -575,7 +578,7 @@ export const layerWithOptions = ( | ... | @@ -575,7 +578,7 @@ export const layerWithOptions = ( |
| 575 | 578 | ||
| 576 | const failSubscribers = (entry: LiveSessionEntry, detail: string) => | 579 | const failSubscribers = (entry: LiveSessionEntry, detail: string) => |
| 577 | Effect.gen(function* () { | 580 | Effect.gen(function* () { |
| 578 | const error = new ProviderAdapterEventStreamError({ | 581 | const error = new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 579 | driver: entry.runtime.driver, | 582 | driver: entry.runtime.driver, |
| 580 | providerSessionId: entry.runtime.providerSessionId, | 583 | providerSessionId: entry.runtime.providerSessionId, |
| 581 | cause: detail, | 584 | cause: detail, |
| ... | @@ -617,7 +620,7 @@ export const layerWithOptions = ( | ... | @@ -617,7 +620,7 @@ export const layerWithOptions = ( |
| 617 | fiber === null ? Effect.void : Fiber.interrupt(fiber).pipe(Effect.ignore); | 620 | fiber === null ? Effect.void : Fiber.interrupt(fiber).pipe(Effect.ignore); |
| 618 | 621 | ||
| 619 | const writeProviderSessionEvents = (input: { | 622 | const writeProviderSessionEvents = (input: { |
| 620 | readonly runtime: ProviderAdapterV2SessionRuntime; | 623 | readonly runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 621 | readonly threadIds: Iterable<ThreadId>; | 624 | readonly threadIds: Iterable<ThreadId>; |
| 622 | readonly type: "provider-session.attached" | "provider-session.updated"; | 625 | readonly type: "provider-session.attached" | "provider-session.updated"; |
| 623 | readonly payload: OrchestrationV2ProviderSession; | 626 | readonly payload: OrchestrationV2ProviderSession; |
| ... | @@ -1226,7 +1229,7 @@ export const layerWithOptions = ( | ... | @@ -1226,7 +1229,7 @@ export const layerWithOptions = ( |
| 1226 | const removeThreadAttachment = (input: { | 1229 | const removeThreadAttachment = (input: { |
| 1227 | readonly providerSessionId: ProviderSessionId; | 1230 | readonly providerSessionId: ProviderSessionId; |
| 1228 | readonly threadId: ThreadId; | 1231 | readonly threadId: ThreadId; |
| 1229 | readonly runtime: ProviderAdapterV2SessionRuntime; | 1232 | readonly runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 1230 | }) => | 1233 | }) => |
| 1231 | Ref.update(sessions, (current) => { | 1234 | Ref.update(sessions, (current) => { |
| 1232 | const key = sessionKey(input.providerSessionId); | 1235 | const key = sessionKey(input.providerSessionId); |
| ... | @@ -1289,7 +1292,7 @@ export const layerWithOptions = ( | ... | @@ -1289,7 +1292,7 @@ export const layerWithOptions = ( |
| 1289 | readonly providerInstanceId: ProviderInstanceId; | 1292 | readonly providerInstanceId: ProviderInstanceId; |
| 1290 | }) => | 1293 | }) => |
| 1291 | Effect.suspend(() => { | 1294 | Effect.suspend(() => { |
| 1292 | let attachedTo: ProviderAdapterV2SessionRuntime | undefined; | 1295 | let attachedTo: ProviderAdapter.ProviderAdapterV2SessionRuntime | undefined; |
| 1293 | let preparedForCleanup: PreparedMcpCredential | undefined; | 1296 | let preparedForCleanup: PreparedMcpCredential | undefined; |
| 1294 | let reservationDropped = false; | 1297 | let reservationDropped = false; |
| 1295 | const dropReservation = () => { | 1298 | const dropReservation = () => { |
| ... | @@ -1631,7 +1634,7 @@ export const layerWithOptions = ( | ... | @@ -1631,7 +1634,7 @@ export const layerWithOptions = ( |
| 1631 | subscribers: Ref.Ref< | 1634 | subscribers: Ref.Ref< |
| 1632 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> | 1635 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> |
| 1633 | >, | 1636 | >, |
| 1634 | ): Effect.Effect<ProviderAdapterV2EventSubscription> => | 1637 | ): Effect.Effect<ProviderAdapter.ProviderAdapterV2EventSubscription> => |
| 1635 | Effect.gen(function* () { | 1638 | Effect.gen(function* () { |
| 1636 | const queue = yield* Queue.unbounded<ProviderSessionEventSignal, Cause.Done>(); | 1639 | const queue = yield* Queue.unbounded<ProviderSessionEventSignal, Cause.Done>(); |
| 1637 | const subscriberId = yield* Ref.getAndUpdate(nextSubscriberId, (value) => value + 1); | 1640 | const subscriberId = yield* Ref.getAndUpdate(nextSubscriberId, (value) => value + 1); |
| ... | @@ -1662,15 +1665,15 @@ export const layerWithOptions = ( | ... | @@ -1662,15 +1665,15 @@ export const layerWithOptions = ( |
| 1662 | ), | 1665 | ), |
| 1663 | Stream.ensuring(close), | 1666 | Stream.ensuring(close), |
| 1664 | ); | 1667 | ); |
| 1665 | return { events, close } satisfies ProviderAdapterV2EventSubscription; | 1668 | return { events, close } satisfies ProviderAdapter.ProviderAdapterV2EventSubscription; |
| 1666 | }); | 1669 | }); |
| 1667 | 1670 | ||
| 1668 | const decorateRuntime = ( | 1671 | const decorateRuntime = ( |
| 1669 | runtime: ProviderAdapterV2SessionRuntime, | 1672 | runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1670 | eventSubscribers: Ref.Ref< | 1673 | eventSubscribers: Ref.Ref< |
| 1671 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> | 1674 | ReadonlyMap<number, Queue.Queue<ProviderSessionEventSignal, Cause.Done>> |
| 1672 | >, | 1675 | >, |
| 1673 | ): ProviderAdapterV2SessionRuntime => { | 1676 | ): ProviderAdapter.ProviderAdapterV2SessionRuntime => { |
| 1674 | const providerSessionId = runtime.providerSessionId; | 1677 | const providerSessionId = runtime.providerSessionId; |
| 1675 | const subscribeEvents = makeEventSubscription(eventSubscribers); | 1678 | const subscribeEvents = makeEventSubscription(eventSubscribers); |
| 1676 | // Every provider's turn operations pass through here, so this is where they are | 1679 | // Every provider's turn operations pass through here, so this is where they are |
| ... | @@ -1852,7 +1855,10 @@ export const layerWithOptions = ( | ... | @@ -1852,7 +1855,10 @@ export const layerWithOptions = ( |
| 1852 | 1855 | ||
| 1853 | const persistProviderSessionUpdate = ( | 1856 | const persistProviderSessionUpdate = ( |
| 1854 | entry: LiveSessionEntry, | 1857 | entry: LiveSessionEntry, |
| 1855 | event: Extract<ProviderAdapterV2Event, { readonly type: "provider_session.updated" }>, | 1858 | event: Extract< |
| 1859 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 1860 | { readonly type: "provider_session.updated" } | ||
| 1861 | >, | ||
| 1856 | ) => | 1862 | ) => |
| 1857 | Effect.gen(function* () { | 1863 | Effect.gen(function* () { |
| 1858 | const current = (yield* Ref.get(sessions)).get( | 1864 | const current = (yield* Ref.get(sessions)).get( |
| ... | @@ -1925,7 +1931,7 @@ export const layerWithOptions = ( | ... | @@ -1925,7 +1931,7 @@ export const layerWithOptions = ( |
| 1925 | .pipe( | 1931 | .pipe( |
| 1926 | Effect.mapError( | 1932 | Effect.mapError( |
| 1927 | (cause) => | 1933 | (cause) => |
| 1928 | new ProviderAdapterEventStreamError({ | 1934 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 1929 | driver: entry.runtime.driver, | 1935 | driver: entry.runtime.driver, |
| 1930 | providerSessionId: entry.runtime.providerSessionId, | 1936 | providerSessionId: entry.runtime.providerSessionId, |
| 1931 | cause, | 1937 | cause, |
| ... | @@ -1962,7 +1968,7 @@ export const layerWithOptions = ( | ... | @@ -1962,7 +1968,7 @@ export const layerWithOptions = ( |
| 1962 | const cause = Exit.isFailure(exit) | 1968 | const cause = Exit.isFailure(exit) |
| 1963 | ? exit.cause | 1969 | ? exit.cause |
| 1964 | : Cause.fail( | 1970 | : Cause.fail( |
| 1965 | new ProviderAdapterEventStreamError({ | 1971 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 1966 | driver: entry.runtime.driver, | 1972 | driver: entry.runtime.driver, |
| 1967 | providerSessionId: entry.runtime.providerSessionId, | 1973 | providerSessionId: entry.runtime.providerSessionId, |
| 1968 | cause: "Provider event stream ended unexpectedly.", | 1974 | cause: "Provider event stream ended unexpectedly.", |
| ... | @@ -2212,7 +2218,7 @@ export const layerWithOptions = ( | ... | @@ -2212,7 +2218,7 @@ export const layerWithOptions = ( |
| 2212 | Effect.gen(function* () { | 2218 | Effect.gen(function* () { |
| 2213 | const entry = (yield* Ref.get(sessions)).get(sessionKey(providerSessionId)); | 2219 | const entry = (yield* Ref.get(sessions)).get(sessionKey(providerSessionId)); |
| 2214 | if (entry === undefined) { | 2220 | if (entry === undefined) { |
| 2215 | return Option.none<ProviderAdapterV2SessionRuntime>(); | 2221 | return Option.none<ProviderAdapter.ProviderAdapterV2SessionRuntime>(); |
| 2216 | } | 2222 | } |
| 2217 | yield* touchActivity(providerSessionId); | 2223 | yield* touchActivity(providerSessionId); |
| 2218 | return Option.some(entry.exposedRuntime); | 2224 | return Option.some(entry.exposedRuntime); |
apps/server/src/orchestration-v2/ProviderSwitchService.test.ts+5-3| ... | @@ -12,10 +12,10 @@ import * as Effect from "effect/Effect"; | ... | @@ -12,10 +12,10 @@ import * as Effect from "effect/Effect"; |
| 12 | import * as Layer from "effect/Layer"; | 12 | import * as Layer from "effect/Layer"; |
| 13 | 13 | ||
| 14 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 14 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 15 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 16 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 15 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 17 | import { acpSelectionTransition } from "@t3tools/provider-core/server/selectionTransition"; | 16 | import { acpSelectionTransition } from "@t3tools/provider-core/server/selectionTransition"; |
| 18 | import * as ProviderSwitch from "./ProviderSwitchService.ts"; | 17 | import * as ProviderSwitch from "./ProviderSwitchService.ts"; |
| 18 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 19 | 19 | ||
| 20 | const driver = ProviderDriverKind.make("codex"); | 20 | const driver = ProviderDriverKind.make("codex"); |
| 21 | const currentInstanceId = ProviderInstanceId.make("codex_primary"); | 21 | const currentInstanceId = ProviderInstanceId.make("codex_primary"); |
| ... | @@ -67,10 +67,12 @@ function deadSessionRecord( | ... | @@ -67,10 +67,12 @@ function deadSessionRecord( |
| 67 | 67 | ||
| 68 | function layerTest( | 68 | function layerTest( |
| 69 | metadata: Readonly<Record<string, { continuationKey: string }>>, | 69 | metadata: Readonly<Record<string, { continuationKey: string }>>, |
| 70 | planSelectionTransition: ProviderAdapterV2Shape["planSelectionTransition"] = () => | 70 | planSelectionTransition: ProviderAdapter.ProviderAdapterV2["Service"]["planSelectionTransition"] = () => |
| 71 | Effect.succeed({ type: "restart_session" }), | 71 | Effect.succeed({ type: "restart_session" }), |
| 72 | ) { | 72 | ) { |
| 73 | const adapter = (instanceId: ProviderInstanceId): ProviderAdapterV2Shape => ({ | 73 | const adapter = ( |
| 74 | instanceId: ProviderInstanceId, | ||
| 75 | ): ProviderAdapter.ProviderAdapterV2["Service"] => ({ | ||
| 74 | instanceId, | 76 | instanceId, |
| 75 | driver, | 77 | driver, |
| 76 | getCapabilities: () => Effect.succeed(capabilitiesWithoutModelSwitch), | 78 | getCapabilities: () => Effect.succeed(capabilitiesWithoutModelSwitch), |
apps/server/src/orchestration-v2/ProviderTurnControlService.test.ts+2-2| ... | @@ -24,7 +24,7 @@ import * as Stream from "effect/Stream"; | ... | @@ -24,7 +24,7 @@ import * as Stream from "effect/Stream"; |
| 24 | 24 | ||
| 25 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 25 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 26 | import * as ProjectionStore from "./ProjectionStore.ts"; | 26 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 27 | import type { ProviderAdapterV2SessionRuntime } from "@t3tools/provider-core/server/ProviderAdapter"; | 27 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 28 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 28 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 29 | import * as ProviderTurnControlService from "./ProviderTurnControlService.ts"; | 29 | import * as ProviderTurnControlService from "./ProviderTurnControlService.ts"; |
| 30 | 30 | ||
| ... | @@ -177,7 +177,7 @@ it.effect( | ... | @@ -177,7 +177,7 @@ it.effect( |
| 177 | updatedAt: now, | 177 | updatedAt: now, |
| 178 | lastError: null, | 178 | lastError: null, |
| 179 | }; | 179 | }; |
| 180 | const runtime: ProviderAdapterV2SessionRuntime = { | 180 | const runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime = { |
| 181 | instanceId: providerInstanceId, | 181 | instanceId: providerInstanceId, |
| 182 | driver, | 182 | driver, |
| 183 | providerSessionId: oldSessionId, | 183 | providerSessionId: oldSessionId, |
apps/server/src/orchestration-v2/ProviderTurnStartService.test.ts+3-3| ... | @@ -32,7 +32,7 @@ import * as EventSink from "./EventSink.ts"; | ... | @@ -32,7 +32,7 @@ import * as EventSink from "./EventSink.ts"; |
| 32 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 32 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 33 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 33 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 34 | import * as ProjectionStore from "./ProjectionStore.ts"; | 34 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 35 | import { ProviderAdapterEventStreamError } from "@t3tools/provider-core/server/ProviderAdapter"; | 35 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 36 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 36 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 37 | import * as ProviderTurnStart from "./ProviderTurnStartService.ts"; | 37 | import * as ProviderTurnStart from "./ProviderTurnStartService.ts"; |
| 38 | import * as RunExecutionService from "./RunExecutionService.ts"; | 38 | import * as RunExecutionService from "./RunExecutionService.ts"; |
| ... | @@ -372,7 +372,7 @@ function makeLocalCommandHarness(input: { | ... | @@ -372,7 +372,7 @@ function makeLocalCommandHarness(input: { |
| 372 | }).pipe( | 372 | }).pipe( |
| 373 | Effect.andThen( | 373 | Effect.andThen( |
| 374 | Effect.fail( | 374 | Effect.fail( |
| 375 | new ProviderAdapterEventStreamError({ | 375 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 376 | driver: providerThread.driver, | 376 | driver: providerThread.driver, |
| 377 | providerSessionId, | 377 | providerSessionId, |
| 378 | cause: input.ensureThreadFailure, | 378 | cause: input.ensureThreadFailure, |
| ... | @@ -385,7 +385,7 @@ function makeLocalCommandHarness(input: { | ... | @@ -385,7 +385,7 @@ function makeLocalCommandHarness(input: { |
| 385 | driver: providerThread.driver, | 385 | driver: providerThread.driver, |
| 386 | resumeThread: () => | 386 | resumeThread: () => |
| 387 | Effect.fail( | 387 | Effect.fail( |
| 388 | new ProviderAdapterEventStreamError({ | 388 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 389 | driver: providerThread.driver, | 389 | driver: providerThread.driver, |
| 390 | providerSessionId, | 390 | providerSessionId, |
| 391 | cause: "native thread is gone", | 391 | cause: "native thread is gone", |
apps/server/src/orchestration-v2/ProviderTurnStartService.ts+9-14| ... | @@ -37,12 +37,7 @@ import { | ... | @@ -37,12 +37,7 @@ import { |
| 37 | latestNativeContextUsage, | 37 | latestNativeContextUsage, |
| 38 | } from "@t3tools/provider-core/server/handoffBudget"; | 38 | } from "@t3tools/provider-core/server/handoffBudget"; |
| 39 | import { deliverContextHandoffs } from "./ContextHandoffDelivery.ts"; | 39 | import { deliverContextHandoffs } from "./ContextHandoffDelivery.ts"; |
| 40 | import { | 40 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 41 | ProviderAdapterTurnStartError, | ||
| 42 | type ProviderAdapterV2Error, | ||
| 43 | type ProviderAdapterV2HistoricalContext, | ||
| 44 | type ProviderAdapterV2SessionRuntime, | ||
| 45 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 46 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 41 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 47 | import * as ProjectionStore from "./ProjectionStore.ts"; | 42 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 48 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 43 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| ... | @@ -184,15 +179,15 @@ export const layer: Layer.Layer< | ... | @@ -184,15 +179,15 @@ export const layer: Layer.Layer< |
| 184 | }; | 179 | }; |
| 185 | 180 | ||
| 186 | const makeDeliverySession = ( | 181 | const makeDeliverySession = ( |
| 187 | session: ProviderAdapterV2SessionRuntime, | 182 | session: ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 188 | startWithHandoffs: ( | 183 | startWithHandoffs: ( |
| 189 | input: Parameters<ProviderAdapterV2SessionRuntime["startTurn"]>[0], | 184 | input: Parameters<ProviderAdapter.ProviderAdapterV2SessionRuntime["startTurn"]>[0], |
| 190 | compact?: boolean, | 185 | compact?: boolean, |
| 191 | ) => ReturnType<ProviderAdapterV2SessionRuntime["startTurn"]>, | 186 | ) => ReturnType<ProviderAdapter.ProviderAdapterV2SessionRuntime["startTurn"]>, |
| 192 | ) => { | 187 | ) => { |
| 193 | let deliver: typeof startWithHandoffs | undefined = startWithHandoffs; | 188 | let deliver: typeof startWithHandoffs | undefined = startWithHandoffs; |
| 194 | const start = ( | 189 | const start = ( |
| 195 | input: Parameters<ProviderAdapterV2SessionRuntime["startTurn"]>[0], | 190 | input: Parameters<ProviderAdapter.ProviderAdapterV2SessionRuntime["startTurn"]>[0], |
| 196 | compact = false, | 191 | compact = false, |
| 197 | ) => | 192 | ) => |
| 198 | Effect.suspend(() => { | 193 | Effect.suspend(() => { |
| ... | @@ -595,7 +590,7 @@ export const layer: Layer.Layer< | ... | @@ -595,7 +590,7 @@ export const layer: Layer.Layer< |
| 595 | // Only the provider's own thread load fails the run on the last attempt; | 590 | // Only the provider's own thread load fails the run on the last attempt; |
| 596 | // store, id and handoff failures around it keep their typed errors. | 591 | // store, id and handoff failures around it keep their typed errors. |
| 597 | const loadFromProvider = ( | 592 | const loadFromProvider = ( |
| 598 | load: Effect.Effect<OrchestrationV2ProviderThread, ProviderAdapterV2Error>, | 593 | load: Effect.Effect<OrchestrationV2ProviderThread, ProviderAdapter.ProviderAdapterV2Error>, |
| 599 | ) => | 594 | ) => |
| 600 | Effect.gen(function* () { | 595 | Effect.gen(function* () { |
| 601 | const loaded = yield* Effect.result(load); | 596 | const loaded = yield* Effect.result(load); |
| ... | @@ -672,7 +667,7 @@ export const layer: Layer.Layer< | ... | @@ -672,7 +667,7 @@ export const layer: Layer.Layer< |
| 672 | const resumed = yield* Effect.result( | 667 | const resumed = yield* Effect.result( |
| 673 | uncertainDelivery | 668 | uncertainDelivery |
| 674 | ? Effect.fail( | 669 | ? Effect.fail( |
| 675 | new ProviderAdapterTurnStartError({ | 670 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 676 | driver: session.driver, | 671 | driver: session.driver, |
| 677 | threadId: projection.thread.id, | 672 | threadId: projection.thread.id, |
| 678 | providerThreadId: providerThread.id, | 673 | providerThreadId: providerThread.id, |
| ... | @@ -1143,7 +1138,7 @@ export const layer: Layer.Layer< | ... | @@ -1143,7 +1138,7 @@ export const layer: Layer.Layer< |
| 1143 | ...(session.injectHistory === undefined | 1138 | ...(session.injectHistory === undefined |
| 1144 | ? {} | 1139 | ? {} |
| 1145 | : { | 1140 | : { |
| 1146 | inject: (history: ProviderAdapterV2HistoricalContext) => | 1141 | inject: (history: ProviderAdapter.ProviderAdapterV2HistoricalContext) => |
| 1147 | session.injectHistory!({ | 1142 | session.injectHistory!({ |
| 1148 | providerThread: runningProviderThread, | 1143 | providerThread: runningProviderThread, |
| 1149 | ...history, | 1144 | ...history, |
| ... | @@ -1211,7 +1206,7 @@ export const layer: Layer.Layer< | ... | @@ -1211,7 +1206,7 @@ export const layer: Layer.Layer< |
| 1211 | Effect.mapError((cause) => | 1206 | Effect.mapError((cause) => |
| 1212 | cause._tag === "ProviderAdapterTurnStartError" | 1207 | cause._tag === "ProviderAdapterTurnStartError" |
| 1213 | ? cause | 1208 | ? cause |
| 1214 | : new ProviderAdapterTurnStartError({ | 1209 | : new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 1215 | driver: session.driver, | 1210 | driver: session.driver, |
| 1216 | threadId: projection.thread.id, | 1211 | threadId: projection.thread.id, |
| 1217 | providerThreadId: providerThread.id, | 1212 | providerThreadId: providerThread.id, |
apps/server/src/orchestration-v2/RunExecutionService.test.ts+71-72| ... | @@ -43,14 +43,7 @@ import * as CheckpointService from "./CheckpointService.ts"; | ... | @@ -43,14 +43,7 @@ import * as CheckpointService from "./CheckpointService.ts"; |
| 43 | import type { PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; | 43 | import type { PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; |
| 44 | import * as EventSink from "./EventSink.ts"; | 44 | import * as EventSink from "./EventSink.ts"; |
| 45 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 45 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 46 | import { | 46 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 47 | ProviderAdapterEventStreamError, | ||
| 48 | ProviderAdapterTurnStartError, | ||
| 49 | type ProviderAdapterV2Error, | ||
| 50 | type ProviderAdapterV2Event, | ||
| 51 | type ProviderAdapterV2SessionRuntime, | ||
| 52 | type ProviderAdapterV2TurnInput, | ||
| 53 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 54 | import * as ProjectionStore from "./ProjectionStore.ts"; | 47 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 55 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; | 48 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; |
| 56 | import * as McpAppModelContext from "../mcpApps/McpAppModelContext.ts"; | 49 | import * as McpAppModelContext from "../mcpApps/McpAppModelContext.ts"; |
| ... | @@ -95,7 +88,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => | ... | @@ -95,7 +88,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => |
| 95 | providerThreadId: ProviderThreadId.make("provider-thread:shared-runtime:second"), | 88 | providerThreadId: ProviderThreadId.make("provider-thread:shared-runtime:second"), |
| 96 | }; | 89 | }; |
| 97 | const firstTurnId = ProviderTurnId.make("provider-turn:shared-runtime:first"); | 90 | const firstTurnId = ProviderTurnId.make("provider-turn:shared-runtime:first"); |
| 98 | const turnEvent: ProviderAdapterV2Event = { | 91 | const turnEvent: ProviderAdapter.ProviderAdapterV2Event = { |
| 99 | type: "provider_turn.updated", | 92 | type: "provider_turn.updated", |
| 100 | driver, | 93 | driver, |
| 101 | threadId: first.threadId, | 94 | threadId: first.threadId, |
| ... | @@ -111,7 +104,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => | ... | @@ -111,7 +104,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => |
| 111 | completedAt: null, | 104 | completedAt: null, |
| 112 | }, | 105 | }, |
| 113 | }; | 106 | }; |
| 114 | const messageEvent: ProviderAdapterV2Event = { | 107 | const messageEvent: ProviderAdapter.ProviderAdapterV2Event = { |
| 115 | type: "message.updated", | 108 | type: "message.updated", |
| 116 | driver, | 109 | driver, |
| 117 | message: { | 110 | message: { |
| ... | @@ -129,7 +122,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => | ... | @@ -129,7 +122,7 @@ it.effect("routes shared-runtime events only to their owning root run", () => |
| 129 | updatedAt: now, | 122 | updatedAt: now, |
| 130 | }, | 123 | }, |
| 131 | }; | 124 | }; |
| 132 | const terminalEvent: ProviderAdapterV2Event = { | 125 | const terminalEvent: ProviderAdapter.ProviderAdapterV2Event = { |
| 133 | type: "turn.terminal", | 126 | type: "turn.terminal", |
| 134 | driver, | 127 | driver, |
| 135 | providerThreadId: first.providerThreadId, | 128 | providerThreadId: first.providerThreadId, |
| ... | @@ -181,7 +174,7 @@ it("leaves a child thread created after the root turn ended to the run that is l | ... | @@ -181,7 +174,7 @@ it("leaves a child thread created after the root turn ended to the run that is l |
| 181 | attemptId: RunAttemptId.make("attempt:late-child"), | 174 | attemptId: RunAttemptId.make("attempt:late-child"), |
| 182 | providerThreadId: ProviderThreadId.make("provider-thread:late-child"), | 175 | providerThreadId: ProviderThreadId.make("provider-thread:late-child"), |
| 183 | }; | 176 | }; |
| 184 | const childCreated = (childThreadId: ThreadId): ProviderAdapterV2Event => | 177 | const childCreated = (childThreadId: ThreadId): ProviderAdapter.ProviderAdapterV2Event => |
| 185 | ({ | 178 | ({ |
| 186 | type: "app_thread.created", | 179 | type: "app_thread.created", |
| 187 | driver, | 180 | driver, |
| ... | @@ -193,7 +186,7 @@ it("leaves a child thread created after the root turn ended to the run that is l | ... | @@ -193,7 +186,7 @@ it("leaves a child thread created after the root turn ended to the run that is l |
| 193 | rootThreadId: threadId, | 186 | rootThreadId: threadId, |
| 194 | }, | 187 | }, |
| 195 | }, | 188 | }, |
| 196 | }) as ProviderAdapterV2Event; | 189 | }) as ProviderAdapter.ProviderAdapterV2Event; |
| 197 | const earlyChild = ThreadId.make("thread:late-child:early"); | 190 | const earlyChild = ThreadId.make("thread:late-child:early"); |
| 198 | const lateChild = ThreadId.make("thread:late-child:late"); | 191 | const lateChild = ThreadId.make("thread:late-child:late"); |
| 199 | 192 | ||
| ... | @@ -246,7 +239,7 @@ it("does not route a superseded attempt through a reused provider thread", () => | ... | @@ -246,7 +239,7 @@ it("does not route a superseded attempt through a reused provider thread", () => |
| 246 | ...oldAttempt, | 239 | ...oldAttempt, |
| 247 | attemptId: RunAttemptId.make("attempt:shared-runtime:restart:new"), | 240 | attemptId: RunAttemptId.make("attempt:shared-runtime:restart:new"), |
| 248 | }; | 241 | }; |
| 249 | const oldTurnEvent: ProviderAdapterV2Event = { | 242 | const oldTurnEvent: ProviderAdapter.ProviderAdapterV2Event = { |
| 250 | type: "provider_turn.updated", | 243 | type: "provider_turn.updated", |
| 251 | driver, | 244 | driver, |
| 252 | threadId, | 245 | threadId, |
| ... | @@ -299,33 +292,33 @@ it("routes only exact same-thread background items inherited from settled runs", | ... | @@ -299,33 +292,33 @@ it("routes only exact same-thread background items inherited from settled runs", |
| 299 | type: "subagent", | 292 | type: "subagent", |
| 300 | status: "running", | 293 | status: "running", |
| 301 | }, | 294 | }, |
| 302 | } as Extract<ProviderAdapterV2Event, { type: "turn_item.updated" }>; | 295 | } as Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "turn_item.updated" }>; |
| 303 | const unrelatedRunItem = { | 296 | const unrelatedRunItem = { |
| 304 | ...inheritedRunning, | 297 | ...inheritedRunning, |
| 305 | turnItem: { | 298 | turnItem: { |
| 306 | ...inheritedRunning.turnItem, | 299 | ...inheritedRunning.turnItem, |
| 307 | runId: RunId.make("run:inherited-background-routing:unrelated"), | 300 | runId: RunId.make("run:inherited-background-routing:unrelated"), |
| 308 | }, | 301 | }, |
| 309 | } as ProviderAdapterV2Event; | 302 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 310 | const unlistedPriorItem = { | 303 | const unlistedPriorItem = { |
| 311 | ...inheritedRunning, | 304 | ...inheritedRunning, |
| 312 | turnItem: { | 305 | turnItem: { |
| 313 | ...inheritedRunning.turnItem, | 306 | ...inheritedRunning.turnItem, |
| 314 | id: TurnItemId.make("turn-item:inherited-background-routing:unrelated"), | 307 | id: TurnItemId.make("turn-item:inherited-background-routing:unrelated"), |
| 315 | }, | 308 | }, |
| 316 | } as ProviderAdapterV2Event; | 309 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 317 | const unrelatedThreadItem = { | 310 | const unrelatedThreadItem = { |
| 318 | ...inheritedRunning, | 311 | ...inheritedRunning, |
| 319 | turnItem: { ...inheritedRunning.turnItem, threadId: otherThreadId }, | 312 | turnItem: { ...inheritedRunning.turnItem, threadId: otherThreadId }, |
| 320 | } as ProviderAdapterV2Event; | 313 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 321 | const ordinaryItem = { | 314 | const ordinaryItem = { |
| 322 | ...inheritedRunning, | 315 | ...inheritedRunning, |
| 323 | turnItem: { ...inheritedRunning.turnItem, type: "reasoning" as const }, | 316 | turnItem: { ...inheritedRunning.turnItem, type: "reasoning" as const }, |
| 324 | } as ProviderAdapterV2Event; | 317 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 325 | const inheritedTerminal = { | 318 | const inheritedTerminal = { |
| 326 | ...inheritedRunning, | 319 | ...inheritedRunning, |
| 327 | turnItem: { ...inheritedRunning.turnItem, status: "completed" as const }, | 320 | turnItem: { ...inheritedRunning.turnItem, status: "completed" as const }, |
| 328 | } as ProviderAdapterV2Event; | 321 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 329 | 322 | ||
| 330 | const [runningAccepted, afterRunning] = RunExecutionService.routeProviderEvent( | 323 | const [runningAccepted, afterRunning] = RunExecutionService.routeProviderEvent( |
| 331 | inheritedRunning, | 324 | inheritedRunning, |
| ... | @@ -515,7 +508,7 @@ it("does not carry interrupted or still-running child ownership into later attem | ... | @@ -515,7 +508,7 @@ it("does not carry interrupted or still-running child ownership into later attem |
| 515 | startedAt: null, | 508 | startedAt: null, |
| 516 | completedAt: null, | 509 | completedAt: null, |
| 517 | }, | 510 | }, |
| 518 | } satisfies ProviderAdapterV2Event; | 511 | } satisfies ProviderAdapter.ProviderAdapterV2Event; |
| 519 | 512 | ||
| 520 | assert.isFalse(RunExecutionService.routeProviderEvent(lateChildNode, identity, state)[0]); | 513 | assert.isFalse(RunExecutionService.routeProviderEvent(lateChildNode, identity, state)[0]); |
| 521 | }); | 514 | }); |
| ... | @@ -550,7 +543,7 @@ it.effect("rechecks run ownership immediately before calling the provider", () = | ... | @@ -550,7 +543,7 @@ it.effect("rechecks run ownership immediately before calling the provider", () = |
| 550 | const session = { | 543 | const session = { |
| 551 | events: Stream.never, | 544 | events: Stream.never, |
| 552 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), | 545 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), |
| 553 | } as unknown as ProviderAdapterV2SessionRuntime; | 546 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 554 | 547 | ||
| 555 | yield* runExecution.startRootRun({ | 548 | yield* runExecution.startRootRun({ |
| 556 | commandId: CommandId.make("command:run-execution-start-guard"), | 549 | commandId: CommandId.make("command:run-execution-start-guard"), |
| ... | @@ -597,14 +590,15 @@ it.effect("rechecks run ownership immediately before calling the provider", () = | ... | @@ -597,14 +590,15 @@ it.effect("rechecks run ownership immediately before calling the provider", () = |
| 597 | it.effect("passes the thread's MCP app context to the provider under a safe key", () => | 590 | it.effect("passes the thread's MCP app context to the provider under a safe key", () => |
| 598 | Effect.gen(function* () { | 591 | Effect.gen(function* () { |
| 599 | const runExecution = yield* RunExecutionService.RunExecutionServiceV2; | 592 | const runExecution = yield* RunExecutionService.RunExecutionServiceV2; |
| 600 | const started = yield* Deferred.make<ProviderAdapterV2TurnInput>(); | 593 | const started = yield* Deferred.make<ProviderAdapter.ProviderAdapterV2TurnInput>(); |
| 601 | const threadId = ThreadId.make("thread:run-execution-app-context"); | 594 | const threadId = ThreadId.make("thread:run-execution-app-context"); |
| 602 | const providerInstanceId = ProviderInstanceId.make("codex"); | 595 | const providerInstanceId = ProviderInstanceId.make("codex"); |
| 603 | const attemptId = RunAttemptId.make("attempt:run-execution-app-context"); | 596 | const attemptId = RunAttemptId.make("attempt:run-execution-app-context"); |
| 604 | const session = { | 597 | const session = { |
| 605 | events: Stream.never, | 598 | events: Stream.never, |
| 606 | startTurn: (input: ProviderAdapterV2TurnInput) => Deferred.succeed(started, input), | 599 | startTurn: (input: ProviderAdapter.ProviderAdapterV2TurnInput) => |
| 607 | } as unknown as ProviderAdapterV2SessionRuntime; | 600 | Deferred.succeed(started, input), |
| 601 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime; | ||
| 608 | 602 | ||
| 609 | yield* runExecution.startRootRun({ | 603 | yield* runExecution.startRootRun({ |
| 610 | commandId: CommandId.make("command:run-execution-app-context"), | 604 | commandId: CommandId.make("command:run-execution-app-context"), |
| ... | @@ -716,7 +710,7 @@ it.effect("fails the run when its ownership check cannot be read before calling | ... | @@ -716,7 +710,7 @@ it.effect("fails the run when its ownership check cannot be read before calling |
| 716 | session: { | 710 | session: { |
| 717 | events: Stream.never, | 711 | events: Stream.never, |
| 718 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), | 712 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), |
| 719 | } as unknown as ProviderAdapterV2SessionRuntime, | 713 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 720 | run: { id: runId, threadId, ordinal: 1, providerInstanceId } as OrchestrationV2Run, | 714 | run: { id: runId, threadId, ordinal: 1, providerInstanceId } as OrchestrationV2Run, |
| 721 | rootNode: { | 715 | rootNode: { |
| 722 | id: NodeId.make("node:run-execution-start-guard-read"), | 716 | id: NodeId.make("node:run-execution-start-guard-read"), |
| ... | @@ -821,7 +815,7 @@ it.effect( | ... | @@ -821,7 +815,7 @@ it.effect( |
| 821 | Effect.sync(() => { | 815 | Effect.sync(() => { |
| 822 | calls.push("compact"); | 816 | calls.push("compact"); |
| 823 | }), | 817 | }), |
| 824 | } as unknown as ProviderAdapterV2SessionRuntime, | 818 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 825 | run: { | 819 | run: { |
| 826 | id: RunId.make(`run:compact-routing:${index}`), | 820 | id: RunId.make(`run:compact-routing:${index}`), |
| 827 | threadId, | 821 | threadId, |
| ... | @@ -888,7 +882,7 @@ it.effect("refreshes MCP credential liveness before calling the provider", () => | ... | @@ -888,7 +882,7 @@ it.effect("refreshes MCP credential liveness before calling the provider", () => |
| 888 | session: { | 882 | session: { |
| 889 | events: Stream.never, | 883 | events: Stream.never, |
| 890 | startTurn: () => Ref.update(order, (entries) => [...entries, "start-turn"]), | 884 | startTurn: () => Ref.update(order, (entries) => [...entries, "start-turn"]), |
| 891 | } as unknown as ProviderAdapterV2SessionRuntime, | 885 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 892 | run: { | 886 | run: { |
| 893 | id: RunId.make("run:run-execution-mcp-liveness"), | 887 | id: RunId.make("run:run-execution-mcp-liveness"), |
| 894 | threadId, | 888 | threadId, |
| ... | @@ -1000,7 +994,7 @@ it.effect("starts the provider when checkpoint baseline capture fails", () => | ... | @@ -1000,7 +994,7 @@ it.effect("starts the provider when checkpoint baseline capture fails", () => |
| 1000 | session: { | 994 | session: { |
| 1001 | events: Stream.never, | 995 | events: Stream.never, |
| 1002 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), | 996 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), |
| 1003 | } as unknown as ProviderAdapterV2SessionRuntime, | 997 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1004 | run: { | 998 | run: { |
| 1005 | id: runId, | 999 | id: runId, |
| 1006 | threadId, | 1000 | threadId, |
| ... | @@ -1137,7 +1131,7 @@ it.effect.each(["failure", "interruption", "stale-attempt", "start-guard"] as co | ... | @@ -1137,7 +1131,7 @@ it.effect.each(["failure", "interruption", "stale-attempt", "start-guard"] as co |
| 1137 | session: { | 1131 | session: { |
| 1138 | events: Stream.never, | 1132 | events: Stream.never, |
| 1139 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), | 1133 | startTurn: () => Ref.update(providerStarts, (count) => count + 1), |
| 1140 | } as unknown as ProviderAdapterV2SessionRuntime, | 1134 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1141 | run: { | 1135 | run: { |
| 1142 | id: runId, | 1136 | id: runId, |
| 1143 | threadId, | 1137 | threadId, |
| ... | @@ -1288,7 +1282,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1288,7 +1282,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1288 | ), | 1282 | ), |
| 1289 | ), | 1283 | ), |
| 1290 | ); | 1284 | ); |
| 1291 | const events: ReadonlyArray<ProviderAdapterV2Event> = [ | 1285 | const events: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event> = [ |
| 1292 | { | 1286 | { |
| 1293 | type: "app_thread.created", | 1287 | type: "app_thread.created", |
| 1294 | driver, | 1288 | driver, |
| ... | @@ -1300,7 +1294,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1300,7 +1294,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1300 | rootThreadId: threadId, | 1294 | rootThreadId: threadId, |
| 1301 | }, | 1295 | }, |
| 1302 | }, | 1296 | }, |
| 1303 | } as ProviderAdapterV2Event, | 1297 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1304 | { | 1298 | { |
| 1305 | type: "provider_thread.updated", | 1299 | type: "provider_thread.updated", |
| 1306 | driver, | 1300 | driver, |
| ... | @@ -1308,7 +1302,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1308,7 +1302,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1308 | id: childProviderThreadId, | 1302 | id: childProviderThreadId, |
| 1309 | appThreadId: childThreadId, | 1303 | appThreadId: childThreadId, |
| 1310 | }, | 1304 | }, |
| 1311 | } as ProviderAdapterV2Event, | 1305 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1312 | { | 1306 | { |
| 1313 | type: "subagent.updated", | 1307 | type: "subagent.updated", |
| 1314 | driver, | 1308 | driver, |
| ... | @@ -1318,7 +1312,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1318,7 +1312,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1318 | runId, | 1312 | runId, |
| 1319 | status: "running", | 1313 | status: "running", |
| 1320 | }, | 1314 | }, |
| 1321 | } as ProviderAdapterV2Event, | 1315 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1322 | { | 1316 | { |
| 1323 | type: "provider_turn.updated", | 1317 | type: "provider_turn.updated", |
| 1324 | driver, | 1318 | driver, |
| ... | @@ -1330,7 +1324,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1330,7 +1324,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1330 | runAttemptId: null, | 1324 | runAttemptId: null, |
| 1331 | status: "running", | 1325 | status: "running", |
| 1332 | }, | 1326 | }, |
| 1333 | } as ProviderAdapterV2Event, | 1327 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1334 | { | 1328 | { |
| 1335 | type: "turn.terminal", | 1329 | type: "turn.terminal", |
| 1336 | driver, | 1330 | driver, |
| ... | @@ -1353,7 +1347,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1353,7 +1347,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1353 | text: "Hello.", | 1347 | text: "Hello.", |
| 1354 | streaming: false, | 1348 | streaming: false, |
| 1355 | }, | 1349 | }, |
| 1356 | } as ProviderAdapterV2Event, | 1350 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1357 | { | 1351 | { |
| 1358 | type: "provider_turn.updated", | 1352 | type: "provider_turn.updated", |
| 1359 | driver, | 1353 | driver, |
| ... | @@ -1365,7 +1359,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1365,7 +1359,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1365 | runAttemptId: null, | 1359 | runAttemptId: null, |
| 1366 | status: "completed", | 1360 | status: "completed", |
| 1367 | }, | 1361 | }, |
| 1368 | } as ProviderAdapterV2Event, | 1362 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1369 | { | 1363 | { |
| 1370 | type: "subagent.updated", | 1364 | type: "subagent.updated", |
| 1371 | driver, | 1365 | driver, |
| ... | @@ -1375,7 +1369,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1375,7 +1369,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1375 | runId, | 1369 | runId, |
| 1376 | status: "completed", | 1370 | status: "completed", |
| 1377 | }, | 1371 | }, |
| 1378 | } as ProviderAdapterV2Event, | 1372 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1379 | ]; | 1373 | ]; |
| 1380 | 1374 | ||
| 1381 | yield* Effect.gen(function* () { | 1375 | yield* Effect.gen(function* () { |
| ... | @@ -1387,7 +1381,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", | ... | @@ -1387,7 +1381,7 @@ it.effect("keeps ingesting owned child events after the root turn terminalizes", |
| 1387 | session: { | 1381 | session: { |
| 1388 | events: Stream.fromIterable(events), | 1382 | events: Stream.fromIterable(events), |
| 1389 | startTurn: () => Effect.void, | 1383 | startTurn: () => Effect.void, |
| 1390 | } as unknown as ProviderAdapterV2SessionRuntime, | 1384 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1391 | run: { | 1385 | run: { |
| 1392 | id: runId, | 1386 | id: runId, |
| 1393 | threadId, | 1387 | threadId, |
| ... | @@ -1788,7 +1782,7 @@ it.effect( | ... | @@ -1788,7 +1782,7 @@ it.effect( |
| 1788 | ], | 1782 | ], |
| 1789 | updatedAt: now, | 1783 | updatedAt: now, |
| 1790 | }, | 1784 | }, |
| 1791 | } as ProviderAdapterV2Event, | 1785 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1792 | rootTerminalEvent(ids, "completed"), | 1786 | rootTerminalEvent(ids, "completed"), |
| 1793 | { | 1787 | { |
| 1794 | type: "provider_thread.updated", | 1788 | type: "provider_thread.updated", |
| ... | @@ -1799,12 +1793,12 @@ it.effect( | ... | @@ -1799,12 +1793,12 @@ it.effect( |
| 1799 | pendingBackgroundTasks: [], | 1793 | pendingBackgroundTasks: [], |
| 1800 | updatedAt: now, | 1794 | updatedAt: now, |
| 1801 | }, | 1795 | }, |
| 1802 | } as ProviderAdapterV2Event, | 1796 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 1803 | ]), | 1797 | ]), |
| 1804 | close: Deferred.succeed(ingestionDone, undefined), | 1798 | close: Deferred.succeed(ingestionDone, undefined), |
| 1805 | }), | 1799 | }), |
| 1806 | startTurn: () => Effect.void, | 1800 | startTurn: () => Effect.void, |
| 1807 | } as unknown as ProviderAdapterV2SessionRuntime, | 1801 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 1808 | run: { | 1802 | run: { |
| 1809 | id: ids.runId, | 1803 | id: ids.runId, |
| 1810 | threadId: ids.threadId, | 1804 | threadId: ids.threadId, |
| ... | @@ -2000,7 +1994,7 @@ it.effect("drops late root provider-thread writes from a superseded attempt", () | ... | @@ -2000,7 +1994,7 @@ it.effect("drops late root provider-thread writes from a superseded attempt", () |
| 2000 | ], | 1994 | ], |
| 2001 | updatedAt: now, | 1995 | updatedAt: now, |
| 2002 | }, | 1996 | }, |
| 2003 | } as ProviderAdapterV2Event, | 1997 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 2004 | rootTerminalEvent(ids, "completed"), | 1998 | rootTerminalEvent(ids, "completed"), |
| 2005 | // Late snapshot after a replacement attempt claimed the same | 1999 | // Late snapshot after a replacement attempt claimed the same |
| 2006 | // run ordinal. Without attempt gating this would clobber it. | 2000 | // run ordinal. Without attempt gating this would clobber it. |
| ... | @@ -2016,12 +2010,12 @@ it.effect("drops late root provider-thread writes from a superseded attempt", () | ... | @@ -2016,12 +2010,12 @@ it.effect("drops late root provider-thread writes from a superseded attempt", () |
| 2016 | ], | 2010 | ], |
| 2017 | updatedAt: now, | 2011 | updatedAt: now, |
| 2018 | }, | 2012 | }, |
| 2019 | } as ProviderAdapterV2Event, | 2013 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 2020 | ]), | 2014 | ]), |
| 2021 | close: Deferred.succeed(ingestionDone, undefined), | 2015 | close: Deferred.succeed(ingestionDone, undefined), |
| 2022 | }), | 2016 | }), |
| 2023 | startTurn: () => Effect.void, | 2017 | startTurn: () => Effect.void, |
| 2024 | } as unknown as ProviderAdapterV2SessionRuntime, | 2018 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 2025 | run: { | 2019 | run: { |
| 2026 | id: ids.runId, | 2020 | id: ids.runId, |
| 2027 | threadId: ids.threadId, | 2021 | threadId: ids.threadId, |
| ... | @@ -2197,7 +2191,7 @@ it.effect( | ... | @@ -2197,7 +2191,7 @@ it.effect( |
| 2197 | ], | 2191 | ], |
| 2198 | updatedAt: now, | 2192 | updatedAt: now, |
| 2199 | }, | 2193 | }, |
| 2200 | } as ProviderAdapterV2Event, | 2194 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 2201 | // Late completion still writable (turn_item writes are not | 2195 | // Late completion still writable (turn_item writes are not |
| 2202 | // ownership-gated); stream must stay open for it. | 2196 | // ownership-gated); stream must stay open for it. |
| 2203 | backgroundTurnItemEvent(ids, "command_execution", "completed", 2), | 2197 | backgroundTurnItemEvent(ids, "command_execution", "completed", 2), |
| ... | @@ -2205,7 +2199,7 @@ it.effect( | ... | @@ -2205,7 +2199,7 @@ it.effect( |
| 2205 | close: Deferred.succeed(ingestionDone, undefined), | 2199 | close: Deferred.succeed(ingestionDone, undefined), |
| 2206 | }), | 2200 | }), |
| 2207 | startTurn: () => Effect.void, | 2201 | startTurn: () => Effect.void, |
| 2208 | } as unknown as ProviderAdapterV2SessionRuntime, | 2202 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 2209 | run: { | 2203 | run: { |
| 2210 | id: ids.runId, | 2204 | id: ids.runId, |
| 2211 | threadId: ids.threadId, | 2205 | threadId: ids.threadId, |
| ... | @@ -2371,12 +2365,12 @@ it.effect( | ... | @@ -2371,12 +2365,12 @@ it.effect( |
| 2371 | ], | 2365 | ], |
| 2372 | updatedAt: now, | 2366 | updatedAt: now, |
| 2373 | }, | 2367 | }, |
| 2374 | } as ProviderAdapterV2Event, | 2368 | } as ProviderAdapter.ProviderAdapterV2Event, |
| 2375 | ]), | 2369 | ]), |
| 2376 | close: Deferred.succeed(ingestionDone, undefined), | 2370 | close: Deferred.succeed(ingestionDone, undefined), |
| 2377 | }), | 2371 | }), |
| 2378 | startTurn: () => Effect.void, | 2372 | startTurn: () => Effect.void, |
| 2379 | } as unknown as ProviderAdapterV2SessionRuntime, | 2373 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 2380 | run: { | 2374 | run: { |
| 2381 | id: ids.runId, | 2375 | id: ids.runId, |
| 2382 | threadId: ids.threadId, | 2376 | threadId: ids.threadId, |
| ... | @@ -2439,7 +2433,7 @@ it.effect( | ... | @@ -2439,7 +2433,7 @@ it.effect( |
| 2439 | ); | 2433 | ); |
| 2440 | const providerInstanceId = ProviderInstanceId.make("codex"); | 2434 | const providerInstanceId = ProviderInstanceId.make("codex"); |
| 2441 | const written = yield* Ref.make<ReadonlyArray<OrchestrationV2DomainEvent>>([]); | 2435 | const written = yield* Ref.make<ReadonlyArray<OrchestrationV2DomainEvent>>([]); |
| 2442 | const ingested = yield* Ref.make<ReadonlyArray<ProviderAdapterV2Event>>([]); | 2436 | const ingested = yield* Ref.make<ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>>([]); |
| 2443 | const ingestionDone = yield* Deferred.make<void>(); | 2437 | const ingestionDone = yield* Deferred.make<void>(); |
| 2444 | const layerTest = RunExecutionService.layer.pipe( | 2438 | const layerTest = RunExecutionService.layer.pipe( |
| 2445 | Layer.provide( | 2439 | Layer.provide( |
| ... | @@ -2609,11 +2603,11 @@ it.effect( | ... | @@ -2609,11 +2603,11 @@ it.effect( |
| 2609 | completedAt: runningChildNode.startedAt, | 2603 | completedAt: runningChildNode.startedAt, |
| 2610 | }, | 2604 | }, |
| 2611 | }, | 2605 | }, |
| 2612 | ] satisfies ReadonlyArray<ProviderAdapterV2Event>), | 2606 | ] satisfies ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>), |
| 2613 | close: Deferred.succeed(ingestionDone, undefined), | 2607 | close: Deferred.succeed(ingestionDone, undefined), |
| 2614 | }), | 2608 | }), |
| 2615 | startTurn: () => Effect.void, | 2609 | startTurn: () => Effect.void, |
| 2616 | } as unknown as ProviderAdapterV2SessionRuntime, | 2610 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 2617 | run: { | 2611 | run: { |
| 2618 | id: ids.runId, | 2612 | id: ids.runId, |
| 2619 | threadId: ids.threadId, | 2613 | threadId: ids.threadId, |
| ... | @@ -2940,11 +2934,11 @@ it.effect( | ... | @@ -2940,11 +2934,11 @@ it.effect( |
| 2940 | }, | 2934 | }, |
| 2941 | }, | 2935 | }, |
| 2942 | rootTerminalEvent(ids, "interrupted"), | 2936 | rootTerminalEvent(ids, "interrupted"), |
| 2943 | ] satisfies ReadonlyArray<ProviderAdapterV2Event>), | 2937 | ] satisfies ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>), |
| 2944 | close: Deferred.succeed(ingestionDone, undefined), | 2938 | close: Deferred.succeed(ingestionDone, undefined), |
| 2945 | }), | 2939 | }), |
| 2946 | startTurn: () => Effect.void, | 2940 | startTurn: () => Effect.void, |
| 2947 | } as unknown as ProviderAdapterV2SessionRuntime, | 2941 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 2948 | run: { | 2942 | run: { |
| 2949 | id: ids.runId, | 2943 | id: ids.runId, |
| 2950 | threadId: ids.threadId, | 2944 | threadId: ids.threadId, |
| ... | @@ -3439,7 +3433,7 @@ it.effect("refreshes pull requests after a provider stream exits with an error", | ... | @@ -3439,7 +3433,7 @@ it.effect("refreshes pull requests after a provider stream exits with an error", |
| 3439 | shouldFinalizeRun: () => Effect.succeed(true), | 3433 | shouldFinalizeRun: () => Effect.succeed(true), |
| 3440 | events: () => | 3434 | events: () => |
| 3441 | Stream.fail( | 3435 | Stream.fail( |
| 3442 | new ProviderAdapterEventStreamError({ | 3436 | new ProviderAdapter.ProviderAdapterEventStreamError({ |
| 3443 | driver, | 3437 | driver, |
| 3444 | providerSessionId: ProviderSessionId.make("session:exited"), | 3438 | providerSessionId: ProviderSessionId.make("session:exited"), |
| 3445 | cause: "provider process exited", | 3439 | cause: "provider process exited", |
| ... | @@ -3468,7 +3462,7 @@ it.effect("refreshes pull requests only once when startup failure closes its eve | ... | @@ -3468,7 +3462,7 @@ it.effect("refreshes pull requests only once when startup failure closes its eve |
| 3468 | Deferred.await(ingestionStarted).pipe( | 3462 | Deferred.await(ingestionStarted).pipe( |
| 3469 | Effect.andThen( | 3463 | Effect.andThen( |
| 3470 | Effect.fail( | 3464 | Effect.fail( |
| 3471 | new ProviderAdapterTurnStartError({ | 3465 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 3472 | driver, | 3466 | driver, |
| 3473 | threadId: input.threadId, | 3467 | threadId: input.threadId, |
| 3474 | providerThreadId: input.providerThread.id, | 3468 | providerThreadId: input.providerThread.id, |
| ... | @@ -3506,8 +3500,11 @@ function captureRootRunTermination(input: { | ... | @@ -3506,8 +3500,11 @@ function captureRootRunTermination(input: { |
| 3506 | readonly seedOpenSubagent?: boolean; | 3500 | readonly seedOpenSubagent?: boolean; |
| 3507 | readonly events?: ( | 3501 | readonly events?: ( |
| 3508 | ids: BackgroundScenarioIds, | 3502 | ids: BackgroundScenarioIds, |
| 3509 | ) => Stream.Stream<ProviderAdapterV2Event, ProviderAdapterV2Error>; | 3503 | ) => Stream.Stream< |
| 3510 | readonly startTurn?: ProviderAdapterV2SessionRuntime["startTurn"]; | 3504 | ProviderAdapter.ProviderAdapterV2Event, |
| 3505 | ProviderAdapter.ProviderAdapterV2Error | ||
| 3506 | >; | ||
| 3507 | readonly startTurn?: ProviderAdapter.ProviderAdapterV2SessionRuntime["startTurn"]; | ||
| 3511 | readonly refreshAfterTurn?: Effect.Effect<void>; | 3508 | readonly refreshAfterTurn?: Effect.Effect<void>; |
| 3512 | }) { | 3509 | }) { |
| 3513 | return Effect.gen(function* () { | 3510 | return Effect.gen(function* () { |
| ... | @@ -3622,11 +3619,11 @@ function captureRootRunTermination(input: { | ... | @@ -3622,11 +3619,11 @@ function captureRootRunTermination(input: { |
| 3622 | ] | 3619 | ] |
| 3623 | : []), | 3620 | : []), |
| 3624 | rootTerminalEvent(ids, "interrupted"), | 3621 | rootTerminalEvent(ids, "interrupted"), |
| 3625 | ] satisfies ReadonlyArray<ProviderAdapterV2Event>), | 3622 | ] satisfies ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>), |
| 3626 | close: Deferred.succeed(ingestionDone, undefined), | 3623 | close: Deferred.succeed(ingestionDone, undefined), |
| 3627 | }), | 3624 | }), |
| 3628 | startTurn: input.startTurn ?? (() => Effect.void), | 3625 | startTurn: input.startTurn ?? (() => Effect.void), |
| 3629 | } as unknown as ProviderAdapterV2SessionRuntime, | 3626 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 3630 | run: { | 3627 | run: { |
| 3631 | id: ids.runId, | 3628 | id: ids.runId, |
| 3632 | threadId: ids.threadId, | 3629 | threadId: ids.threadId, |
| ... | @@ -3716,7 +3713,9 @@ function backgroundScenarioIds(key: string): BackgroundScenarioIds { | ... | @@ -3716,7 +3713,9 @@ function backgroundScenarioIds(key: string): BackgroundScenarioIds { |
| 3716 | }; | 3713 | }; |
| 3717 | } | 3714 | } |
| 3718 | 3715 | ||
| 3719 | function childThreadCreatedEvent(ids: BackgroundScenarioIds): ProviderAdapterV2Event { | 3716 | function childThreadCreatedEvent( |
| 3717 | ids: BackgroundScenarioIds, | ||
| 3718 | ): ProviderAdapter.ProviderAdapterV2Event { | ||
| 3720 | return { | 3719 | return { |
| 3721 | type: "app_thread.created", | 3720 | type: "app_thread.created", |
| 3722 | driver, | 3721 | driver, |
| ... | @@ -3728,14 +3727,14 @@ function childThreadCreatedEvent(ids: BackgroundScenarioIds): ProviderAdapterV2E | ... | @@ -3728,14 +3727,14 @@ function childThreadCreatedEvent(ids: BackgroundScenarioIds): ProviderAdapterV2E |
| 3728 | rootThreadId: ids.threadId, | 3727 | rootThreadId: ids.threadId, |
| 3729 | }, | 3728 | }, |
| 3730 | }, | 3729 | }, |
| 3731 | } as ProviderAdapterV2Event; | 3730 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 3732 | } | 3731 | } |
| 3733 | 3732 | ||
| 3734 | function childBackgroundTurnItemEvent( | 3733 | function childBackgroundTurnItemEvent( |
| 3735 | ids: BackgroundScenarioIds, | 3734 | ids: BackgroundScenarioIds, |
| 3736 | status: "running" | "completed" | "idle", | 3735 | status: "running" | "completed" | "idle", |
| 3737 | ordinal: number, | 3736 | ordinal: number, |
| 3738 | ): ProviderAdapterV2Event { | 3737 | ): ProviderAdapter.ProviderAdapterV2Event { |
| 3739 | return { | 3738 | return { |
| 3740 | type: "turn_item.updated", | 3739 | type: "turn_item.updated", |
| 3741 | driver, | 3740 | driver, |
| ... | @@ -3748,7 +3747,7 @@ function childBackgroundTurnItemEvent( | ... | @@ -3748,7 +3747,7 @@ function childBackgroundTurnItemEvent( |
| 3748 | type: "command_execution", | 3747 | type: "command_execution", |
| 3749 | status, | 3748 | status, |
| 3750 | }, | 3749 | }, |
| 3751 | } as ProviderAdapterV2Event; | 3750 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 3752 | } | 3751 | } |
| 3753 | 3752 | ||
| 3754 | function backgroundTurnItemEvent( | 3753 | function backgroundTurnItemEvent( |
| ... | @@ -3757,7 +3756,7 @@ function backgroundTurnItemEvent( | ... | @@ -3757,7 +3756,7 @@ function backgroundTurnItemEvent( |
| 3757 | status: "running" | "completed" | "idle", | 3756 | status: "running" | "completed" | "idle", |
| 3758 | ordinal: number, | 3757 | ordinal: number, |
| 3759 | itemId?: TurnItemId, | 3758 | itemId?: TurnItemId, |
| 3760 | ): ProviderAdapterV2Event { | 3759 | ): ProviderAdapter.ProviderAdapterV2Event { |
| 3761 | return { | 3760 | return { |
| 3762 | type: "turn_item.updated", | 3761 | type: "turn_item.updated", |
| 3763 | driver, | 3762 | driver, |
| ... | @@ -3770,7 +3769,7 @@ function backgroundTurnItemEvent( | ... | @@ -3770,7 +3769,7 @@ function backgroundTurnItemEvent( |
| 3770 | type, | 3769 | type, |
| 3771 | status, | 3770 | status, |
| 3772 | }, | 3771 | }, |
| 3773 | } as ProviderAdapterV2Event; | 3772 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 3774 | } | 3773 | } |
| 3775 | 3774 | ||
| 3776 | function backgroundTurnItemEventForRun( | 3775 | function backgroundTurnItemEventForRun( |
| ... | @@ -3779,7 +3778,7 @@ function backgroundTurnItemEventForRun( | ... | @@ -3779,7 +3778,7 @@ function backgroundTurnItemEventForRun( |
| 3779 | type: "command_execution" | "dynamic_tool" | "subagent", | 3778 | type: "command_execution" | "dynamic_tool" | "subagent", |
| 3780 | status: "running" | "completed" | "idle", | 3779 | status: "running" | "completed" | "idle", |
| 3781 | ordinal: number, | 3780 | ordinal: number, |
| 3782 | ): ProviderAdapterV2Event { | 3781 | ): ProviderAdapter.ProviderAdapterV2Event { |
| 3783 | const event = backgroundTurnItemEvent(ids, type, status, ordinal); | 3782 | const event = backgroundTurnItemEvent(ids, type, status, ordinal); |
| 3784 | if (event.type !== "turn_item.updated") { | 3783 | if (event.type !== "turn_item.updated") { |
| 3785 | return event; | 3784 | return event; |
| ... | @@ -3790,7 +3789,7 @@ function backgroundTurnItemEventForRun( | ... | @@ -3790,7 +3789,7 @@ function backgroundTurnItemEventForRun( |
| 3790 | function subagentEvent( | 3789 | function subagentEvent( |
| 3791 | ids: BackgroundScenarioIds, | 3790 | ids: BackgroundScenarioIds, |
| 3792 | status: "running" | "completed" | "idle", | 3791 | status: "running" | "completed" | "idle", |
| 3793 | ): ProviderAdapterV2Event { | 3792 | ): ProviderAdapter.ProviderAdapterV2Event { |
| 3794 | return { | 3793 | return { |
| 3795 | type: "subagent.updated", | 3794 | type: "subagent.updated", |
| 3796 | driver, | 3795 | driver, |
| ... | @@ -3800,7 +3799,7 @@ function subagentEvent( | ... | @@ -3800,7 +3799,7 @@ function subagentEvent( |
| 3800 | runId: ids.runId, | 3799 | runId: ids.runId, |
| 3801 | status, | 3800 | status, |
| 3802 | }, | 3801 | }, |
| 3803 | } as ProviderAdapterV2Event; | 3802 | } as ProviderAdapter.ProviderAdapterV2Event; |
| 3804 | } | 3803 | } |
| 3805 | 3804 | ||
| 3806 | function makeRunOwnedSubagentFixture(input: { | 3805 | function makeRunOwnedSubagentFixture(input: { |
| ... | @@ -3977,7 +3976,7 @@ function makeRunOwnedSubagentChildNodeFixture(input: { | ... | @@ -3977,7 +3976,7 @@ function makeRunOwnedSubagentChildNodeFixture(input: { |
| 3977 | function rootTerminalEvent( | 3976 | function rootTerminalEvent( |
| 3978 | ids: BackgroundScenarioIds, | 3977 | ids: BackgroundScenarioIds, |
| 3979 | status: "completed" | "interrupted" | "cancelled" | "failed", | 3978 | status: "completed" | "interrupted" | "cancelled" | "failed", |
| 3980 | ): ProviderAdapterV2Event { | 3979 | ): ProviderAdapter.ProviderAdapterV2Event { |
| 3981 | const common = { | 3980 | const common = { |
| 3982 | type: "turn.terminal" as const, | 3981 | type: "turn.terminal" as const, |
| 3983 | driver, | 3982 | driver, |
| ... | @@ -4003,7 +4002,7 @@ function rootTerminalEvent( | ... | @@ -4003,7 +4002,7 @@ function rootTerminalEvent( |
| 4003 | 4002 | ||
| 4004 | function runBackgroundItemScenario( | 4003 | function runBackgroundItemScenario( |
| 4005 | key: string, | 4004 | key: string, |
| 4006 | makeEvents: (ids: BackgroundScenarioIds) => ReadonlyArray<ProviderAdapterV2Event>, | 4005 | makeEvents: (ids: BackgroundScenarioIds) => ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>, |
| 4007 | options?: { | 4006 | options?: { |
| 4008 | readonly keepEventStreamOpen?: boolean; | 4007 | readonly keepEventStreamOpen?: boolean; |
| 4009 | readonly loadInheritedBackgroundTurnItems?: () => Effect.Effect< | 4008 | readonly loadInheritedBackgroundTurnItems?: () => Effect.Effect< |
| ... | @@ -4082,7 +4081,7 @@ function runBackgroundItemScenario( | ... | @@ -4082,7 +4081,7 @@ function runBackgroundItemScenario( |
| 4082 | }; | 4081 | }; |
| 4083 | }), | 4082 | }), |
| 4084 | startTurn: () => Effect.void, | 4083 | startTurn: () => Effect.void, |
| 4085 | } as unknown as ProviderAdapterV2SessionRuntime, | 4084 | } as unknown as ProviderAdapter.ProviderAdapterV2SessionRuntime, |
| 4086 | run: { | 4085 | run: { |
| 4087 | id: ids.runId, | 4086 | id: ids.runId, |
| 4088 | threadId: ids.threadId, | 4087 | threadId: ids.threadId, |
apps/server/src/orchestration-v2/RunExecutionService.ts+15-16| ... | @@ -41,13 +41,7 @@ import * as ServerSettings from "../serverSettings.ts"; | ... | @@ -41,13 +41,7 @@ import * as ServerSettings from "../serverSettings.ts"; |
| 41 | import * as CheckpointService from "./CheckpointService.ts"; | 41 | import * as CheckpointService from "./CheckpointService.ts"; |
| 42 | import * as EventSink from "./EventSink.ts"; | 42 | import * as EventSink from "./EventSink.ts"; |
| 43 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 43 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 44 | import type { | 44 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 45 | ProviderAdapterV2Event, | ||
| 46 | ProviderAdapterV2RuntimePolicy, | ||
| 47 | ProviderAdapterV2SessionRuntime, | ||
| 48 | ProviderAdapterV2TurnMessage, | ||
| 49 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 50 | import { ProviderAdapterTurnStartError } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 51 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; | 45 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; |
| 52 | import type { ProjectionStoreV2Error } from "./ProjectionStore.ts"; | 46 | import type { ProjectionStoreV2Error } from "./ProjectionStore.ts"; |
| 53 | import { | 47 | import { |
| ... | @@ -79,7 +73,10 @@ export interface InheritedBackgroundTurnItemRoute { | ... | @@ -79,7 +73,10 @@ export interface InheritedBackgroundTurnItemRoute { |
| 79 | readonly runId: OrchestrationV2Run["id"]; | 73 | readonly runId: OrchestrationV2Run["id"]; |
| 80 | } | 74 | } |
| 81 | 75 | ||
| 82 | type ProviderTerminalEvent = Extract<ProviderAdapterV2Event, { readonly type: "turn.terminal" }>; | 76 | type ProviderTerminalEvent = Extract< |
| 77 | ProviderAdapter.ProviderAdapterV2Event, | ||
| 78 | { readonly type: "turn.terminal" } | ||
| 79 | >; | ||
| 83 | 80 | ||
| 84 | function isTerminalProviderTurnStatus(status: OrchestrationV2ProviderTurn["status"]): boolean { | 81 | function isTerminalProviderTurnStatus(status: OrchestrationV2ProviderTurn["status"]): boolean { |
| 85 | return ( | 82 | return ( |
| ... | @@ -351,7 +348,7 @@ export function makeProviderEventRoutingState(input: { | ... | @@ -351,7 +348,7 @@ export function makeProviderEventRoutingState(input: { |
| 351 | } | 348 | } |
| 352 | 349 | ||
| 353 | export function routeProviderEvent( | 350 | export function routeProviderEvent( |
| 354 | event: ProviderAdapterV2Event, | 351 | event: ProviderAdapter.ProviderAdapterV2Event, |
| 355 | input: ProviderEventRouteIdentity, | 352 | input: ProviderEventRouteIdentity, |
| 356 | state: ProviderEventRoutingState, | 353 | state: ProviderEventRoutingState, |
| 357 | ): readonly [boolean, ProviderEventRoutingState] { | 354 | ): readonly [boolean, ProviderEventRoutingState] { |
| ... | @@ -503,7 +500,7 @@ export interface RunExecutionServiceV2StartRootRunInput { | ... | @@ -503,7 +500,7 @@ export interface RunExecutionServiceV2StartRootRunInput { |
| 503 | readonly commandId: CommandId; | 500 | readonly commandId: CommandId; |
| 504 | readonly appThread: OrchestrationV2AppThread; | 501 | readonly appThread: OrchestrationV2AppThread; |
| 505 | readonly providerSessionId: ProviderSessionId; | 502 | readonly providerSessionId: ProviderSessionId; |
| 506 | readonly session: ProviderAdapterV2SessionRuntime; | 503 | readonly session: ProviderAdapter.ProviderAdapterV2SessionRuntime; |
| 507 | readonly run: OrchestrationV2Run; | 504 | readonly run: OrchestrationV2Run; |
| 508 | readonly rootNode: OrchestrationV2ExecutionNode; | 505 | readonly rootNode: OrchestrationV2ExecutionNode; |
| 509 | readonly checkpointScope: OrchestrationV2CheckpointScope; | 506 | readonly checkpointScope: OrchestrationV2CheckpointScope; |
| ... | @@ -521,9 +518,9 @@ export interface RunExecutionServiceV2StartRootRunInput { | ... | @@ -521,9 +518,9 @@ export interface RunExecutionServiceV2StartRootRunInput { |
| 521 | readonly shouldStartProviderTurn?: () => Effect.Effect<boolean, ProjectionStoreV2Error>; | 518 | readonly shouldStartProviderTurn?: () => Effect.Effect<boolean, ProjectionStoreV2Error>; |
| 522 | readonly shouldFinalizeRun?: () => Effect.Effect<boolean, ProjectionStoreV2Error>; | 519 | readonly shouldFinalizeRun?: () => Effect.Effect<boolean, ProjectionStoreV2Error>; |
| 523 | readonly hasUnpairedRunInterruptRequest?: () => Effect.Effect<boolean, never>; | 520 | readonly hasUnpairedRunInterruptRequest?: () => Effect.Effect<boolean, never>; |
| 524 | readonly message: ProviderAdapterV2TurnMessage; | 521 | readonly message: ProviderAdapter.ProviderAdapterV2TurnMessage; |
| 525 | readonly modelSelection: ModelSelection; | 522 | readonly modelSelection: ModelSelection; |
| 526 | readonly runtimePolicy: ProviderAdapterV2RuntimePolicy; | 523 | readonly runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy; |
| 527 | } | 524 | } |
| 528 | 525 | ||
| 529 | export interface RunExecutionServiceV2Shape { | 526 | export interface RunExecutionServiceV2Shape { |
| ... | @@ -738,7 +735,6 @@ export const layer: Layer.Layer< | ... | @@ -738,7 +735,6 @@ export const layer: Layer.Layer< |
| 738 | providerInstanceId: input.run.providerInstanceId, | 735 | providerInstanceId: input.run.providerInstanceId, |
| 739 | occurredAt: completedAt, | 736 | occurredAt: completedAt, |
| 740 | payload: makeProviderFailureTurnItem({ | 737 | payload: makeProviderFailureTurnItem({ |
| 741 | idAllocator, | ||
| 742 | driver: input.terminal.driver, | 738 | driver: input.terminal.driver, |
| 743 | threadId: input.run.threadId, | 739 | threadId: input.run.threadId, |
| 744 | runId: input.run.id, | 740 | runId: input.run.id, |
| ... | @@ -1006,7 +1002,10 @@ export const layer: Layer.Layer< | ... | @@ -1006,7 +1002,10 @@ export const layer: Layer.Layer< |
| 1006 | } | 1002 | } |
| 1007 | yield* Ref.set(rootRunFinalized, true); | 1003 | yield* Ref.set(rootRunFinalized, true); |
| 1008 | }); | 1004 | }); |
| 1009 | const trackChildLifecycle = (event: ProviderAdapterV2Event, deliverable: boolean) => | 1005 | const trackChildLifecycle = ( |
| 1006 | event: ProviderAdapter.ProviderAdapterV2Event, | ||
| 1007 | deliverable: boolean, | ||
| 1008 | ) => | ||
| 1010 | Effect.gen(function* () { | 1009 | Effect.gen(function* () { |
| 1011 | const routing = yield* Ref.get(eventRouting); | 1010 | const routing = yield* Ref.get(eventRouting); |
| 1012 | if (event.type === "provider_turn.updated") { | 1011 | if (event.type === "provider_turn.updated") { |
| ... | @@ -1403,7 +1402,7 @@ export const layer: Layer.Layer< | ... | @@ -1403,7 +1402,7 @@ export const layer: Layer.Layer< |
| 1403 | const startTurn = compact | 1402 | const startTurn = compact |
| 1404 | ? (input.session.compactThread?.(turnInput) ?? | 1403 | ? (input.session.compactThread?.(turnInput) ?? |
| 1405 | Effect.fail( | 1404 | Effect.fail( |
| 1406 | new ProviderAdapterTurnStartError({ | 1405 | new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 1407 | driver: input.session.driver, | 1406 | driver: input.session.driver, |
| 1408 | threadId: input.run.threadId, | 1407 | threadId: input.run.threadId, |
| 1409 | providerThreadId: input.providerThread.id, | 1408 | providerThreadId: input.providerThread.id, |
| ... | @@ -1471,7 +1470,7 @@ export const layer: Layer.Layer< | ... | @@ -1471,7 +1470,7 @@ export const layer: Layer.Layer< |
| 1471 | ); | 1470 | ); |
| 1472 | 1471 | ||
| 1473 | export function makeInterruptResultTurnItem(input: { | 1472 | export function makeInterruptResultTurnItem(input: { |
| 1474 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 1473 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 1475 | readonly run: OrchestrationV2Run; | 1474 | readonly run: OrchestrationV2Run; |
| 1476 | readonly rootNode: OrchestrationV2ExecutionNode; | 1475 | readonly rootNode: OrchestrationV2ExecutionNode; |
| 1477 | readonly providerThread: OrchestrationV2ProviderThread; | 1476 | readonly providerThread: OrchestrationV2ProviderThread; |
apps/server/src/orchestration-v2/RuntimePolicy.ts+4-7| ... | @@ -12,10 +12,7 @@ import * as Option from "effect/Option"; | ... | @@ -12,10 +12,7 @@ import * as Option from "effect/Option"; |
| 12 | import * as Schema from "effect/Schema"; | 12 | import * as Schema from "effect/Schema"; |
| 13 | 13 | ||
| 14 | import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry.ts"; | 14 | import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry.ts"; |
| 15 | import { | 15 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 16 | ProviderAdapterV2RuntimePolicy, | ||
| 17 | type ProviderAdapterV2RuntimePolicy as ProviderAdapterV2RuntimePolicyType, | ||
| 18 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 19 | import * as ProjectStore from "./ProjectStore.ts"; | 16 | import * as ProjectStore from "./ProjectStore.ts"; |
| 20 | 17 | ||
| 21 | /** | 18 | /** |
| ... | @@ -52,7 +49,7 @@ export interface RuntimePolicyV2Shape { | ... | @@ -52,7 +49,7 @@ export interface RuntimePolicyV2Shape { |
| 52 | readonly resolve: (input: { | 49 | readonly resolve: (input: { |
| 53 | readonly thread: OrchestrationV2AppThread; | 50 | readonly thread: OrchestrationV2AppThread; |
| 54 | readonly modelSelection: ModelSelection; | 51 | readonly modelSelection: ModelSelection; |
| 55 | }) => Effect.Effect<ProviderAdapterV2RuntimePolicyType, RuntimePolicyV2Error>; | 52 | }) => Effect.Effect<ProviderAdapter.ProviderAdapterV2RuntimePolicy, RuntimePolicyV2Error>; |
| 56 | } | 53 | } |
| 57 | 54 | ||
| 58 | export class RuntimePolicyV2 extends Context.Service<RuntimePolicyV2, RuntimePolicyV2Shape>()( | 55 | export class RuntimePolicyV2 extends Context.Service<RuntimePolicyV2, RuntimePolicyV2Shape>()( |
| ... | @@ -128,7 +125,7 @@ export const layerFromProjectStore: Layer.Layer< | ... | @@ -128,7 +125,7 @@ export const layerFromProjectStore: Layer.Layer< |
| 128 | }), | 125 | }), |
| 129 | ), | 126 | ), |
| 130 | )); | 127 | )); |
| 131 | return ProviderAdapterV2RuntimePolicy.make({ | 128 | return ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 132 | runtimeMode: providerRuntimeMode(input.thread.runtimeMode, supportedRuntimeModes), | 129 | runtimeMode: providerRuntimeMode(input.thread.runtimeMode, supportedRuntimeModes), |
| 133 | interactionMode: input.thread.interactionMode, | 130 | interactionMode: input.thread.interactionMode, |
| 134 | cwd, | 131 | cwd, |
| ... | @@ -149,7 +146,7 @@ export function layerWithOverride( | ... | @@ -149,7 +146,7 @@ export function layerWithOverride( |
| 149 | resolve: (input) => | 146 | resolve: (input) => |
| 150 | base.resolve(input).pipe( | 147 | base.resolve(input).pipe( |
| 151 | Effect.map((policy) => | 148 | Effect.map((policy) => |
| 152 | ProviderAdapterV2RuntimePolicy.make({ | 149 | ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 153 | ...policy, | 150 | ...policy, |
| 154 | ...(override.cwd === undefined ? {} : { cwd: override.cwd }), | 151 | ...(override.cwd === undefined ? {} : { cwd: override.cwd }), |
| 155 | ...(override.approvalPolicy === undefined | 152 | ...(override.approvalPolicy === undefined |
apps/server/src/orchestration-v2/RuntimeRequestService.test.ts+3-3| ... | @@ -12,7 +12,7 @@ import * as Effect from "effect/Effect"; | ... | @@ -12,7 +12,7 @@ import * as Effect from "effect/Effect"; |
| 12 | import * as Layer from "effect/Layer"; | 12 | import * as Layer from "effect/Layer"; |
| 13 | import * as Option from "effect/Option"; | 13 | import * as Option from "effect/Option"; |
| 14 | 14 | ||
| 15 | import type { ProviderAdapterV2RuntimeRequestResponseInput } from "@t3tools/provider-core/server/ProviderAdapter"; | 15 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 16 | import * as ProjectionStore from "./ProjectionStore.ts"; | 16 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 17 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 17 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 18 | import * as RuntimeRequestService from "./RuntimeRequestService.ts"; | 18 | import * as RuntimeRequestService from "./RuntimeRequestService.ts"; |
| ... | @@ -69,7 +69,7 @@ it.effect("forwards orchestrator-resolved runtime requests to the live adapter", | ... | @@ -69,7 +69,7 @@ it.effect("forwards orchestrator-resolved runtime requests to the live adapter", |
| 69 | const providerSessionId = ProviderSessionId.make("provider-session-runtime-request-resolved"); | 69 | const providerSessionId = ProviderSessionId.make("provider-session-runtime-request-resolved"); |
| 70 | const requestId = RuntimeRequestId.make("request-resolved"); | 70 | const requestId = RuntimeRequestId.make("request-resolved"); |
| 71 | const respondToRuntimeRequest = vi.fn( | 71 | const respondToRuntimeRequest = vi.fn( |
| 72 | (_input: ProviderAdapterV2RuntimeRequestResponseInput) => Effect.void, | 72 | (_input: ProviderAdapter.ProviderAdapterV2RuntimeRequestResponseInput) => Effect.void, |
| 73 | ); | 73 | ); |
| 74 | const getSession = vi.fn(() => | 74 | const getSession = vi.fn(() => |
| 75 | Effect.succeed( | 75 | Effect.succeed( |
| ... | @@ -133,7 +133,7 @@ it.effect("rejects expired runtime requests before invoking the live adapter", ( | ... | @@ -133,7 +133,7 @@ it.effect("rejects expired runtime requests before invoking the live adapter", ( |
| 133 | const providerSessionId = ProviderSessionId.make("provider-session-runtime-request-expired"); | 133 | const providerSessionId = ProviderSessionId.make("provider-session-runtime-request-expired"); |
| 134 | const requestId = RuntimeRequestId.make("request-expired"); | 134 | const requestId = RuntimeRequestId.make("request-expired"); |
| 135 | const respondToRuntimeRequest = vi.fn( | 135 | const respondToRuntimeRequest = vi.fn( |
| 136 | (_input: ProviderAdapterV2RuntimeRequestResponseInput) => Effect.void, | 136 | (_input: ProviderAdapter.ProviderAdapterV2RuntimeRequestResponseInput) => Effect.void, |
| 137 | ); | 137 | ); |
| 138 | const getSession = vi.fn(() => | 138 | const getSession = vi.fn(() => |
| 139 | Effect.succeed( | 139 | Effect.succeed( |
apps/server/src/orchestration-v2/SelectionRestart.integration.test.ts+10-13| ... | @@ -28,15 +28,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -28,15 +28,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 28 | import * as EffectWorker from "./EffectWorker.ts"; | 28 | import * as EffectWorker from "./EffectWorker.ts"; |
| 29 | import * as EventSink from "./EventSink.ts"; | 29 | import * as EventSink from "./EventSink.ts"; |
| 30 | import * as Orchestrator from "./Orchestrator.ts"; | 30 | import * as Orchestrator from "./Orchestrator.ts"; |
| 31 | import { | ||
| 32 | ProviderAdapterOpenSessionError, | ||
| 33 | type ProviderAdapterV2Event, | ||
| 34 | type ProviderAdapterV2Shape, | ||
| 35 | type ProviderAdapterV2TurnInput, | ||
| 36 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 37 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 31 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 38 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 32 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 39 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 33 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 34 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 40 | 35 | ||
| 41 | const driver = ProviderDriverKind.make("codex"); | 36 | const driver = ProviderDriverKind.make("codex"); |
| 42 | const providerInstanceId = ProviderInstanceId.make("codex-restart-test"); | 37 | const providerInstanceId = ProviderInstanceId.make("codex-restart-test"); |
| ... | @@ -69,7 +64,7 @@ const exclusiveCapabilities: OrchestrationV2ProviderCapabilities = { | ... | @@ -69,7 +64,7 @@ const exclusiveCapabilities: OrchestrationV2ProviderCapabilities = { |
| 69 | }; | 64 | }; |
| 70 | 65 | ||
| 71 | interface ActiveTurn { | 66 | interface ActiveTurn { |
| 72 | readonly input: ProviderAdapterV2TurnInput; | 67 | readonly input: ProviderAdapter.ProviderAdapterV2TurnInput; |
| 73 | readonly providerTurnId: ProviderTurnId; | 68 | readonly providerTurnId: ProviderTurnId; |
| 74 | } | 69 | } |
| 75 | 70 | ||
| ... | @@ -92,7 +87,7 @@ function makeRestartAdapter( | ... | @@ -92,7 +87,7 @@ function makeRestartAdapter( |
| 92 | state: Ref.Ref<RestartAdapterState>, | 87 | state: Ref.Ref<RestartAdapterState>, |
| 93 | sessionCapabilities: OrchestrationV2ProviderCapabilities = pooledCapabilities, | 88 | sessionCapabilities: OrchestrationV2ProviderCapabilities = pooledCapabilities, |
| 94 | providerInstanceId = initialSelection.instanceId, | 89 | providerInstanceId = initialSelection.instanceId, |
| 95 | ): ProviderAdapterV2Shape { | 90 | ): ProviderAdapter.ProviderAdapterV2["Service"] { |
| 96 | return { | 91 | return { |
| 97 | instanceId: providerInstanceId, | 92 | instanceId: providerInstanceId, |
| 98 | driver, | 93 | driver, |
| ... | @@ -125,14 +120,14 @@ function makeRestartAdapter( | ... | @@ -125,14 +120,14 @@ function makeRestartAdapter( |
| 125 | ] as const; | 120 | ] as const; |
| 126 | }); | 121 | }); |
| 127 | if (failThisOpen) { | 122 | if (failThisOpen) { |
| 128 | return yield* new ProviderAdapterOpenSessionError({ | 123 | return yield* new ProviderAdapter.ProviderAdapterOpenSessionError({ |
| 129 | driver, | 124 | driver, |
| 130 | providerSessionId: sessionInput.providerSessionId, | 125 | providerSessionId: sessionInput.providerSessionId, |
| 131 | cause: "simulated replacement open failure", | 126 | cause: "simulated replacement open failure", |
| 132 | }); | 127 | }); |
| 133 | } | 128 | } |
| 134 | 129 | ||
| 135 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 130 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 136 | const now = yield* DateTime.now; | 131 | const now = yield* DateTime.now; |
| 137 | const providerSession: OrchestrationV2ProviderSession = { | 132 | const providerSession: OrchestrationV2ProviderSession = { |
| 138 | id: sessionInput.providerSessionId, | 133 | id: sessionInput.providerSessionId, |
| ... | @@ -290,7 +285,9 @@ function makeRestartAdapter( | ... | @@ -290,7 +285,9 @@ function makeRestartAdapter( |
| 290 | }; | 285 | }; |
| 291 | } | 286 | } |
| 292 | 287 | ||
| 293 | function makeCompletingHandoffAdapter(startCount: Ref.Ref<number>): ProviderAdapterV2Shape { | 288 | function makeCompletingHandoffAdapter( |
| 289 | startCount: Ref.Ref<number>, | ||
| 290 | ): ProviderAdapter.ProviderAdapterV2["Service"] { | ||
| 294 | return { | 291 | return { |
| 295 | instanceId: handoffProviderInstanceId, | 292 | instanceId: handoffProviderInstanceId, |
| 296 | driver: handoffDriver, | 293 | driver: handoffDriver, |
| ... | @@ -298,7 +295,7 @@ function makeCompletingHandoffAdapter(startCount: Ref.Ref<number>): ProviderAdap | ... | @@ -298,7 +295,7 @@ function makeCompletingHandoffAdapter(startCount: Ref.Ref<number>): ProviderAdap |
| 298 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 295 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 299 | openSession: (sessionInput) => | 296 | openSession: (sessionInput) => |
| 300 | Effect.gen(function* () { | 297 | Effect.gen(function* () { |
| 301 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 298 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 302 | const now = yield* DateTime.now; | 299 | const now = yield* DateTime.now; |
| 303 | return { | 300 | return { |
| 304 | instanceId: handoffProviderInstanceId, | 301 | instanceId: handoffProviderInstanceId, |
| ... | @@ -865,7 +862,7 @@ it.live.each(["active", "idle", "selection-command", "pooled", "separate-home"] | ... | @@ -865,7 +862,7 @@ it.live.each(["active", "idle", "selection-command", "pooled", "separate-home"] |
| 865 | }), | 862 | }), |
| 866 | })), | 863 | })), |
| 867 | ), | 864 | ), |
| 868 | } satisfies ProviderAdapterV2Shape; | 865 | } satisfies ProviderAdapter.ProviderAdapterV2["Service"]; |
| 869 | }); | 866 | }); |
| 870 | const layerRegistry = Layer.succeed(ProviderAdapterRegistry.ProviderAdapterRegistryV2, { | 867 | const layerRegistry = Layer.succeed(ProviderAdapterRegistry.ProviderAdapterRegistryV2, { |
| 871 | get: (instanceId) => | 868 | get: (instanceId) => |
apps/server/src/orchestration-v2/SteeringCompletion.integration.test.ts+8-13| ... | @@ -23,15 +23,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -23,15 +23,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 23 | import * as EffectWorker from "./EffectWorker.ts"; | 23 | import * as EffectWorker from "./EffectWorker.ts"; |
| 24 | import * as EventSink from "./EventSink.ts"; | 24 | import * as EventSink from "./EventSink.ts"; |
| 25 | import * as Orchestrator from "./Orchestrator.ts"; | 25 | import * as Orchestrator from "./Orchestrator.ts"; |
| 26 | import { | ||
| 27 | ProviderAdapterSteerRunError, | ||
| 28 | type ProviderAdapterV2Event, | ||
| 29 | type ProviderAdapterV2Shape, | ||
| 30 | type ProviderAdapterV2TurnInput, | ||
| 31 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 32 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 26 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 33 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 27 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 34 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 28 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 29 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 35 | 30 | ||
| 36 | const driver = ProviderDriverKind.make("codex"); | 31 | const driver = ProviderDriverKind.make("codex"); |
| 37 | const instanceId = ProviderInstanceId.make("codex"); | 32 | const instanceId = ProviderInstanceId.make("codex"); |
| ... | @@ -67,8 +62,8 @@ it.effect.each( | ... | @@ -67,8 +62,8 @@ it.effect.each( |
| 67 | Effect.scoped( | 62 | Effect.scoped( |
| 68 | Effect.gen(function* () { | 63 | Effect.gen(function* () { |
| 69 | const cwd = yield* checkpointWorkspace(`steering-completion-${timing.replaceAll(" ", "-")}`); | 64 | const cwd = yield* checkpointWorkspace(`steering-completion-${timing.replaceAll(" ", "-")}`); |
| 70 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 65 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 71 | const started: ProviderAdapterV2TurnInput[] = []; | 66 | const started: ProviderAdapter.ProviderAdapterV2TurnInput[] = []; |
| 72 | const steerEntered = yield* Deferred.make<void>(); | 67 | const steerEntered = yield* Deferred.make<void>(); |
| 73 | const rejectSteer = yield* Deferred.make<void>(); | 68 | const rejectSteer = yield* Deferred.make<void>(); |
| 74 | let steerCalls = 0; | 69 | let steerCalls = 0; |
| ... | @@ -80,7 +75,7 @@ it.effect.each( | ... | @@ -80,7 +75,7 @@ it.effect.each( |
| 80 | activeSteeringInterruptsTools: timing === "with interrupting native steering", | 75 | activeSteeringInterruptsTools: timing === "with interrupting native steering", |
| 81 | }, | 76 | }, |
| 82 | }; | 77 | }; |
| 83 | const adapter: ProviderAdapterV2Shape = { | 78 | const adapter: ProviderAdapter.ProviderAdapterV2["Service"] = { |
| 84 | instanceId, | 79 | instanceId, |
| 85 | driver, | 80 | driver, |
| 86 | getCapabilities: () => Effect.succeed(capabilities), | 81 | getCapabilities: () => Effect.succeed(capabilities), |
| ... | @@ -153,7 +148,7 @@ it.effect.each( | ... | @@ -153,7 +148,7 @@ it.effect.each( |
| 153 | if (timing === "after delivery") return; | 148 | if (timing === "after delivery") return; |
| 154 | yield* Deferred.succeed(steerEntered, undefined); | 149 | yield* Deferred.succeed(steerEntered, undefined); |
| 155 | yield* Deferred.await(rejectSteer); | 150 | yield* Deferred.await(rejectSteer); |
| 156 | return yield* new ProviderAdapterSteerRunError({ | 151 | return yield* new ProviderAdapter.ProviderAdapterSteerRunError({ |
| 157 | driver, | 152 | driver, |
| 158 | providerThreadId: turn.providerThread.id, | 153 | providerThreadId: turn.providerThread.id, |
| 159 | providerTurnId: turn.providerTurnId, | 154 | providerTurnId: turn.providerTurnId, |
| ... | @@ -424,8 +419,8 @@ const composerSelection = { | ... | @@ -424,8 +419,8 @@ const composerSelection = { |
| 424 | 419 | ||
| 425 | const nextTurnSelectionHarness = Effect.fn("nextTurnSelectionHarness")(function* (name: string) { | 420 | const nextTurnSelectionHarness = Effect.fn("nextTurnSelectionHarness")(function* (name: string) { |
| 426 | const cwd = yield* checkpointWorkspace(name); | 421 | const cwd = yield* checkpointWorkspace(name); |
| 427 | const events = yield* Queue.unbounded<ProviderAdapterV2Event>(); | 422 | const events = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 428 | const started: ProviderAdapterV2TurnInput[] = []; | 423 | const started: ProviderAdapter.ProviderAdapterV2TurnInput[] = []; |
| 429 | const steered: string[] = []; | 424 | const steered: string[] = []; |
| 430 | const capabilities = { | 425 | const capabilities = { |
| 431 | ...CodexProviderCapabilitiesV2, | 426 | ...CodexProviderCapabilitiesV2, |
| ... | @@ -435,7 +430,7 @@ const nextTurnSelectionHarness = Effect.fn("nextTurnSelectionHarness")(function* | ... | @@ -435,7 +430,7 @@ const nextTurnSelectionHarness = Effect.fn("nextTurnSelectionHarness")(function* |
| 435 | supportsSteeringByInterruptRestart: false, | 430 | supportsSteeringByInterruptRestart: false, |
| 436 | }, | 431 | }, |
| 437 | }; | 432 | }; |
| 438 | const adapter: ProviderAdapterV2Shape = { | 433 | const adapter: ProviderAdapter.ProviderAdapterV2["Service"] = { |
| 439 | instanceId, | 434 | instanceId, |
| 440 | driver, | 435 | driver, |
| 441 | getCapabilities: () => Effect.succeed(capabilities), | 436 | getCapabilities: () => Effect.succeed(capabilities), |
apps/server/src/orchestration-v2/ThreadDeletion.ts+3-3| ... | @@ -7,7 +7,7 @@ import type * as DateTime from "effect/DateTime"; | ... | @@ -7,7 +7,7 @@ import type * as DateTime from "effect/DateTime"; |
| 7 | import * as Effect from "effect/Effect"; | 7 | import * as Effect from "effect/Effect"; |
| 8 | 8 | ||
| 9 | import type { PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; | 9 | import type { PendingOrchestrationEffectV2 } from "./EffectOutbox.ts"; |
| 10 | import type { IdAllocatorV2, IdAllocatorV2Error } from "@t3tools/provider-core/server/IdAllocator"; | 10 | import type * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 11 | 11 | ||
| 12 | export interface ThreadDeletionPlan { | 12 | export interface ThreadDeletionPlan { |
| 13 | readonly events: ReadonlyArray<OrchestrationV2DomainEvent>; | 13 | readonly events: ReadonlyArray<OrchestrationV2DomainEvent>; |
| ... | @@ -23,8 +23,8 @@ export const planThreadDeletion = Effect.fn("ThreadDeletion.planThreadDeletion") | ... | @@ -23,8 +23,8 @@ export const planThreadDeletion = Effect.fn("ThreadDeletion.planThreadDeletion") |
| 23 | >; | 23 | >; |
| 24 | readonly attachmentIds: ReadonlyArray<string>; | 24 | readonly attachmentIds: ReadonlyArray<string>; |
| 25 | readonly now: DateTime.Utc; | 25 | readonly now: DateTime.Utc; |
| 26 | readonly idAllocator: IdAllocatorV2["Service"]; | 26 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 27 | }): Effect.fn.Return<ThreadDeletionPlan, IdAllocatorV2Error> { | 27 | }): Effect.fn.Return<ThreadDeletionPlan, IdAllocator.IdAllocatorV2Error> { |
| 28 | const { command, projection, now, idAllocator } = input; | 28 | const { command, projection, now, idAllocator } = input; |
| 29 | const events: Array<OrchestrationV2DomainEvent> = []; | 29 | const events: Array<OrchestrationV2DomainEvent> = []; |
| 30 | const effects: Array<PendingOrchestrationEffectV2> = []; | 30 | const effects: Array<PendingOrchestrationEffectV2> = []; |
apps/server/src/orchestration-v2/ThreadFork.execution.test.ts+2-2| ... | @@ -21,15 +21,15 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -21,15 +21,15 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 21 | import { ClaudeProviderCapabilitiesV2 } from "./Adapters/ClaudeAdapterV2.ts"; | 21 | import { ClaudeProviderCapabilitiesV2 } from "./Adapters/ClaudeAdapterV2.ts"; |
| 22 | import * as EventSink from "./EventSink.ts"; | 22 | import * as EventSink from "./EventSink.ts"; |
| 23 | import * as Orchestrator from "./Orchestrator.ts"; | 23 | import * as Orchestrator from "./Orchestrator.ts"; |
| 24 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 25 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 24 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 26 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 25 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 26 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 27 | 27 | ||
| 28 | const forkCases = (["codex", "claudeAgent"] as const).flatMap((driverName) => { | 28 | const forkCases = (["codex", "claudeAgent"] as const).flatMap((driverName) => { |
| 29 | const driver = ProviderDriverKind.make(driverName); | 29 | const driver = ProviderDriverKind.make(driverName); |
| 30 | const instanceId = ProviderInstanceId.make(driver); | 30 | const instanceId = ProviderInstanceId.make(driver); |
| 31 | const modelSelection = { instanceId, model: "test-model" }; | 31 | const modelSelection = { instanceId, model: "test-model" }; |
| 32 | const adapter: ProviderAdapterV2Shape = { | 32 | const adapter: ProviderAdapter.ProviderAdapterV2["Service"] = { |
| 33 | instanceId, | 33 | instanceId, |
| 34 | driver, | 34 | driver, |
| 35 | getCapabilities: () => | 35 | getCapabilities: () => |
apps/server/src/orchestration-v2/ThreadLaunchService.test.ts+2-2| ... | @@ -54,12 +54,12 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -54,12 +54,12 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 54 | import * as CommandReceiptStore from "./CommandReceiptStore.ts"; | 54 | import * as CommandReceiptStore from "./CommandReceiptStore.ts"; |
| 55 | import * as EffectOutbox from "./EffectOutbox.ts"; | 55 | import * as EffectOutbox from "./EffectOutbox.ts"; |
| 56 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 56 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 57 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 58 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 57 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 59 | import * as ThreadLaunch from "./ThreadLaunchService.ts"; | 58 | import * as ThreadLaunch from "./ThreadLaunchService.ts"; |
| 60 | import * as ThreadManagement from "./ThreadManagementService.ts"; | 59 | import * as ThreadManagement from "./ThreadManagementService.ts"; |
| 61 | import * as ThreadTitleRegeneration from "./ThreadTitleRegenerationService.ts"; | 60 | import * as ThreadTitleRegeneration from "./ThreadTitleRegenerationService.ts"; |
| 62 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 61 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 62 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 63 | 63 | ||
| 64 | const projectId = ProjectId.make("project:launch-test"); | 64 | const projectId = ProjectId.make("project:launch-test"); |
| 65 | const otherProjectId = ProjectId.make("project:launch-other"); | 65 | const otherProjectId = ProjectId.make("project:launch-other"); |
| ... | @@ -94,7 +94,7 @@ const adapter = { | ... | @@ -94,7 +94,7 @@ const adapter = { |
| 94 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 94 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 95 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 95 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 96 | openSession: () => Effect.die("provider execution is disabled in launch tests"), | 96 | openSession: () => Effect.die("provider execution is disabled in launch tests"), |
| 97 | } as ProviderAdapterV2Shape; | 97 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 98 | 98 | ||
| 99 | interface HarnessOptions { | 99 | interface HarnessOptions { |
| 100 | readonly managedFolders?: Layer.Layer<ManagedProjectFolders.ManagedProjectFolders>; | 100 | readonly managedFolders?: Layer.Layer<ManagedProjectFolders.ManagedProjectFolders>; |
apps/server/src/orchestration-v2/ThreadStop.test.ts+2-2| ... | @@ -24,10 +24,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | ... | @@ -24,10 +24,10 @@ import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 24 | import { OrchestrationEffectRequestV2 } from "./EffectOutbox.ts"; | 24 | import { OrchestrationEffectRequestV2 } from "./EffectOutbox.ts"; |
| 25 | import * as Orchestrator from "./Orchestrator.ts"; | 25 | import * as Orchestrator from "./Orchestrator.ts"; |
| 26 | import * as ProjectionStore from "./ProjectionStore.ts"; | 26 | import * as ProjectionStore from "./ProjectionStore.ts"; |
| 27 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 28 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 27 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 29 | import * as ThreadManagementService from "./ThreadManagementService.ts"; | 28 | import * as ThreadManagementService from "./ThreadManagementService.ts"; |
| 30 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 29 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 30 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 31 | 31 | ||
| 32 | const instanceId = ProviderInstanceId.make("codex"); | 32 | const instanceId = ProviderInstanceId.make("codex"); |
| 33 | const modelSelection = { instanceId, model: "gpt-5.1-codex" }; | 33 | const modelSelection = { instanceId, model: "gpt-5.1-codex" }; |
| ... | @@ -37,7 +37,7 @@ const adapter = { | ... | @@ -37,7 +37,7 @@ const adapter = { |
| 37 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 37 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 38 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 38 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 39 | openSession: () => Effect.die("Runs here never reach a provider"), | 39 | openSession: () => Effect.die("Runs here never reach a provider"), |
| 40 | } as ProviderAdapterV2Shape; | 40 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 41 | const layerDatabase = SqlitePersistence.layerMemory; | 41 | const layerDatabase = SqlitePersistence.layerMemory; |
| 42 | // No effect worker: runs stay unstarted, so Stop ends them without a provider. | 42 | // No effect worker: runs stay unstarted, so Stop ends them without a provider. |
| 43 | const layerTest = ThreadManagementService.layer.pipe( | 43 | const layerTest = ThreadManagementService.layer.pipe( |
apps/server/src/orchestration-v2/ThreadTitleRegenerationService.test.ts+2-2| ... | @@ -22,11 +22,11 @@ import * as ServerSettings from "../serverSettings.ts"; | ... | @@ -22,11 +22,11 @@ import * as ServerSettings from "../serverSettings.ts"; |
| 22 | import * as TextGeneration from "../textGeneration/TextGeneration.ts"; | 22 | import * as TextGeneration from "../textGeneration/TextGeneration.ts"; |
| 23 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 23 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 24 | import * as EffectOutbox from "./EffectOutbox.ts"; | 24 | import * as EffectOutbox from "./EffectOutbox.ts"; |
| 25 | import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 26 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 25 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 27 | import * as ThreadManagement from "./ThreadManagementService.ts"; | 26 | import * as ThreadManagement from "./ThreadManagementService.ts"; |
| 28 | import * as ThreadTitleRegeneration from "./ThreadTitleRegenerationService.ts"; | 27 | import * as ThreadTitleRegeneration from "./ThreadTitleRegenerationService.ts"; |
| 29 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; | 28 | import * as ProviderReplayHarness from "./testkit/ProviderReplayHarness.ts"; |
| 29 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 30 | 30 | ||
| 31 | const projectId = ProjectId.make("project:title-regeneration"); | 31 | const projectId = ProjectId.make("project:title-regeneration"); |
| 32 | const modelSelection = { | 32 | const modelSelection = { |
| ... | @@ -40,7 +40,7 @@ const adapter = { | ... | @@ -40,7 +40,7 @@ const adapter = { |
| 40 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 40 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 41 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), | 41 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" as const }), |
| 42 | openSession: () => Effect.die("provider execution is disabled in title regeneration tests"), | 42 | openSession: () => Effect.die("provider execution is disabled in title regeneration tests"), |
| 43 | } as ProviderAdapterV2Shape; | 43 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 44 | 44 | ||
| 45 | function makeHarness( | 45 | function makeHarness( |
| 46 | options: { | 46 | options: { |
apps/server/src/orchestration-v2/assistantStreaming.test.ts+4-4| ... | @@ -2,9 +2,9 @@ import { describe, expect, it } from "vite-plus/test"; | ... | @@ -2,9 +2,9 @@ import { describe, expect, it } from "vite-plus/test"; |
| 2 | import { MessageId, NodeId, ProviderDriverKind, ThreadId, TurnItemId } from "@t3tools/contracts"; | 2 | import { MessageId, NodeId, ProviderDriverKind, ThreadId, TurnItemId } from "@t3tools/contracts"; |
| 3 | import * as DateTime from "effect/DateTime"; | 3 | import * as DateTime from "effect/DateTime"; |
| 4 | import { makeAssistantStreamingFilter, splitBufferedAssistantText } from "./assistantStreaming.ts"; | 4 | import { makeAssistantStreamingFilter, splitBufferedAssistantText } from "./assistantStreaming.ts"; |
| 5 | import type { ProviderAdapterV2Event } from "@t3tools/provider-core/server/ProviderAdapter"; | 5 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 6 | 6 | ||
| 7 | const message = (text: string, streaming = true): ProviderAdapterV2Event => ({ | 7 | const message = (text: string, streaming = true): ProviderAdapter.ProviderAdapterV2Event => ({ |
| 8 | type: "message.updated", | 8 | type: "message.updated", |
| 9 | driver: ProviderDriverKind.make("codex"), | 9 | driver: ProviderDriverKind.make("codex"), |
| 10 | message: { | 10 | message: { |
| ... | @@ -27,7 +27,7 @@ const turnItem = ( | ... | @@ -27,7 +27,7 @@ const turnItem = ( |
| 27 | text: string, | 27 | text: string, |
| 28 | streaming = true, | 28 | streaming = true, |
| 29 | type: "assistant_message" | "reasoning" = "assistant_message", | 29 | type: "assistant_message" | "reasoning" = "assistant_message", |
| 30 | ): ProviderAdapterV2Event => ({ | 30 | ): ProviderAdapter.ProviderAdapterV2Event => ({ |
| 31 | type: "turn_item.updated", | 31 | type: "turn_item.updated", |
| 32 | driver: ProviderDriverKind.make("codex"), | 32 | driver: ProviderDriverKind.make("codex"), |
| 33 | turnItem: { | 33 | turnItem: { |
| ... | @@ -108,7 +108,7 @@ describe("V2 assistant streaming", () => { | ... | @@ -108,7 +108,7 @@ describe("V2 assistant streaming", () => { |
| 108 | "suppresses running assistant nodes in %s mode while delivering tool and completed nodes", | 108 | "suppresses running assistant nodes in %s mode while delivering tool and completed nodes", |
| 109 | (mode) => { | 109 | (mode) => { |
| 110 | const filter = makeAssistantStreamingFilter(mode); | 110 | const filter = makeAssistantStreamingFilter(mode); |
| 111 | const running: Extract<ProviderAdapterV2Event, { type: "node.updated" }> = { | 111 | const running: Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "node.updated" }> = { |
| 112 | type: "node.updated", | 112 | type: "node.updated", |
| 113 | driver: ProviderDriverKind.make("codex"), | 113 | driver: ProviderDriverKind.make("codex"), |
| 114 | node: { | 114 | node: { |
apps/server/src/orchestration-v2/assistantStreaming.ts+5-2| ... | @@ -1,5 +1,5 @@ | ... | @@ -1,5 +1,5 @@ |
| 1 | import type { ResponseStreamingMode } from "@t3tools/contracts"; | 1 | import type { ResponseStreamingMode } from "@t3tools/contracts"; |
| 2 | import type { ProviderAdapterV2Event } from "@t3tools/provider-core/server/ProviderAdapter"; | 2 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 3 | 3 | ||
| 4 | // An opening fence may sit at any indentation, since fences inside list | 4 | // An opening fence may sit at any indentation, since fences inside list |
| 5 | // items are indented past the marker. A closing fence may be indented at most | 5 | // items are indented past the marker. A closing fence may be indented at most |
| ... | @@ -91,7 +91,10 @@ export function splitBufferedAssistantText(text: string): { ready: string; rest: | ... | @@ -91,7 +91,10 @@ export function splitBufferedAssistantText(text: string): { ready: string; rest: |
| 91 | /** Buffer assistant messages and reasoning alike, keeping unfinished markdown out of the read model. */ | 91 | /** Buffer assistant messages and reasoning alike, keeping unfinished markdown out of the read model. */ |
| 92 | export function makeAssistantStreamingFilter(mode: ResponseStreamingMode) { | 92 | export function makeAssistantStreamingFilter(mode: ResponseStreamingMode) { |
| 93 | const delivered = new Map<string, { text: string; at: number }>(); | 93 | const delivered = new Map<string, { text: string; at: number }>(); |
| 94 | return (event: ProviderAdapterV2Event, now: number): ProviderAdapterV2Event | null => { | 94 | return ( |
| 95 | event: ProviderAdapter.ProviderAdapterV2Event, | ||
| 96 | now: number, | ||
| 97 | ): ProviderAdapter.ProviderAdapterV2Event | null => { | ||
| 95 | if ( | 98 | if ( |
| 96 | event.type === "node.updated" && | 99 | event.type === "node.updated" && |
| 97 | event.node.kind === "assistant_message" && | 100 | event.node.kind === "assistant_message" && |
apps/server/src/orchestration-v2/legacy/LegacyV1Cutover.integration.test.ts+5-9| ... | @@ -44,14 +44,10 @@ import * as LegacyV1ThreadImporter from "./LegacyV1ThreadImporter.ts"; | ... | @@ -44,14 +44,10 @@ import * as LegacyV1ThreadImporter from "./LegacyV1ThreadImporter.ts"; |
| 44 | import * as Orchestrator from "../Orchestrator.ts"; | 44 | import * as Orchestrator from "../Orchestrator.ts"; |
| 45 | import * as ProjectionMaintenance from "../ProjectionMaintenance.ts"; | 45 | import * as ProjectionMaintenance from "../ProjectionMaintenance.ts"; |
| 46 | import * as ProjectionStore from "../ProjectionStore.ts"; | 46 | import * as ProjectionStore from "../ProjectionStore.ts"; |
| 47 | import { | ||
| 48 | ProviderAdapterProtocolError, | ||
| 49 | type ProviderAdapterV2Event, | ||
| 50 | type ProviderAdapterV2Shape, | ||
| 51 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 52 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 47 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 53 | import * as ProviderReplayHarness from "../testkit/ProviderReplayHarness.ts"; | 48 | import * as ProviderReplayHarness from "../testkit/ProviderReplayHarness.ts"; |
| 54 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 49 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 50 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 55 | 51 | ||
| 56 | const PROJECT_ID = "project:cutover"; | 52 | const PROJECT_ID = "project:cutover"; |
| 57 | const ACTIVE_THREAD = "thread:cutover:active"; | 53 | const ACTIVE_THREAD = "thread:cutover:active"; |
| ... | @@ -422,7 +418,7 @@ interface CapturedTurn { | ... | @@ -422,7 +418,7 @@ interface CapturedTurn { |
| 422 | } | 418 | } |
| 423 | 419 | ||
| 424 | const unimplemented = (detail: string) => | 420 | const unimplemented = (detail: string) => |
| 425 | Effect.fail(new ProviderAdapterProtocolError({ driver, detail })); | 421 | Effect.fail(new ProviderAdapter.ProviderAdapterProtocolError({ driver, detail })); |
| 426 | 422 | ||
| 427 | const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) => | 423 | const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) => |
| 428 | ({ | 424 | ({ |
| ... | @@ -432,7 +428,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = | ... | @@ -432,7 +428,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = |
| 432 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 428 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 433 | openSession: (sessionInput) => | 429 | openSession: (sessionInput) => |
| 434 | Effect.gen(function* () { | 430 | Effect.gen(function* () { |
| 435 | const events = yield* PubSub.unbounded<ProviderAdapterV2Event>(); | 431 | const events = yield* PubSub.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 436 | const now = yield* DateTime.now; | 432 | const now = yield* DateTime.now; |
| 437 | const providerSession: OrchestrationV2ProviderSession = { | 433 | const providerSession: OrchestrationV2ProviderSession = { |
| 438 | id: sessionInput.providerSessionId, | 434 | id: sessionInput.providerSessionId, |
| ... | @@ -551,7 +547,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = | ... | @@ -551,7 +547,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = |
| 551 | failure: null, | 547 | failure: null, |
| 552 | threadDisposition: "reusable", | 548 | threadDisposition: "reusable", |
| 553 | }, | 549 | }, |
| 554 | ] satisfies ReadonlyArray<ProviderAdapterV2Event>); | 550 | ] satisfies ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event>); |
| 555 | }), | 551 | }), |
| 556 | steerTurn: () => Effect.void, | 552 | steerTurn: () => Effect.void, |
| 557 | interruptTurn: () => Effect.void, | 553 | interruptTurn: () => Effect.void, |
| ... | @@ -561,7 +557,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = | ... | @@ -561,7 +557,7 @@ const makeCodexAdapter = (capturedTurns: Ref.Ref<ReadonlyArray<CapturedTurn>>) = |
| 561 | forkThread: () => unimplemented("forkThread unused in cutover test"), | 557 | forkThread: () => unimplemented("forkThread unused in cutover test"), |
| 562 | }; | 558 | }; |
| 563 | }), | 559 | }), |
| 564 | }) satisfies ProviderAdapterV2Shape; | 560 | }) satisfies ProviderAdapter.ProviderAdapterV2["Service"]; |
| 565 | 561 | ||
| 566 | const waitForIdle = Effect.fn("LegacyV1Cutover.waitForIdle")(function* (threadId: ThreadId) { | 562 | const waitForIdle = Effect.fn("LegacyV1Cutover.waitForIdle")(function* (threadId: ThreadId) { |
| 567 | const orchestrator = yield* Orchestrator.OrchestratorV2; | 563 | const orchestrator = yield* Orchestrator.OrchestratorV2; |
apps/server/src/orchestration-v2/runtimeLayer.test.ts+5-6| ... | @@ -67,16 +67,13 @@ import * as PullRequestWatchReactor from "./PullRequestWatchReactor.ts"; | ... | @@ -67,16 +67,13 @@ import * as PullRequestWatchReactor from "./PullRequestWatchReactor.ts"; |
| 67 | import { PullRequestProviderError } from "../pullRequest/PullRequestProvider.ts"; | 67 | import { PullRequestProviderError } from "../pullRequest/PullRequestProvider.ts"; |
| 68 | import * as PullRequestService from "../pullRequest/PullRequestService.ts"; | 68 | import * as PullRequestService from "../pullRequest/PullRequestService.ts"; |
| 69 | import * as ProjectStore from "./ProjectStore.ts"; | 69 | import * as ProjectStore from "./ProjectStore.ts"; |
| 70 | import type { | ||
| 71 | ProviderAdapterV2SessionRuntime, | ||
| 72 | ProviderAdapterV2Shape, | ||
| 73 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 74 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; | 70 | import * as ProviderSessionManager from "./ProviderSessionManager.ts"; |
| 75 | import * as RuntimeLayer from "./runtimeLayer.ts"; | 71 | import * as RuntimeLayer from "./runtimeLayer.ts"; |
| 76 | import { shellStreamItemFromThreadShell } from "./ShellStream.ts"; | 72 | import { shellStreamItemFromThreadShell } from "./ShellStream.ts"; |
| 77 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; | 73 | import { CodexProviderCapabilitiesV2 } from "./Adapters/CodexAdapterV2.ts"; |
| 78 | import * as ThreadManagementService from "./ThreadManagementService.ts"; | 74 | import * as ThreadManagementService from "./ThreadManagementService.ts"; |
| 79 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; | 75 | import * as ThreadCommandExecutor from "./ThreadCommandExecutor.ts"; |
| 76 | import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 80 | 77 | ||
| 81 | const layerPlatformTest = Layer.merge( | 78 | const layerPlatformTest = Layer.merge( |
| 82 | NodeServices.layer, | 79 | NodeServices.layer, |
| ... | @@ -119,7 +116,7 @@ const orchestrationAdapter = { | ... | @@ -119,7 +116,7 @@ const orchestrationAdapter = { |
| 119 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), | 116 | getCapabilities: () => Effect.succeed(CodexProviderCapabilitiesV2), |
| 120 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 117 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 121 | openSession: () => Effect.die("sessions are not used by lifecycle tests"), | 118 | openSession: () => Effect.die("sessions are not used by lifecycle tests"), |
| 122 | } as ProviderAdapterV2Shape; | 119 | } as ProviderAdapter.ProviderAdapterV2["Service"]; |
| 123 | const providerInstance = { | 120 | const providerInstance = { |
| 124 | instanceId: modelSelection.instanceId, | 121 | instanceId: modelSelection.instanceId, |
| 125 | driverKind: driver, | 122 | driverKind: driver, |
| ... | @@ -928,7 +925,9 @@ it.layer(layerTest)("OrchestrationV2LayerLive", (it) => { | ... | @@ -928,7 +925,9 @@ it.layer(layerTest)("OrchestrationV2LayerLive", (it) => { |
| 928 | const sessionSpy = vi | 925 | const sessionSpy = vi |
| 929 | .spyOn(sessions, "get") | 926 | .spyOn(sessions, "get") |
| 930 | .mockReturnValue( | 927 | .mockReturnValue( |
| 931 | Effect.succeed(Option.some({ providerSession } as ProviderAdapterV2SessionRuntime)), | 928 | Effect.succeed( |
| 929 | Option.some({ providerSession } as ProviderAdapter.ProviderAdapterV2SessionRuntime), | ||
| 930 | ), | ||
| 932 | ); | 931 | ); |
| 933 | yield* Effect.addFinalizer(() => Effect.sync(() => sessionSpy.mockRestore())); | 932 | yield* Effect.addFinalizer(() => Effect.sync(() => sessionSpy.mockRestore())); |
| 934 | 933 |
apps/server/src/orchestration-v2/runtimeLayer.ts+1-1| ... | @@ -30,7 +30,7 @@ import * as ProjectionStore from "./ProjectionStore.ts"; | ... | @@ -30,7 +30,7 @@ import * as ProjectionStore from "./ProjectionStore.ts"; |
| 30 | import * as ProjectionMaintenance from "./ProjectionMaintenance.ts"; | 30 | import * as ProjectionMaintenance from "./ProjectionMaintenance.ts"; |
| 31 | import * as ProjectStore from "./ProjectStore.ts"; | 31 | import * as ProjectStore from "./ProjectStore.ts"; |
| 32 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; | 32 | import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; |
| 33 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 33 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 34 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; | 34 | import * as ProviderContinuationService from "./ProviderContinuationService.ts"; |
| 35 | import * as ThreadTitleRegenerationService from "./ThreadTitleRegenerationService.ts"; | 35 | import * as ThreadTitleRegenerationService from "./ThreadTitleRegenerationService.ts"; |
| 36 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; | 36 | import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; |
apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts+1-1| ... | @@ -35,7 +35,7 @@ import * as ProjectionStore from "../ProjectionStore.ts"; | ... | @@ -35,7 +35,7 @@ import * as ProjectionStore from "../ProjectionStore.ts"; |
| 35 | import * as ProjectStore from "../ProjectStore.ts"; | 35 | import * as ProjectStore from "../ProjectStore.ts"; |
| 36 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 36 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 37 | import * as ProviderAuthService from "../../provider/ProviderAuthService.ts"; | 37 | import * as ProviderAuthService from "../../provider/ProviderAuthService.ts"; |
| 38 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 38 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 39 | import * as ProviderContinuationService from "../ProviderContinuationService.ts"; | 39 | import * as ProviderContinuationService from "../ProviderContinuationService.ts"; |
| 40 | import * as ProviderEventIngestor from "../ProviderEventIngestor.ts"; | 40 | import * as ProviderEventIngestor from "../ProviderEventIngestor.ts"; |
| 41 | import * as ProviderRuntimeRecoveryService from "../ProviderRuntimeRecoveryService.ts"; | 41 | import * as ProviderRuntimeRecoveryService from "../ProviderRuntimeRecoveryService.ts"; |
apps/server/src/orchestration-v2/testkit/ProviderSwitch.integration.test.ts+9-16| ... | @@ -52,14 +52,6 @@ import * as EffectWorker from "../EffectWorker.ts"; | ... | @@ -52,14 +52,6 @@ import * as EffectWorker from "../EffectWorker.ts"; |
| 52 | import * as EffectOutbox from "../EffectOutbox.ts"; | 52 | import * as EffectOutbox from "../EffectOutbox.ts"; |
| 53 | import * as ProjectionMaintenance from "../ProjectionMaintenance.ts"; | 53 | import * as ProjectionMaintenance from "../ProjectionMaintenance.ts"; |
| 54 | import * as ProjectionStore from "../ProjectionStore.ts"; | 54 | import * as ProjectionStore from "../ProjectionStore.ts"; |
| 55 | import { | ||
| 56 | type ProviderAdapterV2Event, | ||
| 57 | type ProviderAdapterV2HistoricalContext, | ||
| 58 | ProviderAdapterProtocolError, | ||
| 59 | ProviderAdapterTurnStartError, | ||
| 60 | type ProviderAdapterV2Shape, | ||
| 61 | type ProviderAdapterV2SessionRuntime, | ||
| 62 | } from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 63 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; | 55 | import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; |
| 64 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; | 56 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; |
| 65 | import { | 57 | import { |
| ... | @@ -70,6 +62,7 @@ import { | ... | @@ -70,6 +62,7 @@ import { |
| 70 | } from "./fixtures/shared.ts"; | 62 | } from "./fixtures/shared.ts"; |
| 71 | import * as ProviderReplayHarness from "./ProviderReplayHarness.ts"; | 63 | import * as ProviderReplayHarness from "./ProviderReplayHarness.ts"; |
| 72 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; | 64 | import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; |
| 65 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | ||
| 73 | 66 | ||
| 74 | const encodeJson = Schema.encodeEffect(Schema.fromJsonString(Schema.Unknown)); | 67 | const encodeJson = Schema.encodeEffect(Schema.fromJsonString(Schema.Unknown)); |
| 75 | 68 | ||
| ... | @@ -95,7 +88,7 @@ interface CapturedTurn { | ... | @@ -95,7 +88,7 @@ interface CapturedTurn { |
| 95 | } | 88 | } |
| 96 | 89 | ||
| 97 | function unimplemented(driver: ProviderDriverKind, detail: string) { | 90 | function unimplemented(driver: ProviderDriverKind, detail: string) { |
| 98 | return Effect.fail(new ProviderAdapterProtocolError({ driver, detail })); | 91 | return Effect.fail(new ProviderAdapter.ProviderAdapterProtocolError({ driver, detail })); |
| 99 | } | 92 | } |
| 100 | 93 | ||
| 101 | function makeTestAdapter(input: { | 94 | function makeTestAdapter(input: { |
| ... | @@ -116,7 +109,7 @@ function makeTestAdapter(input: { | ... | @@ -116,7 +109,7 @@ function makeTestAdapter(input: { |
| 116 | readonly failResumeOnce?: Ref.Ref<boolean>; | 109 | readonly failResumeOnce?: Ref.Ref<boolean>; |
| 117 | readonly initialContextUsage?: OrchestrationV2ProviderThread["contextUsage"]; | 110 | readonly initialContextUsage?: OrchestrationV2ProviderThread["contextUsage"]; |
| 118 | readonly getModelContextWindow?: (selection: ModelSelection) => number | undefined; | 111 | readonly getModelContextWindow?: (selection: ModelSelection) => number | undefined; |
| 119 | readonly canReuseContextUsage?: ProviderAdapterV2SessionRuntime["canReuseContextUsage"]; | 112 | readonly canReuseContextUsage?: ProviderAdapter.ProviderAdapterV2SessionRuntime["canReuseContextUsage"]; |
| 120 | readonly tokenUsageByRunOrdinal?: Readonly< | 113 | readonly tokenUsageByRunOrdinal?: Readonly< |
| 121 | Record<number, Omit<OrchestrationV2ProviderTurnTokenUsage, "updatedAt">> | 114 | Record<number, Omit<OrchestrationV2ProviderTurnTokenUsage, "updatedAt">> |
| 122 | >; | 115 | >; |
| ... | @@ -125,7 +118,7 @@ function makeTestAdapter(input: { | ... | @@ -125,7 +118,7 @@ function makeTestAdapter(input: { |
| 125 | readonly holdRunOrdinal?: number; | 118 | readonly holdRunOrdinal?: number; |
| 126 | readonly holdFirstTurn?: Deferred.Deferred<void>; | 119 | readonly holdFirstTurn?: Deferred.Deferred<void>; |
| 127 | readonly releaseFirstTurn?: Deferred.Deferred<void>; | 120 | readonly releaseFirstTurn?: Deferred.Deferred<void>; |
| 128 | }): ProviderAdapterV2Shape { | 121 | }): ProviderAdapter.ProviderAdapterV2["Service"] { |
| 129 | return { | 122 | return { |
| 130 | instanceId: input.instanceId, | 123 | instanceId: input.instanceId, |
| 131 | driver: input.driver, | 124 | driver: input.driver, |
| ... | @@ -133,7 +126,7 @@ function makeTestAdapter(input: { | ... | @@ -133,7 +126,7 @@ function makeTestAdapter(input: { |
| 133 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), | 126 | planSelectionTransition: () => Effect.succeed({ type: "apply_on_next_turn" }), |
| 134 | openSession: (sessionInput) => | 127 | openSession: (sessionInput) => |
| 135 | Effect.gen(function* () { | 128 | Effect.gen(function* () { |
| 136 | const events = yield* PubSub.unbounded<ProviderAdapterV2Event>(); | 129 | const events = yield* PubSub.unbounded<ProviderAdapter.ProviderAdapterV2Event>(); |
| 137 | const now = yield* DateTime.now; | 130 | const now = yield* DateTime.now; |
| 138 | const providerSession: OrchestrationV2ProviderSession = { | 131 | const providerSession: OrchestrationV2ProviderSession = { |
| 139 | id: sessionInput.providerSessionId, | 132 | id: sessionInput.providerSessionId, |
| ... | @@ -148,7 +141,7 @@ function makeTestAdapter(input: { | ... | @@ -148,7 +141,7 @@ function makeTestAdapter(input: { |
| 148 | lastError: null, | 141 | lastError: null, |
| 149 | }; | 142 | }; |
| 150 | 143 | ||
| 151 | const runtime: ProviderAdapterV2SessionRuntime = { | 144 | const runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime = { |
| 152 | instanceId: input.instanceId, | 145 | instanceId: input.instanceId, |
| 153 | driver: input.driver, | 146 | driver: input.driver, |
| 154 | providerSessionId: sessionInput.providerSessionId, | 147 | providerSessionId: sessionInput.providerSessionId, |
| ... | @@ -204,7 +197,7 @@ function makeTestAdapter(input: { | ... | @@ -204,7 +197,7 @@ function makeTestAdapter(input: { |
| 204 | ...(input.injectedHistory === undefined | 197 | ...(input.injectedHistory === undefined |
| 205 | ? {} | 198 | ? {} |
| 206 | : { | 199 | : { |
| 207 | injectHistory: (history: ProviderAdapterV2HistoricalContext) => | 200 | injectHistory: (history: ProviderAdapter.ProviderAdapterV2HistoricalContext) => |
| 208 | Ref.update(input.injectedHistory!, (current) => [ | 201 | Ref.update(input.injectedHistory!, (current) => [ |
| 209 | ...current, | 202 | ...current, |
| 210 | ...historyResponseItems(history.messages, history.context), | 203 | ...historyResponseItems(history.messages, history.context), |
| ... | @@ -236,7 +229,7 @@ function makeTestAdapter(input: { | ... | @@ -236,7 +229,7 @@ function makeTestAdapter(input: { |
| 236 | input.refuseStarts !== undefined && | 229 | input.refuseStarts !== undefined && |
| 237 | (yield* Ref.getAndUpdate(input.refuseStarts, (left) => Math.max(0, left - 1))) > 0 | 230 | (yield* Ref.getAndUpdate(input.refuseStarts, (left) => Math.max(0, left - 1))) > 0 |
| 238 | ) | 231 | ) |
| 239 | return yield* new ProviderAdapterTurnStartError({ | 232 | return yield* new ProviderAdapter.ProviderAdapterTurnStartError({ |
| 240 | driver: input.driver, | 233 | driver: input.driver, |
| 241 | threadId: turnInput.threadId, | 234 | threadId: turnInput.threadId, |
| 242 | providerThreadId: turnInput.providerThread.id, | 235 | providerThreadId: turnInput.providerThread.id, |
| ... | @@ -280,7 +273,7 @@ function makeTestAdapter(input: { | ... | @@ -280,7 +273,7 @@ function makeTestAdapter(input: { |
| 280 | input.responseByThreadId?.[turnInput.threadId]?.[turnInput.runOrdinal] ?? | 273 | input.responseByThreadId?.[turnInput.threadId]?.[turnInput.runOrdinal] ?? |
| 281 | input.responseByRunOrdinal[turnInput.runOrdinal] ?? | 274 | input.responseByRunOrdinal[turnInput.runOrdinal] ?? |
| 282 | `${input.driver} response for run ${turnInput.runOrdinal}`; | 275 | `${input.driver} response for run ${turnInput.runOrdinal}`; |
| 283 | const providerEvents: ReadonlyArray<ProviderAdapterV2Event> = [ | 276 | const providerEvents: ReadonlyArray<ProviderAdapter.ProviderAdapterV2Event> = [ |
| 284 | { | 277 | { |
| 285 | type: "provider_turn.updated", | 278 | type: "provider_turn.updated", |
| 286 | driver: input.driver, | 279 | driver: input.driver, |
apps/server/src/provider/CodexChatGptAuth.ts+2-2| ... | @@ -19,8 +19,8 @@ import * as Effect from "effect/Effect"; | ... | @@ -19,8 +19,8 @@ import * as Effect from "effect/Effect"; |
| 19 | import * as Option from "effect/Option"; | 19 | import * as Option from "effect/Option"; |
| 20 | import * as Schema from "effect/Schema"; | 20 | import * as Schema from "effect/Schema"; |
| 21 | import * as Semaphore from "effect/Semaphore"; | 21 | import * as Semaphore from "effect/Semaphore"; |
| 22 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/ProviderAuthFlow"; | 22 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/providerAuthFlow"; |
| 23 | import type { ProviderAuthFlowContext } from "@t3tools/provider-core/server/ProviderAuthFlow"; | 23 | import type { ProviderAuthFlowContext } from "@t3tools/provider-core/server/providerAuthFlow"; |
| 24 | import { HttpClient, HttpClientRequest } from "effect/http"; | 24 | import { HttpClient, HttpClientRequest } from "effect/http"; |
| 25 | import * as ProviderCredentialStore from "./ProviderCredentialStore.ts"; | 25 | import * as ProviderCredentialStore from "./ProviderCredentialStore.ts"; |
| 26 | import { withChatGptSessionLock } from "./CodexChatGptSessionLock.ts"; | 26 | import { withChatGptSessionLock } from "./CodexChatGptSessionLock.ts"; |
apps/server/src/provider/Drivers/AntigravityDriver.test.ts+1-1| ... | @@ -29,7 +29,7 @@ import { | ... | @@ -29,7 +29,7 @@ import { |
| 29 | ANTIGRAVITY_AUTH_STDOUT_PREFIX, | 29 | ANTIGRAVITY_AUTH_STDOUT_PREFIX, |
| 30 | resolveAntigravityInstanceDirectories, | 30 | resolveAntigravityInstanceDirectories, |
| 31 | } from "../antigravityAuthSupport.ts"; | 31 | } from "../antigravityAuthSupport.ts"; |
| 32 | import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; | 32 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 33 | import * as ModelManifest from "../ModelManifest.ts"; | 33 | import * as ModelManifest from "../ModelManifest.ts"; |
| 34 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 34 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 35 | import { AntigravityDriver } from "./AntigravityDriver.ts"; | 35 | import { AntigravityDriver } from "./AntigravityDriver.ts"; |
apps/server/src/provider/Drivers/AntigravityDriver.ts+5-5| ... | @@ -18,7 +18,7 @@ import * as Stream from "effect/Stream"; | ... | @@ -18,7 +18,7 @@ import * as Stream from "effect/Stream"; |
| 18 | import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"; | 18 | import * as ChildProcessSpawner from "effect/process/ChildProcessSpawner"; |
| 19 | import type { AcpError } from "effect-acp/errors"; | 19 | import type { AcpError } from "effect-acp/errors"; |
| 20 | 20 | ||
| 21 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 21 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 22 | import { | 22 | import { |
| 23 | isAntigravityTextGenerationAvailable, | 23 | isAntigravityTextGenerationAvailable, |
| 24 | makeAntigravityTextGeneration, | 24 | makeAntigravityTextGeneration, |
| ... | @@ -46,12 +46,12 @@ import { | ... | @@ -46,12 +46,12 @@ import { |
| 46 | removeAntigravitySessionFiles, | 46 | removeAntigravitySessionFiles, |
| 47 | } from "../acp/AntigravitySessionFiles.ts"; | 47 | } from "../acp/AntigravitySessionFiles.ts"; |
| 48 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 48 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 49 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 49 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 50 | import { makeAntigravityAdapterV2 } from "../../orchestration-v2/Adapters/AntigravityAdapterV2.ts"; | 50 | import { makeAntigravityAdapterV2 } from "../../orchestration-v2/Adapters/AntigravityAdapterV2.ts"; |
| 51 | import { makeAcpNativeLoggerFactory } from "@t3tools/provider-acp/server/nativeLogging"; | 51 | import { makeAcpNativeLoggerFactory } from "@t3tools/provider-acp/server/nativeLogging"; |
| 52 | import { ProviderDriverError } from "../Errors.ts"; | 52 | import { ProviderDriverError } from "../Errors.ts"; |
| 53 | import { makeAntigravityProvider } from "../AntigravityProvider.ts"; | 53 | import { makeAntigravityProvider } from "../AntigravityProvider.ts"; |
| 54 | import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; | 54 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 55 | import * as ModelCatalog from "@t3tools/provider-core/server/ModelCatalog"; | 55 | import * as ModelCatalog from "@t3tools/provider-core/server/ModelCatalog"; |
| 56 | import { | 56 | import { |
| 57 | defaultProviderContinuationIdentity, | 57 | defaultProviderContinuationIdentity, |
| ... | @@ -68,7 +68,7 @@ const isNodeRuntimeUnavailableError = Schema.is(NodeRuntimeUnavailableError); | ... | @@ -68,7 +68,7 @@ const isNodeRuntimeUnavailableError = Schema.is(NodeRuntimeUnavailableError); |
| 68 | 68 | ||
| 69 | export type AntigravityDriverEnv = | 69 | export type AntigravityDriverEnv = |
| 70 | | AntigravityInstallation.AntigravityInstallation | 70 | | AntigravityInstallation.AntigravityInstallation |
| 71 | | ProviderHost | 71 | | ProviderHost.ProviderHost |
| 72 | | ChildProcessSpawner.ChildProcessSpawner | 72 | | ChildProcessSpawner.ChildProcessSpawner |
| 73 | | Crypto.Crypto | 73 | | Crypto.Crypto |
| 74 | | FileSystem.FileSystem | 74 | | FileSystem.FileSystem |
| ... | @@ -89,7 +89,7 @@ export const AntigravityDriver: ProviderDriver<AntigravitySettings, AntigravityD | ... | @@ -89,7 +89,7 @@ export const AntigravityDriver: ProviderDriver<AntigravitySettings, AntigravityD |
| 89 | const fileSystem = yield* FileSystem.FileSystem; | 89 | const fileSystem = yield* FileSystem.FileSystem; |
| 90 | const path = yield* Path.Path; | 90 | const path = yield* Path.Path; |
| 91 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; | 91 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; |
| 92 | const host = yield* ProviderHost; | 92 | const host = yield* ProviderHost.ProviderHost; |
| 93 | const selfInvocation = yield* resolveSelfInvocation(); | 93 | const selfInvocation = yield* resolveSelfInvocation(); |
| 94 | const installation = yield* AntigravityInstallation.AntigravityInstallation; | 94 | const installation = yield* AntigravityInstallation.AntigravityInstallation; |
| 95 | const loggers = yield* ProviderEventLoggers.ProviderEventLoggers; | 95 | const loggers = yield* ProviderEventLoggers.ProviderEventLoggers; |
apps/server/src/provider/Drivers/ClaudeDriver.ts+4-5| ... | @@ -24,10 +24,10 @@ import { HttpClient } from "effect/http"; | ... | @@ -24,10 +24,10 @@ import { HttpClient } from "effect/http"; |
| 24 | import { ChildProcessSpawner } from "effect/process"; | 24 | import { ChildProcessSpawner } from "effect/process"; |
| 25 | 25 | ||
| 26 | import { makeClaudeTextGeneration } from "../../textGeneration/ClaudeTextGeneration.ts"; | 26 | import { makeClaudeTextGeneration } from "../../textGeneration/ClaudeTextGeneration.ts"; |
| 27 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 27 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 28 | import * as ServerConfig from "../../config.ts"; | 28 | import * as ServerConfig from "../../config.ts"; |
| 29 | import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion"; | 29 | import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion"; |
| 30 | import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; | 30 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 31 | import { | 31 | import { |
| 32 | createClaudeAdapterV2, | 32 | createClaudeAdapterV2, |
| 33 | type ClaudeAdapterV2DriverEnv, | 33 | type ClaudeAdapterV2DriverEnv, |
| ... | @@ -94,7 +94,7 @@ const UPDATE = makePackageManagedProviderMaintenanceResolver({ | ... | @@ -94,7 +94,7 @@ const UPDATE = makePackageManagedProviderMaintenanceResolver({ |
| 94 | 94 | ||
| 95 | export type ClaudeDriverEnv = | 95 | export type ClaudeDriverEnv = |
| 96 | | ClaudeAdapterV2DriverEnv | 96 | | ClaudeAdapterV2DriverEnv |
| 97 | | ProviderHost | 97 | | ProviderHost.ProviderHost |
| 98 | | ChildProcessSpawner.ChildProcessSpawner | 98 | | ChildProcessSpawner.ChildProcessSpawner |
| 99 | | ResetCreditCoordinator.ResetCreditCoordinator | 99 | | ResetCreditCoordinator.ResetCreditCoordinator |
| 100 | | Crypto.Crypto | 100 | | Crypto.Crypto |
| ... | @@ -121,7 +121,6 @@ export const ClaudeDriver: ProviderDriver<ClaudeSettings, ClaudeDriverEnv> = { | ... | @@ -121,7 +121,6 @@ export const ClaudeDriver: ProviderDriver<ClaudeSettings, ClaudeDriverEnv> = { |
| 121 | const { cwd } = yield* ServerConfig.ServerConfig; | 121 | const { cwd } = yield* ServerConfig.ServerConfig; |
| 122 | const httpClient = yield* HttpClient.HttpClient; | 122 | const httpClient = yield* HttpClient.HttpClient; |
| 123 | const resetCreditCoordinator = yield* ResetCreditCoordinator.ResetCreditCoordinator; | 123 | const resetCreditCoordinator = yield* ResetCreditCoordinator.ResetCreditCoordinator; |
| 124 | const host = yield* ProviderHost; | ||
| 125 | const catalogService = yield* ModelCatalog.ModelCatalog; | 124 | const catalogService = yield* ModelCatalog.ModelCatalog; |
| 126 | const modelCatalog = catalogService | 125 | const modelCatalog = catalogService |
| 127 | .current(DRIVER_KIND) | 126 | .current(DRIVER_KIND) |
| ... | @@ -237,7 +236,7 @@ export const ClaudeDriver: ProviderDriver<ClaudeSettings, ClaudeDriverEnv> = { | ... | @@ -237,7 +236,7 @@ export const ClaudeDriver: ProviderDriver<ClaudeSettings, ClaudeDriverEnv> = { |
| 237 | Effect.provideService(Path.Path, path), | 236 | Effect.provideService(Path.Path, path), |
| 238 | ); | 237 | ); |
| 239 | 238 | ||
| 240 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 239 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 241 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<ClaudeSettings>>({ | 240 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<ClaudeSettings>>({ |
| 242 | resolveMaintenance, | 241 | resolveMaintenance, |
| 243 | getSettings: snapshotSettings.getSettings, | 242 | getSettings: snapshotSettings.getSettings, |
apps/server/src/provider/Drivers/CodexDriver.test.ts+3-3| ... | @@ -26,7 +26,7 @@ import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts"; | ... | @@ -26,7 +26,7 @@ import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts"; |
| 26 | import * as ServerConfig from "../../config.ts"; | 26 | import * as ServerConfig from "../../config.ts"; |
| 27 | import * as ServerSettings from "../../serverSettings.ts"; | 27 | import * as ServerSettings from "../../serverSettings.ts"; |
| 28 | import * as ResetCreditCoordinator from "../resetCreditCoordinator.ts"; | 28 | import * as ResetCreditCoordinator from "../resetCreditCoordinator.ts"; |
| 29 | import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; | 29 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 30 | import * as ModelManifest from "../ModelManifest.ts"; | 30 | import * as ModelManifest from "../ModelManifest.ts"; |
| 31 | import { | 31 | import { |
| 32 | createProviderVersionAdvisory, | 32 | createProviderVersionAdvisory, |
| ... | @@ -36,7 +36,7 @@ import { | ... | @@ -36,7 +36,7 @@ import { |
| 36 | import { CodexDriver } from "./CodexDriver.ts"; | 36 | import { CodexDriver } from "./CodexDriver.ts"; |
| 37 | import * as CodexAdapterV2 from "../../orchestration-v2/Adapters/CodexAdapterV2.ts"; | 37 | import * as CodexAdapterV2 from "../../orchestration-v2/Adapters/CodexAdapterV2.ts"; |
| 38 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 38 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 39 | import { ProviderAdapterV2RuntimePolicy } from "@t3tools/provider-core/server/ProviderAdapter"; | 39 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 40 | import * as ProviderCredentialStore from "../ProviderCredentialStore.ts"; | 40 | import * as ProviderCredentialStore from "../ProviderCredentialStore.ts"; |
| 41 | import * as ProviderHostLive from "../ProviderHostLive.ts"; | 41 | import * as ProviderHostLive from "../ProviderHostLive.ts"; |
| 42 | 42 | ||
| ... | @@ -214,7 +214,7 @@ it.layer(layerTest)("CodexDriver", (it) => { | ... | @@ -214,7 +214,7 @@ it.layer(layerTest)("CodexDriver", (it) => { |
| 214 | threadId, | 214 | threadId, |
| 215 | providerSessionId: ProviderSessionId.make("managed-account-session"), | 215 | providerSessionId: ProviderSessionId.make("managed-account-session"), |
| 216 | modelSelection: { instanceId, model: "gpt-5.4" }, | 216 | modelSelection: { instanceId, model: "gpt-5.4" }, |
| 217 | runtimePolicy: ProviderAdapterV2RuntimePolicy.make({ | 217 | runtimePolicy: ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({ |
| 218 | runtimeMode: "full-access", | 218 | runtimeMode: "full-access", |
| 219 | interactionMode: "default", | 219 | interactionMode: "default", |
| 220 | cwd: serverConfig.stateDir, | 220 | cwd: serverConfig.stateDir, |
apps/server/src/provider/Drivers/CodexDriver.ts+4-5| ... | @@ -31,10 +31,10 @@ import { HttpClient } from "effect/http"; | ... | @@ -31,10 +31,10 @@ import { HttpClient } from "effect/http"; |
| 31 | import { ChildProcessSpawner } from "effect/process"; | 31 | import { ChildProcessSpawner } from "effect/process"; |
| 32 | 32 | ||
| 33 | import { makeCodexTextGeneration } from "../../textGeneration/CodexTextGeneration.ts"; | 33 | import { makeCodexTextGeneration } from "../../textGeneration/CodexTextGeneration.ts"; |
| 34 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 34 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 35 | import * as ServerConfig from "../../config.ts"; | 35 | import * as ServerConfig from "../../config.ts"; |
| 36 | import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion"; | 36 | import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion"; |
| 37 | import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; | 37 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 38 | import { | 38 | import { |
| 39 | createCodexAdapterV2, | 39 | createCodexAdapterV2, |
| 40 | type CodexAdapterV2DriverEnv, | 40 | type CodexAdapterV2DriverEnv, |
| ... | @@ -109,7 +109,7 @@ function makeCodexMaintenanceResolver(sharedHomePath: string) { | ... | @@ -109,7 +109,7 @@ function makeCodexMaintenanceResolver(sharedHomePath: string) { |
| 109 | */ | 109 | */ |
| 110 | export type CodexDriverEnv = | 110 | export type CodexDriverEnv = |
| 111 | | CodexAdapterV2DriverEnv | 111 | | CodexAdapterV2DriverEnv |
| 112 | | ProviderHost | 112 | | ProviderHost.ProviderHost |
| 113 | | ChildProcessSpawner.ChildProcessSpawner | 113 | | ChildProcessSpawner.ChildProcessSpawner |
| 114 | | ResetCreditCoordinator.ResetCreditCoordinator | 114 | | ResetCreditCoordinator.ResetCreditCoordinator |
| 115 | | Crypto.Crypto | 115 | | Crypto.Crypto |
| ... | @@ -147,7 +147,6 @@ export const CodexDriver: ProviderDriver<CodexSettings, CodexDriverEnv> = { | ... | @@ -147,7 +147,6 @@ export const CodexDriver: ProviderDriver<CodexSettings, CodexDriverEnv> = { |
| 147 | const fileSystem = yield* FileSystem.FileSystem; | 147 | const fileSystem = yield* FileSystem.FileSystem; |
| 148 | const pathService = yield* Path.Path; | 148 | const pathService = yield* Path.Path; |
| 149 | const httpClient = yield* HttpClient.HttpClient; | 149 | const httpClient = yield* HttpClient.HttpClient; |
| 150 | const host = yield* ProviderHost; | ||
| 151 | const modelCatalog = yield* ModelCatalog.ModelCatalog; | 150 | const modelCatalog = yield* ModelCatalog.ModelCatalog; |
| 152 | const currentCatalog = modelCatalog.current(DRIVER_KIND); | 151 | const currentCatalog = modelCatalog.current(DRIVER_KIND); |
| 153 | const processEnv = mergeProviderInstanceEnvironment(environment); | 152 | const processEnv = mergeProviderInstanceEnvironment(environment); |
| ... | @@ -231,7 +230,7 @@ export const CodexDriver: ProviderDriver<CodexSettings, CodexDriverEnv> = { | ... | @@ -231,7 +230,7 @@ export const CodexDriver: ProviderDriver<CodexSettings, CodexDriverEnv> = { |
| 231 | ), | 230 | ), |
| 232 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), | 231 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 233 | ); | 232 | ); |
| 234 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 233 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 235 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<CodexSettings>>({ | 234 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<CodexSettings>>({ |
| 236 | resolveMaintenance, | 235 | resolveMaintenance, |
| 237 | getSettings: snapshotSettings.getSettings, | 236 | getSettings: snapshotSettings.getSettings, |
apps/server/src/provider/Drivers/CodexManagedProvider.ts+2-2| ... | @@ -4,7 +4,7 @@ import * as Stream from "effect/Stream"; | ... | @@ -4,7 +4,7 @@ import * as Stream from "effect/Stream"; |
| 4 | import * as Option from "effect/Option"; | 4 | import * as Option from "effect/Option"; |
| 5 | import { ChildProcessSpawner } from "effect/process"; | 5 | import { ChildProcessSpawner } from "effect/process"; |
| 6 | import { makeCodexTextGeneration } from "../../textGeneration/CodexTextGeneration.ts"; | 6 | import { makeCodexTextGeneration } from "../../textGeneration/CodexTextGeneration.ts"; |
| 7 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 7 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 8 | import { chatGptModels } from "../CodexChatGptModels.ts"; | 8 | import { chatGptModels } from "../CodexChatGptModels.ts"; |
| 9 | import { makeCodexManagedRuntime } from "../CodexManagedRuntime.ts"; | 9 | import { makeCodexManagedRuntime } from "../CodexManagedRuntime.ts"; |
| 10 | import { ProviderDriverError } from "../Errors.ts"; | 10 | import { ProviderDriverError } from "../Errors.ts"; |
| ... | @@ -31,7 +31,7 @@ export const makeManagedCodexProvider = Effect.fn("makeManagedCodexProvider")(fu | ... | @@ -31,7 +31,7 @@ export const makeManagedCodexProvider = Effect.fn("makeManagedCodexProvider")(fu |
| 31 | const { instanceId, enabled, displayName, accentColor, config } = input; | 31 | const { instanceId, enabled, displayName, accentColor, config } = input; |
| 32 | const http = yield* HttpClient.HttpClient; | 32 | const http = yield* HttpClient.HttpClient; |
| 33 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; | 33 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; |
| 34 | const host = yield* ProviderHost; | 34 | const host = yield* ProviderHost.ProviderHost; |
| 35 | const runtime = yield* makeCodexManagedRuntime({ | 35 | const runtime = yield* makeCodexManagedRuntime({ |
| 36 | instanceId, | 36 | instanceId, |
| 37 | enabled, | 37 | enabled, |
apps/server/src/provider/EventNdjsonLogger.ts+13-11| ... | @@ -9,7 +9,7 @@ import * as NodeFS from "node:fs"; | ... | @@ -9,7 +9,7 @@ import * as NodeFS from "node:fs"; |
| 9 | import * as NodePath from "node:path"; | 9 | import * as NodePath from "node:path"; |
| 10 | 10 | ||
| 11 | import type { ThreadId } from "@t3tools/contracts"; | 11 | import type { ThreadId } from "@t3tools/contracts"; |
| 12 | import type { EventNdjsonLogger } from "@t3tools/provider-core/server/ProviderEventLoggers"; | 12 | import type * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 13 | import { RotatingFileSink } from "@t3tools/shared/logging"; | 13 | import { RotatingFileSink } from "@t3tools/shared/logging"; |
| 14 | import { errorTag } from "@t3tools/shared/observability"; | 14 | import { errorTag } from "@t3tools/shared/observability"; |
| 15 | import * as Clock from "effect/Clock"; | 15 | import * as Clock from "effect/Clock"; |
| ... | @@ -21,7 +21,7 @@ import * as Scope from "effect/Scope"; | ... | @@ -21,7 +21,7 @@ import * as Scope from "effect/Scope"; |
| 21 | import * as SynchronizedRef from "effect/SynchronizedRef"; | 21 | import * as SynchronizedRef from "effect/SynchronizedRef"; |
| 22 | 22 | ||
| 23 | import { toSafeThreadAttachmentSegment } from "../attachmentStore.ts"; | 23 | import { toSafeThreadAttachmentSegment } from "../attachmentStore.ts"; |
| 24 | import type { ResourceAttribution } from "../resourceTelemetry/ResourceAttribution.ts"; | 24 | import type * as ResourceAttribution from "../resourceTelemetry/ResourceAttribution.ts"; |
| 25 | 25 | ||
| 26 | const MEBIBYTE = 1024 * 1024; | 26 | const MEBIBYTE = 1024 * 1024; |
| 27 | const DAY_MS = 24 * 60 * 60 * 1_000; | 27 | const DAY_MS = 24 * 60 * 60 * 1_000; |
| ... | @@ -64,11 +64,9 @@ const transientAcpUpdates = new Set(["agent_message_chunk", "agent_thought_chunk | ... | @@ -64,11 +64,9 @@ const transientAcpUpdates = new Set(["agent_message_chunk", "agent_thought_chunk |
| 64 | 64 | ||
| 65 | export type EventNdjsonStream = "native" | "canonical" | "orchestration"; | 65 | export type EventNdjsonStream = "native" | "canonical" | "orchestration"; |
| 66 | 66 | ||
| 67 | export type { EventNdjsonLogger }; | ||
| 68 | |||
| 69 | export interface EventNdjsonLogStore { | 67 | export interface EventNdjsonLogStore { |
| 70 | readonly filePath: string; | 68 | readonly filePath: string; |
| 71 | readonly logger: (stream: EventNdjsonStream) => EventNdjsonLogger; | 69 | readonly logger: (stream: EventNdjsonStream) => ProviderEventLoggers.EventNdjsonLogger; |
| 72 | readonly close: () => Effect.Effect<void>; | 70 | readonly close: () => Effect.Effect<void>; |
| 73 | } | 71 | } |
| 74 | 72 | ||
| ... | @@ -81,7 +79,7 @@ export interface EventNdjsonLogStoreOptions { | ... | @@ -81,7 +79,7 @@ export interface EventNdjsonLogStoreOptions { |
| 81 | readonly retentionCheckIntervalMs?: number; | 79 | readonly retentionCheckIntervalMs?: number; |
| 82 | readonly maxBufferedBytes?: number; | 80 | readonly maxBufferedBytes?: number; |
| 83 | readonly maxBufferedRecords?: number; | 81 | readonly maxBufferedRecords?: number; |
| 84 | readonly attribution?: ResourceAttribution["Service"]; | 82 | readonly attribution?: ResourceAttribution.ResourceAttribution["Service"]; |
| 85 | } | 83 | } |
| 86 | 84 | ||
| 87 | export interface EventNdjsonLoggerOptions extends EventNdjsonLogStoreOptions { | 85 | export interface EventNdjsonLoggerOptions extends EventNdjsonLogStoreOptions { |
| ... | @@ -127,7 +125,7 @@ interface ResolvedOptions { | ... | @@ -127,7 +125,7 @@ interface ResolvedOptions { |
| 127 | readonly retentionCheckIntervalMs: number; | 125 | readonly retentionCheckIntervalMs: number; |
| 128 | readonly maxBufferedBytes: number; | 126 | readonly maxBufferedBytes: number; |
| 129 | readonly maxBufferedRecords: number; | 127 | readonly maxBufferedRecords: number; |
| 130 | readonly attribution: ResourceAttribution["Service"] | undefined; | 128 | readonly attribution: ResourceAttribution.ResourceAttribution["Service"] | undefined; |
| 131 | } | 129 | } |
| 132 | 130 | ||
| 133 | export interface PendingRecord { | 131 | export interface PendingRecord { |
| ... | @@ -731,8 +729,8 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( | ... | @@ -731,8 +729,8 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( |
| 731 | yield* Scope.close(timerScope, Exit.void); | 729 | yield* Scope.close(timerScope, Exit.void); |
| 732 | }); | 730 | }); |
| 733 | 731 | ||
| 734 | const loggerViews = new Map<EventNdjsonStream, EventNdjsonLogger>(); | 732 | const loggerViews = new Map<EventNdjsonStream, ProviderEventLoggers.EventNdjsonLogger>(); |
| 735 | const logger = (stream: EventNdjsonStream): EventNdjsonLogger => { | 733 | const logger = (stream: EventNdjsonStream): ProviderEventLoggers.EventNdjsonLogger => { |
| 736 | const existing = loggerViews.get(stream); | 734 | const existing = loggerViews.get(stream); |
| 737 | if (existing) return existing; | 735 | if (existing) return existing; |
| 738 | 736 | ||
| ... | @@ -778,7 +776,11 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( | ... | @@ -778,7 +776,11 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( |
| 778 | } | 776 | } |
| 779 | }); | 777 | }); |
| 780 | 778 | ||
| 781 | const view = { filePath, write, close: () => Effect.void } satisfies EventNdjsonLogger; | 779 | const view = { |
| 780 | filePath, | ||
| 781 | write, | ||
| 782 | close: () => Effect.void, | ||
| 783 | } satisfies ProviderEventLoggers.EventNdjsonLogger; | ||
| 782 | loggerViews.set(stream, view); | 784 | loggerViews.set(stream, view); |
| 783 | return view; | 785 | return view; |
| 784 | }; | 786 | }; |
| ... | @@ -789,7 +791,7 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( | ... | @@ -789,7 +791,7 @@ export const makeEventNdjsonLogStore = Effect.fnUntraced(function* ( |
| 789 | export const makeEventNdjsonLogger = Effect.fnUntraced(function* ( | 791 | export const makeEventNdjsonLogger = Effect.fnUntraced(function* ( |
| 790 | filePath: string, | 792 | filePath: string, |
| 791 | options: EventNdjsonLoggerOptions, | 793 | options: EventNdjsonLoggerOptions, |
| 792 | ): Effect.fn.Return<EventNdjsonLogger | undefined> { | 794 | ): Effect.fn.Return<ProviderEventLoggers.EventNdjsonLogger | undefined> { |
| 793 | const store = yield* makeEventNdjsonLogStore(filePath, options).pipe( | 795 | const store = yield* makeEventNdjsonLogStore(filePath, options).pipe( |
| 794 | Effect.catch((error) => | 796 | Effect.catch((error) => |
| 795 | logWarning(error.message, { error }).pipe( | 797 | logWarning(error.message, { error }).pipe( |
apps/server/src/provider/ProviderEventLoggers.ts deleted-71| ... | @@ -1,71 +0,0 @@ | ||
| 1 | /** | ||
| 2 | * ProviderEventLoggers — single observability service that owns the shared | ||
| 3 | * provider event log store and exposes its two runtime views: | ||
| 4 | * | ||
| 5 | * - `native` — provider-protocol events as the SDK emits them, written | ||
| 6 | * from inside each `<X>Adapter` factory. | ||
| 7 | * - `canonical` — runtime events after `ProviderService` has normalized | ||
| 8 | * them onto `ProviderRuntimeEvent`. | ||
| 9 | * | ||
| 10 | * Why a service tag and not constructor options? | ||
| 11 | * | ||
| 12 | * - Adapters are now constructed *inside* drivers (`<X>Driver.create()`), | ||
| 13 | * not at the boot Layer. There is no longer a single `make<X>AdapterLive(options)` | ||
| 14 | * call site where we can hand an `EventNdjsonLogger` in by hand. | ||
| 15 | * - Multiple driver instances per kind (`codex_personal`, `codex_work`) | ||
| 16 | * must share one underlying log store — opening N writers against the | ||
| 17 | * same rotating file would race the rotation logic. Owning the loggers on | ||
| 18 | * a single tag keeps that invariant intact. | ||
| 19 | * - Tests can swap one (or both) loggers with in-memory recorders by | ||
| 20 | * `Layer.succeed(ProviderEventLoggers, { native, canonical })` instead of | ||
| 21 | * juggling per-Layer option threading. | ||
| 22 | * | ||
| 23 | * Both fields are optional because observability must not prevent startup. | ||
| 24 | * | ||
| 25 | * @module provider/ProviderEventLoggers | ||
| 26 | */ | ||
| 27 | import * as Effect from "effect/Effect"; | ||
| 28 | import * as Layer from "effect/Layer"; | ||
| 29 | |||
| 30 | import * as ServerConfig from "../config.ts"; | ||
| 31 | import * as ResourceAttribution from "../resourceTelemetry/ResourceAttribution.ts"; | ||
| 32 | import { | ||
| 33 | NoOpProviderEventLoggers, | ||
| 34 | ProviderEventLoggers, | ||
| 35 | } from "@t3tools/provider-core/server/ProviderEventLoggers"; | ||
| 36 | import * as EventNdjsonLogger from "./EventNdjsonLogger.ts"; | ||
| 37 | |||
| 38 | export { NoOpProviderEventLoggers, ProviderEventLoggers }; | ||
| 39 | |||
| 40 | /** | ||
| 41 | * Builds both stream views over one shared store. Setup failures are logged | ||
| 42 | * and downgraded to the no-op service so diagnostics never block startup. | ||
| 43 | * | ||
| 44 | * @public Service construction is part of the canonical Effect module API. | ||
| 45 | */ | ||
| 46 | export const make = Effect.gen(function* () { | ||
| 47 | const { providerEventLogPath } = yield* ServerConfig.ServerConfig; | ||
| 48 | const attribution = yield* ResourceAttribution.ResourceAttribution; | ||
| 49 | const store = yield* EventNdjsonLogger.makeEventNdjsonLogStore(providerEventLogPath, { | ||
| 50 | attribution, | ||
| 51 | }).pipe( | ||
| 52 | Effect.catch((error) => | ||
| 53 | Effect.logWarning(error.message, { error }).pipe( | ||
| 54 | Effect.annotateLogs({ scope: "provider-observability" }), | ||
| 55 | Effect.as<EventNdjsonLogger.EventNdjsonLogStore | undefined>(undefined), | ||
| 56 | ), | ||
| 57 | ), | ||
| 58 | ); | ||
| 59 | |||
| 60 | if (!store) { | ||
| 61 | return ProviderEventLoggers.of(NoOpProviderEventLoggers); | ||
| 62 | } | ||
| 63 | |||
| 64 | yield* Effect.addFinalizer(() => store.close()); | ||
| 65 | return ProviderEventLoggers.of({ | ||
| 66 | native: store.logger("native"), | ||
| 67 | canonical: store.logger("canonical"), | ||
| 68 | }); | ||
| 69 | }); | ||
| 70 | |||
| 71 | export const layer = Layer.effect(ProviderEventLoggers, make); | ||
apps/server/src/provider/ProviderHostLive.ts+4-4| ... | @@ -1,10 +1,10 @@ | ... | @@ -1,10 +1,10 @@ |
| 1 | /** | 1 | /** |
| 2 | * The server's implementation of `ProviderHost`, the only server surface | 2 | * The server's implementation of `ProviderHost.ProviderHost`, the only server surface |
| 3 | * provider drivers and adapters may use. | 3 | * provider drivers and adapters may use. |
| 4 | * | 4 | * |
| 5 | * @module provider/ProviderHostLive | 5 | * @module provider/ProviderHostLive |
| 6 | */ | 6 | */ |
| 7 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 7 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 8 | import { ProviderCredentialError } from "@t3tools/provider-core/server/errors"; | 8 | import { ProviderCredentialError } from "@t3tools/provider-core/server/errors"; |
| 9 | import * as Crypto from "effect/Crypto"; | 9 | import * as Crypto from "effect/Crypto"; |
| 10 | import * as Effect from "effect/Effect"; | 10 | import * as Effect from "effect/Effect"; |
| ... | @@ -18,14 +18,14 @@ import * as ServerSettings from "../serverSettings.ts"; | ... | @@ -18,14 +18,14 @@ import * as ServerSettings from "../serverSettings.ts"; |
| 18 | import * as ProviderCredentialStore from "./ProviderCredentialStore.ts"; | 18 | import * as ProviderCredentialStore from "./ProviderCredentialStore.ts"; |
| 19 | 19 | ||
| 20 | export const layer = Layer.effect( | 20 | export const layer = Layer.effect( |
| 21 | ProviderHost, | 21 | ProviderHost.ProviderHost, |
| 22 | Effect.gen(function* () { | 22 | Effect.gen(function* () { |
| 23 | const config = yield* ServerConfig.ServerConfig; | 23 | const config = yield* ServerConfig.ServerConfig; |
| 24 | const serverSettings = yield* ServerSettings.ServerSettingsService; | 24 | const serverSettings = yield* ServerSettings.ServerSettingsService; |
| 25 | const backgroundPolicy = yield* BackgroundPolicy.BackgroundPolicy; | 25 | const backgroundPolicy = yield* BackgroundPolicy.BackgroundPolicy; |
| 26 | const secrets = yield* ServerSecretStore.ServerSecretStore; | 26 | const secrets = yield* ServerSecretStore.ServerSecretStore; |
| 27 | const crypto = yield* Crypto.Crypto; | 27 | const crypto = yield* Crypto.Crypto; |
| 28 | return ProviderHost.of({ | 28 | return ProviderHost.ProviderHost.of({ |
| 29 | paths: { | 29 | paths: { |
| 30 | cwd: config.cwd, | 30 | cwd: config.cwd, |
| 31 | baseDir: config.baseDir, | 31 | baseDir: config.baseDir, |
apps/server/src/provider/ProviderInstanceRegistry.test.ts+1-1| ... | @@ -61,7 +61,7 @@ import * as ModelManifest from "./ModelManifest.ts"; | ... | @@ -61,7 +61,7 @@ import * as ModelManifest from "./ModelManifest.ts"; |
| 61 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 61 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 62 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 62 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 63 | import * as ResetCreditCoordinator from "./resetCreditCoordinator.ts"; | 63 | import * as ResetCreditCoordinator from "./resetCreditCoordinator.ts"; |
| 64 | import * as ProviderEventLoggers from "./ProviderEventLoggers.ts"; | 64 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 65 | import { makeProviderInstanceRegistry } from "./ProviderInstanceRegistry.ts"; | 65 | import { makeProviderInstanceRegistry } from "./ProviderInstanceRegistry.ts"; |
| 66 | import * as ProviderOrchestrationAdapterInfrastructure from "./ProviderOrchestrationAdapterInfrastructure.ts"; | 66 | import * as ProviderOrchestrationAdapterInfrastructure from "./ProviderOrchestrationAdapterInfrastructure.ts"; |
| 67 | import * as ProviderHostLive from "./ProviderHostLive.ts"; | 67 | import * as ProviderHostLive from "./ProviderHostLive.ts"; |
apps/server/src/provider/ProviderInstanceRegistryHydration.ts+3-3| ... | @@ -40,7 +40,7 @@ import * as ProviderInstanceRegistryMutator from "./ProviderInstanceRegistryMuta | ... | @@ -40,7 +40,7 @@ import * as ProviderInstanceRegistryMutator from "./ProviderInstanceRegistryMuta |
| 40 | import * as ProviderOrchestrationAdapterInfrastructure from "./ProviderOrchestrationAdapterInfrastructure.ts"; | 40 | import * as ProviderOrchestrationAdapterInfrastructure from "./ProviderOrchestrationAdapterInfrastructure.ts"; |
| 41 | import * as AcpRegistrySupport from "@t3tools/provider-acp-registry/server/AcpRegistrySupport"; | 41 | import * as AcpRegistrySupport from "@t3tools/provider-acp-registry/server/AcpRegistrySupport"; |
| 42 | import * as ProviderHostLive from "./ProviderHostLive.ts"; | 42 | import * as ProviderHostLive from "./ProviderHostLive.ts"; |
| 43 | import type { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 43 | import type * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 44 | import type * as BackgroundPolicy from "../background/BackgroundPolicy.ts"; | 44 | import type * as BackgroundPolicy from "../background/BackgroundPolicy.ts"; |
| 45 | import type * as ServerConfig from "../config.ts"; | 45 | import type * as ServerConfig from "../config.ts"; |
| 46 | 46 | ||
| ... | @@ -49,10 +49,10 @@ type ProviderInstanceRegistryHydrationEnv = | ... | @@ -49,10 +49,10 @@ type ProviderInstanceRegistryHydrationEnv = |
| 49 | BuiltInDriversEnv, | 49 | BuiltInDriversEnv, |
| 50 | | ProviderOrchestrationAdapterInfrastructure.ProviderOrchestrationAdapterInfrastructure | 50 | | ProviderOrchestrationAdapterInfrastructure.ProviderOrchestrationAdapterInfrastructure |
| 51 | | AcpRegistrySupport.AcpRegistryCatalog | 51 | | AcpRegistrySupport.AcpRegistryCatalog |
| 52 | | ProviderHost | 52 | | ProviderHost.ProviderHost |
| 53 | > | 53 | > |
| 54 | | Settings.ServerSettingsService | 54 | | Settings.ServerSettingsService |
| 55 | // Requirements of the `ProviderHost` the drivers receive. | 55 | // Requirements of the `ProviderHost.ProviderHost` the drivers receive. |
| 56 | | BackgroundPolicy.BackgroundPolicy | 56 | | BackgroundPolicy.BackgroundPolicy |
| 57 | | ServerConfig.ServerConfig; | 57 | | ServerConfig.ServerConfig; |
| 58 | 58 |
apps/server/src/provider/ProviderOrchestrationAdapterInfrastructure.ts+1-1| ... | @@ -4,7 +4,7 @@ import * as ClaudeAdapterV2 from "../orchestration-v2/Adapters/ClaudeAdapterV2.t | ... | @@ -4,7 +4,7 @@ import * as ClaudeAdapterV2 from "../orchestration-v2/Adapters/ClaudeAdapterV2.t |
| 4 | import * as CodexAdapterV2 from "../orchestration-v2/Adapters/CodexAdapterV2.ts"; | 4 | import * as CodexAdapterV2 from "../orchestration-v2/Adapters/CodexAdapterV2.ts"; |
| 5 | import * as CursorAgentSdk from "@t3tools/provider-cursor/server/CursorAgentSdk"; | 5 | import * as CursorAgentSdk from "@t3tools/provider-cursor/server/CursorAgentSdk"; |
| 6 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 6 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 7 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 7 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 8 | 8 | ||
| 9 | export type ProviderOrchestrationAdapterInfrastructure = | 9 | export type ProviderOrchestrationAdapterInfrastructure = |
| 10 | | ClaudeAdapterV2.ClaudeAgentSdkQueryRunner | 10 | | ClaudeAdapterV2.ClaudeAgentSdkQueryRunner |
apps/server/src/provider/ProviderRegistry.test.ts+1-1| ... | @@ -47,7 +47,7 @@ import { applyProviderCompatibility } from "./providerCompatibility.ts"; | ... | @@ -47,7 +47,7 @@ import { applyProviderCompatibility } from "./providerCompatibility.ts"; |
| 47 | import * as ResetCreditCoordinator from "./resetCreditCoordinator.ts"; | 47 | import * as ResetCreditCoordinator from "./resetCreditCoordinator.ts"; |
| 48 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 48 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 49 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 49 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 50 | import * as ProviderEventLoggers from "./ProviderEventLoggers.ts"; | 50 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 51 | import * as ProviderInstanceRegistryHydration from "./ProviderInstanceRegistryHydration.ts"; | 51 | import * as ProviderInstanceRegistryHydration from "./ProviderInstanceRegistryHydration.ts"; |
| 52 | import * as ServerConfig from "../config.ts"; | 52 | import * as ServerConfig from "../config.ts"; |
| 53 | import * as ServerSettingsModule from "../serverSettings.ts"; | 53 | import * as ServerSettingsModule from "../serverSettings.ts"; |
apps/server/src/server.ts+29-7| ... | @@ -1,3 +1,4 @@ | ... | @@ -1,3 +1,4 @@ |
| 1 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; | ||
| 1 | import type { RelayManagedEndpointRuntimeConfig } from "@t3tools/contracts/relay"; | 2 | import type { RelayManagedEndpointRuntimeConfig } from "@t3tools/contracts/relay"; |
| 2 | import * as Clock from "effect/Clock"; | 3 | import * as Clock from "effect/Clock"; |
| 3 | import * as Random from "effect/Random"; | 4 | import * as Random from "effect/Random"; |
| ... | @@ -42,7 +43,7 @@ import * as AnalyticsService from "./telemetry/AnalyticsService.ts"; | ... | @@ -42,7 +43,7 @@ import * as AnalyticsService from "./telemetry/AnalyticsService.ts"; |
| 42 | import * as ProviderEventIngestor from "./orchestration-v2/ProviderEventIngestor.ts"; | 43 | import * as ProviderEventIngestor from "./orchestration-v2/ProviderEventIngestor.ts"; |
| 43 | import * as ModelManifest from "./provider/ModelManifest.ts"; | 44 | import * as ModelManifest from "./provider/ModelManifest.ts"; |
| 44 | import * as ResetCreditCoordinator from "./provider/resetCreditCoordinator.ts"; | 45 | import * as ResetCreditCoordinator from "./provider/resetCreditCoordinator.ts"; |
| 45 | import * as ProviderEventLoggers from "./provider/ProviderEventLoggers.ts"; | 46 | import * as EventNdjsonLogger from "./provider/EventNdjsonLogger.ts"; |
| 46 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; | 47 | import * as OpenCodeRuntime from "@t3tools/provider-opencode/server/OpenCodeRuntime"; |
| 47 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; | 48 | import * as OpenCodeServerLedger from "@t3tools/provider-opencode/server/OpenCodeServerLedger"; |
| 48 | import * as ProviderHostLive from "./provider/ProviderHostLive.ts"; | 49 | import * as ProviderHostLive from "./provider/ProviderHostLive.ts"; |
| ... | @@ -193,6 +194,30 @@ const layerApplicationObservability = EventLoopMonitor.layer.pipe( | ... | @@ -193,6 +194,30 @@ const layerApplicationObservability = EventLoopMonitor.layer.pipe( |
| 193 | Layer.provideMerge(layerResourceAttribution), | 194 | Layer.provideMerge(layerResourceAttribution), |
| 194 | ); | 195 | ); |
| 195 | 196 | ||
| 197 | // One rotating store behind both logger views, so driver instances never race | ||
| 198 | // its rotation. Diagnostics must not block startup: a store that cannot open | ||
| 199 | // degrades to the no-op loggers. | ||
| 200 | const layerProviderEventLoggers = Layer.effect( | ||
| 201 | ProviderEventLoggers.ProviderEventLoggers, | ||
| 202 | Effect.gen(function* () { | ||
| 203 | const { providerEventLogPath } = yield* ServerConfig.ServerConfig; | ||
| 204 | const attribution = yield* ResourceAttribution.ResourceAttribution; | ||
| 205 | const store = yield* EventNdjsonLogger.makeEventNdjsonLogStore(providerEventLogPath, { | ||
| 206 | attribution, | ||
| 207 | }).pipe( | ||
| 208 | Effect.catch((error) => | ||
| 209 | Effect.logWarning(error.message, { error }).pipe( | ||
| 210 | Effect.annotateLogs({ scope: "provider-observability" }), | ||
| 211 | Effect.as(undefined), | ||
| 212 | ), | ||
| 213 | ), | ||
| 214 | ); | ||
| 215 | if (!store) return ProviderEventLoggers.NoOpProviderEventLoggers; | ||
| 216 | yield* Effect.addFinalizer(() => store.close()); | ||
| 217 | return { native: store.logger("native"), canonical: store.logger("canonical") }; | ||
| 218 | }), | ||
| 219 | ); | ||
| 220 | |||
| 196 | const layerPtyAdapter = NodePtyAdapter.layer; | 221 | const layerPtyAdapter = NodePtyAdapter.layer; |
| 197 | 222 | ||
| 198 | const layerServerSettings = ServerSettings.layer.pipe( | 223 | const layerServerSettings = ServerSettings.layer.pipe( |
| ... | @@ -599,17 +624,14 @@ const layerRuntimeCoreDependencies = layerRuntimeCoreDependenciesBase.pipe( | ... | @@ -599,17 +624,14 @@ const layerRuntimeCoreDependencies = layerRuntimeCoreDependenciesBase.pipe( |
| 599 | // Search, prepare, status inspection, and turn launch share one registry | 624 | // Search, prepare, status inspection, and turn launch share one registry |
| 600 | // cache so every client and provider instance sees the same prepared agents. | 625 | // cache so every client and provider instance sees the same prepared agents. |
| 601 | Layer.provideMerge(AcpRegistrySupport.layerFromHost.pipe(Layer.provide(ProviderHostLive.layer))), | 626 | Layer.provideMerge(AcpRegistrySupport.layerFromHost.pipe(Layer.provide(ProviderHostLive.layer))), |
| 602 | // Shared native/canonical NDJSON writers used by both the per-instance | 627 | // Provider event loggers are shared by every driver instance and the |
| 603 | // V2 drivers and the orchestration runtime. Provide resource attribution so | 628 | // orchestration runtime, so they are provided once here. |
| 604 | // the rewritten telemetry pipeline can account for logical NDJSON writes. | ||
| 605 | // Provided once at the runtime level so every consumer sees the same | ||
| 606 | // logger instances. | ||
| 607 | // `ModelManifest.layer` is the model manifest, refreshed from the repo's | 629 | // `ModelManifest.layer` is the model manifest, refreshed from the repo's |
| 608 | // `model-manifest.json` on `main`. Drivers read their entry through the | 630 | // `model-manifest.json` on `main`. Drivers read their entry through the |
| 609 | // `ModelCatalog` port it provides. | 631 | // `ModelCatalog` port it provides. |
| 610 | Layer.provideMerge( | 632 | Layer.provideMerge( |
| 611 | Layer.mergeAll( | 633 | Layer.mergeAll( |
| 612 | ProviderEventLoggers.layer, | 634 | layerProviderEventLoggers, |
| 613 | ModelManifest.layerModelCatalog.pipe(Layer.provideMerge(ModelManifest.layer)), | 635 | ModelManifest.layerModelCatalog.pipe(Layer.provideMerge(ModelManifest.layer)), |
| 614 | ResetCreditCoordinator.layer, | 636 | ResetCreditCoordinator.layer, |
| 615 | ), | 637 | ), |
packages/provider-acp-registry/src/server/auth.ts+1-1| ... | @@ -16,7 +16,7 @@ import { ChildProcessSpawner } from "effect/process"; | ... | @@ -16,7 +16,7 @@ import { ChildProcessSpawner } from "effect/process"; |
| 16 | import type * as AcpSchema from "effect-acp/compat"; | 16 | import type * as AcpSchema from "effect-acp/compat"; |
| 17 | 17 | ||
| 18 | import * as PtyAdapter from "@t3tools/shared/PtyAdapter"; | 18 | import * as PtyAdapter from "@t3tools/shared/PtyAdapter"; |
| 19 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/ProviderAuthFlow"; | 19 | import * as ProviderAuthFlow from "@t3tools/provider-core/server/providerAuthFlow"; |
| 20 | import { normalizeAcpRegistryAuthMethods, normalizeAcpRegistryWebUrl } from "./probe.ts"; | 20 | import { normalizeAcpRegistryAuthMethods, normalizeAcpRegistryWebUrl } from "./probe.ts"; |
| 21 | import * as AcpRegistrySupport from "./AcpRegistrySupport.ts"; | 21 | import * as AcpRegistrySupport from "./AcpRegistrySupport.ts"; |
| 22 | import * as AcpRegistryRuntimeCoordinator from "./AcpRegistryRuntimeCoordinator.ts"; | 22 | import * as AcpRegistryRuntimeCoordinator from "./AcpRegistryRuntimeCoordinator.ts"; |
packages/provider-acp-registry/src/server/driver.ts+4-4| ... | @@ -21,7 +21,7 @@ import * as Schema from "effect/Schema"; | ... | @@ -21,7 +21,7 @@ import * as Schema from "effect/Schema"; |
| 21 | import * as Semaphore from "effect/Semaphore"; | 21 | import * as Semaphore from "effect/Semaphore"; |
| 22 | import { ChildProcessSpawner } from "effect/process"; | 22 | import { ChildProcessSpawner } from "effect/process"; |
| 23 | 23 | ||
| 24 | import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; | 24 | import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost"; |
| 25 | import { AcpRegistryAdapterV2Driver, type AcpRegistryAdapterV2DriverEnv } from "./adapter.ts"; | 25 | import { AcpRegistryAdapterV2Driver, type AcpRegistryAdapterV2DriverEnv } from "./adapter.ts"; |
| 26 | import type { ProviderTextGeneration } from "@t3tools/provider-core/server/textGeneration"; | 26 | import type { ProviderTextGeneration } from "@t3tools/provider-core/server/textGeneration"; |
| 27 | import { ProviderDriverError } from "@t3tools/provider-core/server/errors"; | 27 | import { ProviderDriverError } from "@t3tools/provider-core/server/errors"; |
| ... | @@ -455,7 +455,7 @@ export const checkAcpRegistryProviderReadiness = Effect.fn( | ... | @@ -455,7 +455,7 @@ export const checkAcpRegistryProviderReadiness = Effect.fn( |
| 455 | : snapshot; | 455 | : snapshot; |
| 456 | }); | 456 | }); |
| 457 | 457 | ||
| 458 | export type AcpRegistryDriverEnv = AcpRegistryAdapterV2DriverEnv | ProviderHost; | 458 | export type AcpRegistryDriverEnv = AcpRegistryAdapterV2DriverEnv | ProviderHost.ProviderHost; |
| 459 | 459 | ||
| 460 | /** Canonical provider-instance wrapper for ACP Registry orchestration adapters. */ | 460 | /** Canonical provider-instance wrapper for ACP Registry orchestration adapters. */ |
| 461 | export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryDriverEnv> = { | 461 | export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryDriverEnv> = { |
| ... | @@ -485,7 +485,7 @@ export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryD | ... | @@ -485,7 +485,7 @@ export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryD |
| 485 | const crypto = yield* Crypto.Crypto; | 485 | const crypto = yield* Crypto.Crypto; |
| 486 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; | 486 | const spawner = yield* ChildProcessSpawner.ChildProcessSpawner; |
| 487 | const hostEnvironment = yield* HostProcessEnvironment; | 487 | const hostEnvironment = yield* HostProcessEnvironment; |
| 488 | const host = yield* ProviderHost; | 488 | const host = yield* ProviderHost.ProviderHost; |
| 489 | const continuationIdentity = defaultProviderContinuationIdentity({ | 489 | const continuationIdentity = defaultProviderContinuationIdentity({ |
| 490 | driverKind: DRIVER_KIND, | 490 | driverKind: DRIVER_KIND, |
| 491 | instanceId, | 491 | instanceId, |
| ... | @@ -619,7 +619,7 @@ export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryD | ... | @@ -619,7 +619,7 @@ export const AcpRegistryDriver: ProviderDriver<AcpRegistrySettings, AcpRegistryD |
| 619 | } | 619 | } |
| 620 | return { provider: enriched, generation: cacheState.generation }; | 620 | return { provider: enriched, generation: cacheState.generation }; |
| 621 | }); | 621 | }); |
| 622 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 622 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 623 | const snapshot = yield* makeManagedServerProvider< | 623 | const snapshot = yield* makeManagedServerProvider< |
| 624 | ProviderSnapshotSettings<AcpRegistrySettings> | 624 | ProviderSnapshotSettings<AcpRegistrySettings> |
| 625 | >({ | 625 | >({ |
packages/provider-acp/src/server/adapter.ts+5-4| ... | @@ -95,7 +95,7 @@ import { | ... | @@ -95,7 +95,7 @@ import { |
| 95 | } from "@t3tools/provider-core/server/orchestrationInstructions"; | 95 | } from "@t3tools/provider-core/server/orchestrationInstructions"; |
| 96 | import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions"; | 96 | import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions"; |
| 97 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 97 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 98 | import { type ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | 98 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 99 | import { | 99 | import { |
| 100 | type BackgroundWork, | 100 | type BackgroundWork, |
| 101 | type BackgroundWorkReport, | 101 | type BackgroundWorkReport, |
| ... | @@ -499,7 +499,9 @@ export interface AcpAdapterV2Options { | ... | @@ -499,7 +499,9 @@ export interface AcpAdapterV2Options { |
| 499 | * / history-only behavior for null-activeTurn updates. | 499 | * / history-only behavior for null-activeTurn updates. |
| 500 | */ | 500 | */ |
| 501 | readonly continuationRequests?: { | 501 | readonly continuationRequests?: { |
| 502 | readonly offer: (request: ProviderContinuationRequest) => Effect.Effect<void>; | 502 | readonly offer: ( |
| 503 | request: ProviderContinuationRequests.ProviderContinuationRequest, | ||
| 504 | ) => Effect.Effect<void>; | ||
| 503 | }; | 505 | }; |
| 504 | readonly testHooks?: { | 506 | readonly testHooks?: { |
| 505 | /** | 507 | /** |
| ... | @@ -743,7 +745,7 @@ function nativeThreadId( | ... | @@ -743,7 +745,7 @@ function nativeThreadId( |
| 743 | function makeProviderThread(input: { | 745 | function makeProviderThread(input: { |
| 744 | readonly driver: ProviderDriverKind; | 746 | readonly driver: ProviderDriverKind; |
| 745 | readonly providerInstanceId: ProviderInstanceId; | 747 | readonly providerInstanceId: ProviderInstanceId; |
| 746 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 748 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 747 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; | 749 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; |
| 748 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; | 750 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; |
| 749 | readonly nativeThreadId: string; | 751 | readonly nativeThreadId: string; |
| ... | @@ -2226,7 +2228,6 @@ export const makeAcpAdapterV2 = Effect.fn("makeAcpAdapterV2")(function* ( | ... | @@ -2226,7 +2228,6 @@ export const makeAcpAdapterV2 = Effect.fn("makeAcpAdapterV2")(function* ( |
| 2226 | type: "turn_item.updated", | 2228 | type: "turn_item.updated", |
| 2227 | driver, | 2229 | driver, |
| 2228 | turnItem: makeProviderRetryTurnItem({ | 2230 | turnItem: makeProviderRetryTurnItem({ |
| 2229 | idAllocator, | ||
| 2230 | driver, | 2231 | driver, |
| 2231 | threadId: context.input.threadId, | 2232 | threadId: context.input.threadId, |
| 2232 | runId: context.input.runId, | 2233 | runId: context.input.runId, |
packages/provider-core/package.json+7-7| ... | @@ -23,10 +23,6 @@ | ... | @@ -23,10 +23,6 @@ |
| 23 | "types": "./src/server/collectStreamText.ts", | 23 | "types": "./src/server/collectStreamText.ts", |
| 24 | "import": "./src/server/collectStreamText.ts" | 24 | "import": "./src/server/collectStreamText.ts" |
| 25 | }, | 25 | }, |
| 26 | "./server/continuationRequests": { | ||
| 27 | "types": "./src/server/continuationRequests.ts", | ||
| 28 | "import": "./src/server/continuationRequests.ts" | ||
| 29 | }, | ||
| 30 | "./server/driver": { | 26 | "./server/driver": { |
| 31 | "types": "./src/server/driver.ts", | 27 | "types": "./src/server/driver.ts", |
| 32 | "import": "./src/server/driver.ts" | 28 | "import": "./src/server/driver.ts" |
| ... | @@ -103,9 +99,13 @@ | ... | @@ -103,9 +99,13 @@ |
| 103 | "types": "./src/server/ProviderAdapter.ts", | 99 | "types": "./src/server/ProviderAdapter.ts", |
| 104 | "import": "./src/server/ProviderAdapter.ts" | 100 | "import": "./src/server/ProviderAdapter.ts" |
| 105 | }, | 101 | }, |
| 106 | "./server/ProviderAuthFlow": { | 102 | "./server/providerAuthFlow": { |
| 107 | "types": "./src/server/ProviderAuthFlow.ts", | 103 | "types": "./src/server/providerAuthFlow.ts", |
| 108 | "import": "./src/server/ProviderAuthFlow.ts" | 104 | "import": "./src/server/providerAuthFlow.ts" |
| 105 | }, | ||
| 106 | "./server/ProviderContinuationRequests": { | ||
| 107 | "types": "./src/server/ProviderContinuationRequests.ts", | ||
| 108 | "import": "./src/server/ProviderContinuationRequests.ts" | ||
| 109 | }, | 109 | }, |
| 110 | "./server/ProviderEventLoggers": { | 110 | "./server/ProviderEventLoggers": { |
| 111 | "types": "./src/server/ProviderEventLoggers.ts", | 111 | "types": "./src/server/ProviderEventLoggers.ts", |
packages/provider-core/src/server/IdAllocator.ts+53-55| ... | @@ -67,7 +67,7 @@ export class IdAllocatorV2AllocationError extends Schema.TaggedError<IdAllocator | ... | @@ -67,7 +67,7 @@ export class IdAllocatorV2AllocationError extends Schema.TaggedError<IdAllocator |
| 67 | export const IdAllocatorV2Error = Schema.Union([IdAllocatorV2AllocationError]); | 67 | export const IdAllocatorV2Error = Schema.Union([IdAllocatorV2AllocationError]); |
| 68 | export type IdAllocatorV2Error = typeof IdAllocatorV2Error.Type; | 68 | export type IdAllocatorV2Error = typeof IdAllocatorV2Error.Type; |
| 69 | 69 | ||
| 70 | export interface IdAllocatorV2AllocateShape { | 70 | export interface IdAllocatorV2Allocate { |
| 71 | readonly command: (input: { | 71 | readonly command: (input: { |
| 72 | readonly fixtureName: string; | 72 | readonly fixtureName: string; |
| 73 | readonly commandName: string; | 73 | readonly commandName: string; |
| ... | @@ -126,7 +126,7 @@ export interface IdAllocatorV2AllocateShape { | ... | @@ -126,7 +126,7 @@ export interface IdAllocatorV2AllocateShape { |
| 126 | }) => Effect.Effect<PlanId, IdAllocatorV2Error>; | 126 | }) => Effect.Effect<PlanId, IdAllocatorV2Error>; |
| 127 | } | 127 | } |
| 128 | 128 | ||
| 129 | export interface IdAllocatorV2DeriveShape { | 129 | export interface IdAllocatorV2Derive { |
| 130 | readonly providerSession: (input: { | 130 | readonly providerSession: (input: { |
| 131 | readonly providerInstanceId: ProviderInstanceId; | 131 | readonly providerInstanceId: ProviderInstanceId; |
| 132 | }) => ProviderSessionId; | 132 | }) => ProviderSessionId; |
| ... | @@ -180,14 +180,13 @@ export interface IdAllocatorV2DeriveShape { | ... | @@ -180,14 +180,13 @@ export interface IdAllocatorV2DeriveShape { |
| 180 | readonly approvalTurnItem: (input: { readonly requestId: RuntimeRequestId }) => TurnItemId; | 180 | readonly approvalTurnItem: (input: { readonly requestId: RuntimeRequestId }) => TurnItemId; |
| 181 | } | 181 | } |
| 182 | 182 | ||
| 183 | export interface IdAllocatorV2Shape { | 183 | export class IdAllocatorV2 extends Context.Service< |
| 184 | readonly allocate: IdAllocatorV2AllocateShape; | 184 | IdAllocatorV2, |
| 185 | readonly derive: IdAllocatorV2DeriveShape; | 185 | { |
| 186 | } | 186 | readonly allocate: IdAllocatorV2Allocate; |
| 187 | 187 | readonly derive: IdAllocatorV2Derive; | |
| 188 | export class IdAllocatorV2 extends Context.Service<IdAllocatorV2, IdAllocatorV2Shape>()( | 188 | } |
| 189 | "@t3tools/provider-core/server/IdAllocator/IdAllocatorV2", | 189 | >()("@t3tools/provider-core/server/IdAllocator/IdAllocatorV2") {} |
| 190 | ) {} | ||
| 191 | 190 | ||
| 192 | const encodePart = (part: string | number): string => encodeURIComponent(String(part)); | 191 | const encodePart = (part: string | number): string => encodeURIComponent(String(part)); |
| 193 | 192 | ||
| ... | @@ -252,6 +251,49 @@ const randomId = | ... | @@ -252,6 +251,49 @@ const randomId = |
| 252 | ), | 251 | ), |
| 253 | ); | 252 | ); |
| 254 | 253 | ||
| 254 | /** Deterministic id derivations; pure, so callers that only derive need no allocator. */ | ||
| 255 | export const derive: IdAllocatorV2Derive = { | ||
| 256 | providerSession: (input) => | ||
| 257 | ProviderSessionId.make( | ||
| 258 | joinId("provider-session", "provider-instance", input.providerInstanceId, "shared"), | ||
| 259 | ), | ||
| 260 | delegatedTaskNode: (input) => NodeId.make(joinId("node", "delegated-task", input.commandId)), | ||
| 261 | delegatedTaskThread: (input) => | ||
| 262 | ThreadId.make(joinId("thread", "delegated-task", input.commandId)), | ||
| 263 | delegatedTaskMessage: (input) => | ||
| 264 | MessageId.make(joinId("message", "delegated-task", input.commandId)), | ||
| 265 | delegatedTaskTurnItem: (input) => | ||
| 266 | TurnItemId.make(joinId("turn-item", "delegated-task", input.commandId)), | ||
| 267 | createdThreadTurnItem: (input) => | ||
| 268 | TurnItemId.make(joinId("turn-item", "created-thread", input.commandId)), | ||
| 269 | threadFromProviderThread: deriveThreadFromProviderThread, | ||
| 270 | run: (input) => RunId.make(joinId("run", "thread", input.threadId, "ordinal", input.ordinal)), | ||
| 271 | runAttempt: (input) => | ||
| 272 | RunAttemptId.make(joinId("run-attempt", "run", input.runId, "attempt", input.attemptOrdinal)), | ||
| 273 | rootNode: (input) => NodeId.make(joinId("node", "run", input.runId, "root")), | ||
| 274 | rootNodeAttempt: (input) => | ||
| 275 | NodeId.make(joinId("node", "run", input.runId, "attempt", input.attemptOrdinal, "root")), | ||
| 276 | userTurnItem: (input) => TurnItemId.make(joinId("turn-item", "message", input.messageId)), | ||
| 277 | runSignalTurnItem: (input) => | ||
| 278 | TurnItemId.make(joinId("turn-item", "run", input.runId, "signal", input.signal)), | ||
| 279 | providerThread: deriveProviderThread, | ||
| 280 | providerTurn: (input) => | ||
| 281 | ProviderTurnId.make( | ||
| 282 | joinId("provider-turn", "provider", input.driver, "native-turn", input.nativeTurnId), | ||
| 283 | ), | ||
| 284 | nodeFromProviderItem: (input) => | ||
| 285 | NodeId.make(joinId("node", "provider", input.driver, "native-item", input.nativeItemId)), | ||
| 286 | messageFromProviderItem: (input) => | ||
| 287 | MessageId.make(joinId("message", "provider", input.driver, "native-item", input.nativeItemId)), | ||
| 288 | turnItemFromProviderItem: (input) => | ||
| 289 | TurnItemId.make( | ||
| 290 | joinId("turn-item", "provider", input.driver, "native-item", input.nativeItemId), | ||
| 291 | ), | ||
| 292 | approvalNode: (input) => NodeId.make(joinId("node", "runtime-request", input.requestId)), | ||
| 293 | approvalTurnItem: (input) => | ||
| 294 | TurnItemId.make(joinId("turn-item", "runtime-request", input.requestId)), | ||
| 295 | }; | ||
| 296 | |||
| 255 | export const layer: Layer.Layer<IdAllocatorV2> = Layer.succeed( | 297 | export const layer: Layer.Layer<IdAllocatorV2> = Layer.succeed( |
| 256 | IdAllocatorV2, | 298 | IdAllocatorV2, |
| 257 | IdAllocatorV2.of({ | 299 | IdAllocatorV2.of({ |
| ... | @@ -386,50 +428,6 @@ export const layer: Layer.Layer<IdAllocatorV2> = Layer.succeed( | ... | @@ -386,50 +428,6 @@ export const layer: Layer.Layer<IdAllocatorV2> = Layer.succeed( |
| 386 | make: PlanId.make, | 428 | make: PlanId.make, |
| 387 | })(input), | 429 | })(input), |
| 388 | }, | 430 | }, |
| 389 | derive: { | 431 | derive, |
| 390 | providerSession: (input) => | ||
| 391 | ProviderSessionId.make( | ||
| 392 | joinId("provider-session", "provider-instance", input.providerInstanceId, "shared"), | ||
| 393 | ), | ||
| 394 | delegatedTaskNode: (input) => NodeId.make(joinId("node", "delegated-task", input.commandId)), | ||
| 395 | delegatedTaskThread: (input) => | ||
| 396 | ThreadId.make(joinId("thread", "delegated-task", input.commandId)), | ||
| 397 | delegatedTaskMessage: (input) => | ||
| 398 | MessageId.make(joinId("message", "delegated-task", input.commandId)), | ||
| 399 | delegatedTaskTurnItem: (input) => | ||
| 400 | TurnItemId.make(joinId("turn-item", "delegated-task", input.commandId)), | ||
| 401 | createdThreadTurnItem: (input) => | ||
| 402 | TurnItemId.make(joinId("turn-item", "created-thread", input.commandId)), | ||
| 403 | threadFromProviderThread: deriveThreadFromProviderThread, | ||
| 404 | run: (input) => RunId.make(joinId("run", "thread", input.threadId, "ordinal", input.ordinal)), | ||
| 405 | runAttempt: (input) => | ||
| 406 | RunAttemptId.make( | ||
| 407 | joinId("run-attempt", "run", input.runId, "attempt", input.attemptOrdinal), | ||
| 408 | ), | ||
| 409 | rootNode: (input) => NodeId.make(joinId("node", "run", input.runId, "root")), | ||
| 410 | rootNodeAttempt: (input) => | ||
| 411 | NodeId.make(joinId("node", "run", input.runId, "attempt", input.attemptOrdinal, "root")), | ||
| 412 | userTurnItem: (input) => TurnItemId.make(joinId("turn-item", "message", input.messageId)), | ||
| 413 | runSignalTurnItem: (input) => | ||
| 414 | TurnItemId.make(joinId("turn-item", "run", input.runId, "signal", input.signal)), | ||
| 415 | providerThread: deriveProviderThread, | ||
| 416 | providerTurn: (input) => | ||
| 417 | ProviderTurnId.make( | ||
| 418 | joinId("provider-turn", "provider", input.driver, "native-turn", input.nativeTurnId), | ||
| 419 | ), | ||
| 420 | nodeFromProviderItem: (input) => | ||
| 421 | NodeId.make(joinId("node", "provider", input.driver, "native-item", input.nativeItemId)), | ||
| 422 | messageFromProviderItem: (input) => | ||
| 423 | MessageId.make( | ||
| 424 | joinId("message", "provider", input.driver, "native-item", input.nativeItemId), | ||
| 425 | ), | ||
| 426 | turnItemFromProviderItem: (input) => | ||
| 427 | TurnItemId.make( | ||
| 428 | joinId("turn-item", "provider", input.driver, "native-item", input.nativeItemId), | ||
| 429 | ), | ||
| 430 | approvalNode: (input) => NodeId.make(joinId("node", "runtime-request", input.requestId)), | ||
| 431 | approvalTurnItem: (input) => | ||
| 432 | TurnItemId.make(joinId("turn-item", "runtime-request", input.requestId)), | ||
| 433 | }, | ||
| 434 | }), | 432 | }), |
| 435 | ); | 433 | ); |
packages/provider-core/src/server/ProviderAdapter.ts+17-18| ... | @@ -632,21 +632,20 @@ export interface ProviderAdapterV2SessionRuntime { | ... | @@ -632,21 +632,20 @@ export interface ProviderAdapterV2SessionRuntime { |
| 632 | ) => Effect.Effect<OrchestrationV2ProviderThread, ProviderAdapterV2Error>; | 632 | ) => Effect.Effect<OrchestrationV2ProviderThread, ProviderAdapterV2Error>; |
| 633 | } | 633 | } |
| 634 | 634 | ||
| 635 | export interface ProviderAdapterV2Shape { | 635 | export class ProviderAdapterV2 extends Context.Service< |
| 636 | readonly instanceId: ProviderInstanceId; | 636 | ProviderAdapterV2, |
| 637 | readonly driver: ProviderDriverKind; | 637 | { |
| 638 | readonly getCapabilities: () => Effect.Effect< | 638 | readonly instanceId: ProviderInstanceId; |
| 639 | OrchestrationV2ProviderCapabilities, | 639 | readonly driver: ProviderDriverKind; |
| 640 | ProviderAdapterV2Error | 640 | readonly getCapabilities: () => Effect.Effect< |
| 641 | >; | 641 | OrchestrationV2ProviderCapabilities, |
| 642 | readonly planSelectionTransition: ( | 642 | ProviderAdapterV2Error |
| 643 | input: ProviderSelectionTransitionInput, | 643 | >; |
| 644 | ) => Effect.Effect<ProviderSelectionTransitionPlan, ProviderAdapterV2Error>; | 644 | readonly planSelectionTransition: ( |
| 645 | readonly openSession: ( | 645 | input: ProviderSelectionTransitionInput, |
| 646 | input: ProviderAdapterV2OpenSessionInput, | 646 | ) => Effect.Effect<ProviderSelectionTransitionPlan, ProviderAdapterV2Error>; |
| 647 | ) => Effect.Effect<ProviderAdapterV2SessionRuntime, ProviderAdapterV2Error, Scope.Scope>; | 647 | readonly openSession: ( |
| 648 | } | 648 | input: ProviderAdapterV2OpenSessionInput, |
| 649 | 649 | ) => Effect.Effect<ProviderAdapterV2SessionRuntime, ProviderAdapterV2Error, Scope.Scope>; | |
| 650 | export class ProviderAdapterV2 extends Context.Service<ProviderAdapterV2, ProviderAdapterV2Shape>()( | 650 | } |
| 651 | "@t3tools/provider-core/server/ProviderAdapter/ProviderAdapterV2", | 651 | >()("@t3tools/provider-core/server/ProviderAdapter/ProviderAdapterV2") {} |
| 652 | ) {} |
packages/provider-core/src/server/ProviderAuthFlow.test.ts deleted-559| ... | @@ -1,559 +0,0 @@ | ||
| 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; | ||
| 2 | import { assert, it } from "@effect/vitest"; | ||
| 3 | import { | ||
| 4 | ProviderInstanceId, | ||
| 5 | ProviderSetupError, | ||
| 6 | type ProviderAuthInteraction, | ||
| 7 | type ProviderAuthResponse, | ||
| 8 | type ProviderAuthState, | ||
| 9 | } from "@t3tools/contracts"; | ||
| 10 | import * as Fiber from "effect/Fiber"; | ||
| 11 | import * as Exit from "effect/Exit"; | ||
| 12 | import * as Scope from "effect/Scope"; | ||
| 13 | import * as Deferred from "effect/Deferred"; | ||
| 14 | import * as Effect from "effect/Effect"; | ||
| 15 | import * as Option from "effect/Option"; | ||
| 16 | import * as Stream from "effect/Stream"; | ||
| 17 | import * as TestClock from "effect/testing/TestClock"; | ||
| 18 | |||
| 19 | import * as ProviderAuthFlow from "./ProviderAuthFlow.ts"; | ||
| 20 | |||
| 21 | const instanceId = ProviderInstanceId.make("auth-flow-test"); | ||
| 22 | const method = { id: "browser", name: "Browser", description: null, type: "agent" as const }; | ||
| 23 | |||
| 24 | it.effect("distinguishes pending method discovery from an agent with no sign-in methods", () => | ||
| 25 | Effect.gen(function* () { | ||
| 26 | const discovered = yield* Deferred.make<ReadonlyArray<typeof method>>(); | ||
| 27 | const controller = yield* ProviderAuthFlow.make({ | ||
| 28 | instanceId, | ||
| 29 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 30 | methods: Deferred.await(discovered), | ||
| 31 | authenticate: () => Effect.void, | ||
| 32 | logout: Effect.void, | ||
| 33 | }); | ||
| 34 | const pending = yield* controller | ||
| 35 | .subscribe("owner") | ||
| 36 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 37 | assert.isUndefined(pending.methods); | ||
| 38 | yield* Deferred.succeed(discovered, []); | ||
| 39 | const ready = yield* controller.subscribe("owner").pipe( | ||
| 40 | Stream.filter((state) => state.methods !== undefined), | ||
| 41 | Stream.runHead, | ||
| 42 | Effect.map(Option.getOrThrow), | ||
| 43 | ); | ||
| 44 | assert.deepEqual(ready.methods, []); | ||
| 45 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 46 | ); | ||
| 47 | |||
| 48 | const makeHarness = Effect.gen(function* () { | ||
| 49 | const approved = yield* Deferred.make<void>(); | ||
| 50 | const verified = yield* Deferred.make<void>(); | ||
| 51 | const started = yield* Deferred.make<void>(); | ||
| 52 | let attempts = 0; | ||
| 53 | const controller = yield* ProviderAuthFlow.make({ | ||
| 54 | instanceId, | ||
| 55 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 56 | methods: Effect.succeed([method]), | ||
| 57 | authenticate: (_, context) => | ||
| 58 | Effect.gen(function* () { | ||
| 59 | attempts++; | ||
| 60 | yield* context.setInteraction( | ||
| 61 | { | ||
| 62 | type: "browser", | ||
| 63 | id: "consent", | ||
| 64 | url: "https://example.com/login", | ||
| 65 | requiresConsent: true, | ||
| 66 | }, | ||
| 67 | (response) => | ||
| 68 | response.type === "browser" && response.action === "accept" | ||
| 69 | ? Deferred.succeed(approved, undefined).pipe(Effect.asVoid) | ||
| 70 | : Effect.void, | ||
| 71 | ); | ||
| 72 | yield* Deferred.succeed(started, undefined); | ||
| 73 | yield* Deferred.await(approved); | ||
| 74 | yield* context.verifying; | ||
| 75 | yield* Deferred.await(verified); | ||
| 76 | }), | ||
| 77 | logout: Effect.void, | ||
| 78 | }); | ||
| 79 | const phase = (phase: ProviderAuthState["phase"], owner = "owner") => | ||
| 80 | controller.subscribe(owner).pipe( | ||
| 81 | Stream.filter((state) => state.phase === phase), | ||
| 82 | Stream.runHead, | ||
| 83 | Effect.map(Option.getOrThrow), | ||
| 84 | ); | ||
| 85 | return { controller, phase, started, verified, attempts: () => attempts }; | ||
| 86 | }); | ||
| 87 | |||
| 88 | it.effect("requires owner consent and provider verification before success", () => | ||
| 89 | Effect.gen(function* () { | ||
| 90 | const { controller, phase, started, verified, attempts } = yield* makeHarness; | ||
| 91 | const state = yield* controller.start("owner"); | ||
| 92 | yield* Deferred.await(started); | ||
| 93 | const response = { | ||
| 94 | instanceId, | ||
| 95 | flowId: state.flowId!, | ||
| 96 | interactionId: "consent", | ||
| 97 | response: { type: "browser" as const, action: "accept" as const }, | ||
| 98 | }; | ||
| 99 | const other = yield* phase("waiting", "other"); | ||
| 100 | assert.isNull(other.interaction); | ||
| 101 | assert.isNull(other.flowId); | ||
| 102 | assert.isTrue( | ||
| 103 | (yield* controller.respond!("other", response).pipe(Effect.result))._tag === "Failure", | ||
| 104 | ); | ||
| 105 | assert.isTrue( | ||
| 106 | (yield* controller.respond!("owner", { ...response, interactionId: "stale" }).pipe( | ||
| 107 | Effect.result, | ||
| 108 | ))._tag === "Failure", | ||
| 109 | ); | ||
| 110 | yield* controller.start("owner"); | ||
| 111 | assert.strictEqual(attempts(), 1); | ||
| 112 | yield* controller.respond!("owner", response); | ||
| 113 | yield* phase("verifying"); | ||
| 114 | yield* Deferred.succeed(verified, undefined); | ||
| 115 | assert.strictEqual((yield* phase("succeeded")).phase, "succeeded"); | ||
| 116 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 117 | ); | ||
| 118 | |||
| 119 | it.effect("cancellation rejects late consent and permits another login", () => | ||
| 120 | Effect.gen(function* () { | ||
| 121 | const { controller, started, phase } = yield* makeHarness; | ||
| 122 | const state = yield* controller.start("owner"); | ||
| 123 | yield* Deferred.await(started); | ||
| 124 | yield* controller.cancel("owner", state.flowId!); | ||
| 125 | assert.strictEqual((yield* phase("cancelled")).phase, "cancelled"); | ||
| 126 | assert.isTrue( | ||
| 127 | (yield* controller.respond!("owner", { | ||
| 128 | instanceId, | ||
| 129 | flowId: state.flowId!, | ||
| 130 | interactionId: "consent", | ||
| 131 | response: { type: "browser", action: "accept" }, | ||
| 132 | }).pipe(Effect.result))._tag === "Failure", | ||
| 133 | ); | ||
| 134 | const next = yield* controller.start("other"); | ||
| 135 | assert.notStrictEqual(next.flowId, state.flowId); | ||
| 136 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 137 | ); | ||
| 138 | |||
| 139 | it.effect("expires pending login and rejects its response", () => | ||
| 140 | Effect.gen(function* () { | ||
| 141 | const { controller, started, phase } = yield* makeHarness; | ||
| 142 | const state = yield* controller.start("owner"); | ||
| 143 | yield* Deferred.await(started); | ||
| 144 | yield* TestClock.adjust(300_001); | ||
| 145 | assert.include((yield* phase("failed")).message ?? "", "expired"); | ||
| 146 | assert.isTrue( | ||
| 147 | (yield* controller.respond!("owner", { | ||
| 148 | instanceId, | ||
| 149 | flowId: state.flowId!, | ||
| 150 | interactionId: "consent", | ||
| 151 | response: { type: "browser", action: "accept" }, | ||
| 152 | }).pipe(Effect.result))._tag === "Failure", | ||
| 153 | ); | ||
| 154 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 155 | ); | ||
| 156 | |||
| 157 | it.effect("closes admitted provider processes and blocks new ones while login is pending", () => | ||
| 158 | Effect.gen(function* () { | ||
| 159 | const { controller, started } = yield* makeHarness; | ||
| 160 | let closed = false; | ||
| 161 | yield* controller.withAccess!( | ||
| 162 | Effect.addFinalizer(() => | ||
| 163 | Effect.sync(() => { | ||
| 164 | closed = true; | ||
| 165 | }), | ||
| 166 | ), | ||
| 167 | ); | ||
| 168 | yield* controller.start("owner"); | ||
| 169 | yield* Deferred.await(started); | ||
| 170 | assert.isTrue(closed); | ||
| 171 | assert.isTrue( | ||
| 172 | (yield* controller.withAccess!(Effect.void).pipe(Effect.result))._tag === "Failure", | ||
| 173 | ); | ||
| 174 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 175 | ); | ||
| 176 | |||
| 177 | it.effect("shared credential invalidation closes admitted processes before permitting reuse", () => | ||
| 178 | Effect.gen(function* () { | ||
| 179 | const { controller } = yield* makeHarness; | ||
| 180 | let closed = false; | ||
| 181 | yield* controller.withAccess!( | ||
| 182 | Effect.addFinalizer(() => | ||
| 183 | Effect.sync(() => { | ||
| 184 | closed = true; | ||
| 185 | }), | ||
| 186 | ), | ||
| 187 | ); | ||
| 188 | yield* controller.invalidate!; | ||
| 189 | assert.isTrue(closed); | ||
| 190 | assert.strictEqual(yield* controller.withAccess!(Effect.succeed("new process")), "new process"); | ||
| 191 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 192 | ); | ||
| 193 | |||
| 194 | it.effect.each([ | ||
| 195 | { | ||
| 196 | interaction: { type: "terminal", id: "terminal", output: "Log in" }, | ||
| 197 | response: { type: "terminal", data: "input", size: { cols: 80, rows: 24 } }, | ||
| 198 | }, | ||
| 199 | { | ||
| 200 | interaction: { | ||
| 201 | type: "credentials", | ||
| 202 | id: "credentials", | ||
| 203 | fields: [{ name: "token", label: "Token", secret: true }], | ||
| 204 | }, | ||
| 205 | response: { type: "credentials", values: { token: "private-token" } }, | ||
| 206 | }, | ||
| 207 | ] satisfies ReadonlyArray<{ | ||
| 208 | interaction: ProviderAuthInteraction; | ||
| 209 | response: ProviderAuthResponse; | ||
| 210 | }>)( | ||
| 211 | "keeps $interaction.type responses private and waits for adapter verification", | ||
| 212 | ({ interaction, response }) => | ||
| 213 | Effect.gen(function* () { | ||
| 214 | const received = yield* Deferred.make<ProviderAuthResponse>(); | ||
| 215 | const controller = yield* ProviderAuthFlow.make({ | ||
| 216 | instanceId, | ||
| 217 | credentialBinding: { owner: "t3", key: "binding" }, | ||
| 218 | methods: Effect.succeed([method]), | ||
| 219 | authenticate: (_, context) => | ||
| 220 | Effect.gen(function* () { | ||
| 221 | yield* context.setInteraction(interaction, (response) => | ||
| 222 | Deferred.succeed(received, response).pipe(Effect.asVoid), | ||
| 223 | ); | ||
| 224 | yield* Deferred.await(received); | ||
| 225 | yield* context.verifying; | ||
| 226 | return yield* Effect.never; | ||
| 227 | }), | ||
| 228 | logout: Effect.void, | ||
| 229 | }); | ||
| 230 | const state = yield* controller.start("owner"); | ||
| 231 | const pending = yield* controller.subscribe("owner").pipe( | ||
| 232 | Stream.filter((state) => state.phase === "waiting"), | ||
| 233 | Stream.runHead, | ||
| 234 | Effect.map(Option.getOrThrow), | ||
| 235 | ); | ||
| 236 | assert.deepStrictEqual(pending.interaction, interaction); | ||
| 237 | const hidden = yield* controller | ||
| 238 | .subscribe("other") | ||
| 239 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 240 | assert.isNull(hidden.interaction); | ||
| 241 | yield* controller.respond!("owner", { | ||
| 242 | instanceId, | ||
| 243 | flowId: state.flowId!, | ||
| 244 | interactionId: interaction.id, | ||
| 245 | response, | ||
| 246 | }); | ||
| 247 | assert.deepStrictEqual(yield* Deferred.await(received), response); | ||
| 248 | const verifying = yield* controller.subscribe("owner").pipe( | ||
| 249 | Stream.filter((state) => state.phase === "verifying"), | ||
| 250 | Stream.runHead, | ||
| 251 | Effect.map(Option.getOrThrow), | ||
| 252 | ); | ||
| 253 | assert.isNull(verifying.interaction); | ||
| 254 | assert.notInclude(verifying.message ?? "", "private-token"); | ||
| 255 | yield* controller.cancel("owner", state.flowId!); | ||
| 256 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 257 | ); | ||
| 258 | |||
| 259 | it.effect("shows a device code only to its owner without treating it as authenticated", () => | ||
| 260 | Effect.gen(function* () { | ||
| 261 | const controller = yield* ProviderAuthFlow.make({ | ||
| 262 | instanceId, | ||
| 263 | credentialBinding: { owner: "provider", key: "device" }, | ||
| 264 | methods: Effect.succeed([method]), | ||
| 265 | authenticate: (_, context) => | ||
| 266 | context | ||
| 267 | .setInteraction({ | ||
| 268 | type: "deviceCode", | ||
| 269 | id: "code", | ||
| 270 | url: "https://example.com/device", | ||
| 271 | userCode: "ABCD-EFGH", | ||
| 272 | }) | ||
| 273 | .pipe(Effect.andThen(Effect.never)), | ||
| 274 | logout: Effect.void, | ||
| 275 | }); | ||
| 276 | const start = yield* controller.start("owner"); | ||
| 277 | const waiting = yield* controller.subscribe("owner").pipe( | ||
| 278 | Stream.filter((state) => state.phase === "waiting"), | ||
| 279 | Stream.runHead, | ||
| 280 | Effect.map(Option.getOrThrow), | ||
| 281 | ); | ||
| 282 | assert.strictEqual(waiting.interaction?.type, "deviceCode"); | ||
| 283 | assert.strictEqual(waiting.authorizationUrl, "https://example.com/device"); | ||
| 284 | const other = yield* controller | ||
| 285 | .subscribe("other") | ||
| 286 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 287 | assert.isNull(other.interaction); | ||
| 288 | assert.isNull(other.authorizationUrl); | ||
| 289 | yield* controller.cancel("owner", start.flowId!); | ||
| 290 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 291 | ); | ||
| 292 | |||
| 293 | it.effect.each([ | ||
| 294 | { | ||
| 295 | failure: Effect.fail( | ||
| 296 | new ProviderSetupError({ | ||
| 297 | instanceId, | ||
| 298 | operation: "authenticate", | ||
| 299 | detail: "This account cannot sign in. Choose another account.", | ||
| 300 | }), | ||
| 301 | ), | ||
| 302 | message: "This account cannot sign in. Choose another account.", | ||
| 303 | }, | ||
| 304 | { | ||
| 305 | failure: Effect.die(new Error("private-token in native diagnostics")), | ||
| 306 | message: "Sign-in failed. Start again.", | ||
| 307 | }, | ||
| 308 | ])("publishes only safe authentication failure text %#", ({ failure, message }) => | ||
| 309 | Effect.gen(function* () { | ||
| 310 | const controller = yield* ProviderAuthFlow.make({ | ||
| 311 | instanceId, | ||
| 312 | credentialBinding: { owner: "t3", key: "failure" }, | ||
| 313 | methods: Effect.succeed([method]), | ||
| 314 | authenticate: () => failure, | ||
| 315 | logout: Effect.void, | ||
| 316 | }); | ||
| 317 | yield* controller.start("owner"); | ||
| 318 | const failed = yield* controller.subscribe("owner").pipe( | ||
| 319 | Stream.filter((state) => state.phase === "failed"), | ||
| 320 | Stream.runHead, | ||
| 321 | Effect.map(Option.getOrThrow), | ||
| 322 | ); | ||
| 323 | assert.strictEqual(failed.message, message); | ||
| 324 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 325 | ); | ||
| 326 | |||
| 327 | const makeBlockingResponseHarness = Effect.gen(function* () { | ||
| 328 | const entered = yield* Deferred.make<void>(); | ||
| 329 | const cleanupStarted = yield* Deferred.make<void>(); | ||
| 330 | const cleanupReleased = yield* Deferred.make<void>(); | ||
| 331 | const cleanupFinished = yield* Deferred.make<void>(); | ||
| 332 | const authenticationFinished = yield* Deferred.make<void>(); | ||
| 333 | let responses = 0; | ||
| 334 | const controller = yield* ProviderAuthFlow.make({ | ||
| 335 | instanceId, | ||
| 336 | credentialBinding: { owner: "t3", key: "blocked-response" }, | ||
| 337 | methods: Effect.succeed([method]), | ||
| 338 | authenticate: (_, context) => | ||
| 339 | Effect.gen(function* () { | ||
| 340 | yield* context.setInteraction( | ||
| 341 | { | ||
| 342 | type: "browser", | ||
| 343 | id: "blocked", | ||
| 344 | url: "https://example.com/login", | ||
| 345 | requiresConsent: true, | ||
| 346 | }, | ||
| 347 | () => | ||
| 348 | Effect.gen(function* () { | ||
| 349 | responses++; | ||
| 350 | yield* Deferred.succeed(entered, undefined); | ||
| 351 | return yield* Effect.never; | ||
| 352 | }).pipe( | ||
| 353 | Effect.ensuring( | ||
| 354 | Effect.gen(function* () { | ||
| 355 | yield* Deferred.succeed(cleanupStarted, undefined); | ||
| 356 | yield* Deferred.await(cleanupReleased); | ||
| 357 | yield* Deferred.succeed(cleanupFinished, undefined); | ||
| 358 | }), | ||
| 359 | ), | ||
| 360 | ), | ||
| 361 | ); | ||
| 362 | yield* Deferred.await(authenticationFinished); | ||
| 363 | }), | ||
| 364 | logout: Effect.void, | ||
| 365 | }); | ||
| 366 | const start = yield* controller.start("owner"); | ||
| 367 | yield* controller.subscribe("owner").pipe( | ||
| 368 | Stream.filter((state) => state.phase === "waiting"), | ||
| 369 | Stream.runHead, | ||
| 370 | ); | ||
| 371 | const input = { | ||
| 372 | instanceId, | ||
| 373 | flowId: start.flowId!, | ||
| 374 | interactionId: "blocked", | ||
| 375 | response: { type: "browser" as const, action: "accept" as const }, | ||
| 376 | }; | ||
| 377 | const response = yield* controller.respond!("owner", input).pipe(Effect.exit, Effect.forkChild); | ||
| 378 | yield* Deferred.await(entered); | ||
| 379 | return { | ||
| 380 | controller, | ||
| 381 | input, | ||
| 382 | response, | ||
| 383 | cleanupStarted, | ||
| 384 | cleanupReleased, | ||
| 385 | cleanupFinished, | ||
| 386 | authenticationFinished, | ||
| 387 | responses: () => responses, | ||
| 388 | }; | ||
| 389 | }); | ||
| 390 | |||
| 391 | it.effect.each(["cancel", "logout"] as const)( | ||
| 392 | "%s interrupts and awaits a blocked adapter response before admitting another sign-in", | ||
| 393 | (action) => | ||
| 394 | Effect.gen(function* () { | ||
| 395 | const harness = yield* makeBlockingResponseHarness; | ||
| 396 | const duplicate = yield* Effect.flip(harness.controller.respond!("owner", harness.input)); | ||
| 397 | assert.include(duplicate.detail, "already in progress"); | ||
| 398 | assert.equal(harness.responses(), 1); | ||
| 399 | const stopping = yield* ( | ||
| 400 | action === "cancel" | ||
| 401 | ? harness.controller.cancel("owner", harness.input.flowId) | ||
| 402 | : harness.controller.logout(Effect.void) | ||
| 403 | ).pipe(Effect.forkChild); | ||
| 404 | yield* Deferred.await(harness.cleanupStarted); | ||
| 405 | assert.isTrue(yield* harness.controller.isChangingCredentials!); | ||
| 406 | assert.isUndefined(stopping.pollUnsafe()); | ||
| 407 | const premature = yield* Effect.flip(harness.controller.start("other")); | ||
| 408 | assert.include(premature.detail, "in progress"); | ||
| 409 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 410 | yield* Fiber.join(stopping); | ||
| 411 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 412 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 413 | assert.isFalse(yield* harness.controller.isChangingCredentials!); | ||
| 414 | assert.notEqual((yield* harness.controller.start("other")).flowId, harness.input.flowId); | ||
| 415 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 416 | ); | ||
| 417 | |||
| 418 | it.effect("timeout interrupts and drains a blocked response before publishing failure", () => | ||
| 419 | Effect.gen(function* () { | ||
| 420 | const harness = yield* makeBlockingResponseHarness; | ||
| 421 | yield* TestClock.adjust(300_001); | ||
| 422 | yield* Deferred.await(harness.cleanupStarted); | ||
| 423 | assert.isTrue(yield* harness.controller.isChangingCredentials!); | ||
| 424 | const duringCleanup = yield* harness.controller | ||
| 425 | .subscribe("owner") | ||
| 426 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 427 | assert.notEqual(duringCleanup.phase, "failed"); | ||
| 428 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 429 | const failed = yield* harness.controller.subscribe("owner").pipe( | ||
| 430 | Stream.filter((state) => state.phase === "failed"), | ||
| 431 | Stream.runHead, | ||
| 432 | Effect.map(Option.getOrThrow), | ||
| 433 | ); | ||
| 434 | assert.include(failed.message ?? "", "expired"); | ||
| 435 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 436 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 437 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 438 | ); | ||
| 439 | |||
| 440 | it.effect( | ||
| 441 | "successful authentication drains a still-running response before admitting provider access", | ||
| 442 | () => | ||
| 443 | Effect.gen(function* () { | ||
| 444 | const harness = yield* makeBlockingResponseHarness; | ||
| 445 | yield* Deferred.succeed(harness.authenticationFinished, undefined); | ||
| 446 | yield* Deferred.await(harness.cleanupStarted); | ||
| 447 | const denied = yield* Effect.flip(harness.controller.withAccess!(Effect.void)); | ||
| 448 | assert.include(denied.detail, "changing"); | ||
| 449 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 450 | const succeeded = yield* harness.controller.subscribe("owner").pipe( | ||
| 451 | Stream.filter((state) => state.phase === "succeeded"), | ||
| 452 | Stream.runHead, | ||
| 453 | Effect.map(Option.getOrThrow), | ||
| 454 | ); | ||
| 455 | assert.equal(succeeded.phase, "succeeded"); | ||
| 456 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 457 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 458 | yield* harness.controller.withAccess!(Effect.void); | ||
| 459 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 460 | ); | ||
| 461 | |||
| 462 | it.effect("closing the controller scope interrupts and drains its adapter response", () => | ||
| 463 | Effect.gen(function* () { | ||
| 464 | const scope = yield* Scope.make(); | ||
| 465 | const harness = yield* makeBlockingResponseHarness.pipe( | ||
| 466 | Effect.provideService(Scope.Scope, scope), | ||
| 467 | ); | ||
| 468 | const closing = yield* Scope.close(scope, Exit.void).pipe(Effect.forkChild); | ||
| 469 | yield* Deferred.await(harness.cleanupStarted); | ||
| 470 | assert.isUndefined(closing.pollUnsafe()); | ||
| 471 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 472 | yield* Fiber.join(closing); | ||
| 473 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 474 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 475 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 476 | ); | ||
| 477 | |||
| 478 | it.effect("a failed method refresh keeps the last discovered methods", () => | ||
| 479 | Effect.gen(function* () { | ||
| 480 | let fail = false; | ||
| 481 | const controller = yield* ProviderAuthFlow.make({ | ||
| 482 | instanceId, | ||
| 483 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 484 | methods: Effect.suspend(() => | ||
| 485 | fail | ||
| 486 | ? Effect.fail( | ||
| 487 | new ProviderSetupError({ instanceId, operation: "status", detail: "interrupted" }), | ||
| 488 | ) | ||
| 489 | : Effect.succeed([method]), | ||
| 490 | ), | ||
| 491 | authenticate: () => Effect.void, | ||
| 492 | logout: Effect.void, | ||
| 493 | }); | ||
| 494 | yield* controller.refreshMethods!; | ||
| 495 | fail = true; | ||
| 496 | yield* controller.refreshMethods!; | ||
| 497 | const state = yield* controller | ||
| 498 | .subscribe("owner") | ||
| 499 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 500 | assert.deepEqual(state.methods, [method]); | ||
| 501 | assert.strictEqual(state.message, "interrupted"); | ||
| 502 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 503 | ); | ||
| 504 | |||
| 505 | it.effect("rebuilding a controller leaves sessions it admitted to their owners", () => | ||
| 506 | Effect.gen(function* () { | ||
| 507 | const scope = yield* Scope.make(); | ||
| 508 | const { controller } = yield* makeHarness.pipe(Effect.provideService(Scope.Scope, scope)); | ||
| 509 | let closed = false; | ||
| 510 | yield* controller.withAccess!( | ||
| 511 | Effect.addFinalizer(() => | ||
| 512 | Effect.sync(() => { | ||
| 513 | closed = true; | ||
| 514 | }), | ||
| 515 | ), | ||
| 516 | ); | ||
| 517 | yield* Scope.close(scope, Exit.void); | ||
| 518 | assert.isFalse(closed); | ||
| 519 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 520 | ); | ||
| 521 | |||
| 522 | it.effect("profile import stops owned sessions and gates access until credentials are saved", () => | ||
| 523 | Effect.gen(function* () { | ||
| 524 | const controller = yield* ProviderAuthFlow.make({ | ||
| 525 | instanceId, | ||
| 526 | credentialBinding: { owner: "t3", key: "handoff-binding" }, | ||
| 527 | methods: Effect.succeed([method]), | ||
| 528 | authenticate: () => Effect.void, | ||
| 529 | logout: Effect.void, | ||
| 530 | }); | ||
| 531 | let closed = false; | ||
| 532 | yield* controller.withAccess!( | ||
| 533 | Effect.addFinalizer(() => | ||
| 534 | Effect.sync(() => { | ||
| 535 | closed = true; | ||
| 536 | }), | ||
| 537 | ), | ||
| 538 | ); | ||
| 539 | const writing = yield* Deferred.make<void>(); | ||
| 540 | const release = yield* Deferred.make<void>(); | ||
| 541 | const imported = yield* controller.adoptCredentials!( | ||
| 542 | Deferred.succeed(writing, undefined).pipe(Effect.andThen(Deferred.await(release))), | ||
| 543 | Effect.sync(() => { | ||
| 544 | assert.isTrue(closed); | ||
| 545 | }), | ||
| 546 | ).pipe(Effect.forkChild); | ||
| 547 | yield* Deferred.await(writing); | ||
| 548 | const denied = yield* controller.withAccess!(Effect.succeed("old credential process")).pipe( | ||
| 549 | Effect.result, | ||
| 550 | ); | ||
| 551 | assert.strictEqual(denied._tag, "Failure"); | ||
| 552 | yield* Deferred.succeed(release, undefined); | ||
| 553 | assert.strictEqual((yield* Fiber.join(imported)).phase, "succeeded"); | ||
| 554 | assert.strictEqual( | ||
| 555 | yield* controller.withAccess!(Effect.succeed("new credential process")), | ||
| 556 | "new credential process", | ||
| 557 | ); | ||
| 558 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 559 | ); | ||
packages/provider-core/src/server/ProviderAuthFlow.ts deleted-525| ... | @@ -1,525 +0,0 @@ | ||
| 1 | import { | ||
| 2 | ProviderSetupError, | ||
| 3 | type ProviderAuthInteraction, | ||
| 4 | type ProviderAuthMethod, | ||
| 5 | type ProviderAuthResponse, | ||
| 6 | type ProviderAuthState, | ||
| 7 | type ProviderInstanceId, | ||
| 8 | } from "@t3tools/contracts"; | ||
| 9 | import * as Cause from "effect/Cause"; | ||
| 10 | import * as Option from "effect/Option"; | ||
| 11 | import * as Schema from "effect/Schema"; | ||
| 12 | import * as Clock from "effect/Clock"; | ||
| 13 | import * as Crypto from "effect/Crypto"; | ||
| 14 | import * as DateTime from "effect/DateTime"; | ||
| 15 | import * as Effect from "effect/Effect"; | ||
| 16 | import * as Deferred from "effect/Deferred"; | ||
| 17 | import * as Exit from "effect/Exit"; | ||
| 18 | import * as Fiber from "effect/Fiber"; | ||
| 19 | import * as Scope from "effect/Scope"; | ||
| 20 | import * as Semaphore from "effect/Semaphore"; | ||
| 21 | import * as Stream from "effect/Stream"; | ||
| 22 | import * as SubscriptionRef from "effect/SubscriptionRef"; | ||
| 23 | |||
| 24 | import type * as ProviderAuth from "./auth.ts"; | ||
| 25 | |||
| 26 | export interface ProviderAuthFlowContext { | ||
| 27 | readonly flowId: string; | ||
| 28 | /** The lifetime timeout interrupts authenticate before publishing its expired result. */ | ||
| 29 | readonly expiresAt: number; | ||
| 30 | readonly returnUrl?: string; | ||
| 31 | readonly callbackMode?: "server" | "client"; | ||
| 32 | readonly setInteraction: ( | ||
| 33 | interaction: ProviderAuthInteraction, | ||
| 34 | respond?: (response: ProviderAuthResponse) => Effect.Effect<void, ProviderSetupError>, | ||
| 35 | complete?: (callbackUrl: string) => Effect.Effect<void, ProviderSetupError>, | ||
| 36 | ) => Effect.Effect<void>; | ||
| 37 | readonly verifying: Effect.Effect<void>; | ||
| 38 | } | ||
| 39 | |||
| 40 | const isSetupError = Schema.is(ProviderSetupError); | ||
| 41 | |||
| 42 | const failureMessage = (cause: Cause.Cause<ProviderSetupError>) => { | ||
| 43 | const error = Cause.findErrorOption(cause); | ||
| 44 | return Option.isSome(error) && isSetupError(error.value) | ||
| 45 | ? error.value.detail | ||
| 46 | : "Sign-in failed. Start again."; | ||
| 47 | }; | ||
| 48 | |||
| 49 | interface Flow { | ||
| 50 | readonly id: string; | ||
| 51 | readonly owner: string; | ||
| 52 | readonly expiresAt: number; | ||
| 53 | complete?: ((callbackUrl: string) => Effect.Effect<void, ProviderSetupError>) | undefined; | ||
| 54 | fiber?: Fiber.Fiber<void>; | ||
| 55 | responseFiber?: Fiber.Fiber<void, ProviderSetupError>; | ||
| 56 | respond: | ||
| 57 | | ((response: ProviderAuthResponse) => Effect.Effect<void, ProviderSetupError>) | ||
| 58 | | undefined; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** Adapters do login and credential handling; this owns client consent and flow lifetime. */ | ||
| 62 | export const make = Effect.fn("ProviderAuthFlow.make")(function* (options: { | ||
| 63 | readonly instanceId: ProviderInstanceId; | ||
| 64 | readonly credentialBinding: NonNullable<ProviderAuth.ProviderAuthController["credentialBinding"]>; | ||
| 65 | readonly methods: Effect.Effect<ReadonlyArray<ProviderAuthMethod>, ProviderSetupError>; | ||
| 66 | readonly defaultMethodId?: string; | ||
| 67 | /** Stored account profiles can change the advertised methods after auth/logout. */ | ||
| 68 | readonly refreshMethodsAfterAuth?: boolean; | ||
| 69 | /** Fail with ProviderSetupError containing safe text for the user, never native token data. */ | ||
| 70 | readonly authenticate: ( | ||
| 71 | methodId: string, | ||
| 72 | context: ProviderAuthFlowContext, | ||
| 73 | ) => Effect.Effect<void, ProviderSetupError, Scope.Scope>; | ||
| 74 | readonly logout: Effect.Effect<void | string, ProviderSetupError>; | ||
| 75 | readonly timeoutMs?: number; | ||
| 76 | }) { | ||
| 77 | const scope = yield* Scope.Scope; | ||
| 78 | const crypto = yield* Crypto.Crypto; | ||
| 79 | const lock = yield* Semaphore.make(1); | ||
| 80 | const timeoutMs = options.timeoutMs ?? 300_000; | ||
| 81 | const empty: ProviderAuthState = { | ||
| 82 | instanceId: options.instanceId, | ||
| 83 | phase: "idle", | ||
| 84 | flowId: null, | ||
| 85 | authorizationUrl: null, | ||
| 86 | expiresAt: null, | ||
| 87 | message: null, | ||
| 88 | interaction: null, | ||
| 89 | credentialOwner: options.credentialBinding.owner, | ||
| 90 | }; | ||
| 91 | const snapshot = yield* SubscriptionRef.make({ owner: null as string | null, state: empty }); | ||
| 92 | let active: Flow | undefined; | ||
| 93 | let operation: "idle" | "auth" | "stopping" | "closed" = "idle"; | ||
| 94 | const sessions = new Set<Scope.Closeable>(); | ||
| 95 | const stopOwnedSessions = Effect.suspend(() => | ||
| 96 | Effect.forEach(Array.from(sessions), (session) => Scope.close(session, Exit.void), { | ||
| 97 | discard: true, | ||
| 98 | concurrency: "unbounded", | ||
| 99 | }), | ||
| 100 | ); | ||
| 101 | const publish = (flow: Flow, patch: Partial<ProviderAuthState>) => | ||
| 102 | Effect.suspend(() => | ||
| 103 | active === flow | ||
| 104 | ? SubscriptionRef.update(snapshot, (current) => ({ | ||
| 105 | owner: flow.owner, | ||
| 106 | state: { ...current.state, ...patch }, | ||
| 107 | })) | ||
| 108 | : Effect.void, | ||
| 109 | ); | ||
| 110 | |||
| 111 | const requireFlow = Effect.fnUntraced(function* (owner: string, id: string) { | ||
| 112 | if ( | ||
| 113 | operation !== "auth" || | ||
| 114 | !active || | ||
| 115 | active.owner !== owner || | ||
| 116 | active.id !== id || | ||
| 117 | (yield* Clock.currentTimeMillis) >= active.expiresAt | ||
| 118 | ) { | ||
| 119 | return yield* new ProviderSetupError({ | ||
| 120 | instanceId: options.instanceId, | ||
| 121 | operation: "respond", | ||
| 122 | detail: "This sign-in is no longer active in this client.", | ||
| 123 | }); | ||
| 124 | } | ||
| 125 | return active; | ||
| 126 | }); | ||
| 127 | |||
| 128 | // Method discovery does not start a sign-in flow. | ||
| 129 | const refreshMethods = options.methods.pipe( | ||
| 130 | Effect.flatMap((methods) => | ||
| 131 | SubscriptionRef.update(snapshot, (current) => ({ | ||
| 132 | ...current, | ||
| 133 | state: { ...current.state, methods }, | ||
| 134 | })), | ||
| 135 | ), | ||
| 136 | // Keep the last known methods when a refresh fails or is interrupted. | ||
| 137 | Effect.catch((error) => | ||
| 138 | SubscriptionRef.update(snapshot, (current) => ({ | ||
| 139 | ...current, | ||
| 140 | state: { ...current.state, methods: current.state.methods ?? [], message: error.detail }, | ||
| 141 | })), | ||
| 142 | ), | ||
| 143 | ); | ||
| 144 | yield* refreshMethods.pipe(Effect.forkIn(scope)); | ||
| 145 | |||
| 146 | const controller: ProviderAuth.ProviderAuthController = { | ||
| 147 | credentialBinding: options.credentialBinding, | ||
| 148 | adoptCredentials: (update, stopSessions) => | ||
| 149 | Effect.gen(function* () { | ||
| 150 | yield* lock.withPermit( | ||
| 151 | Effect.gen(function* () { | ||
| 152 | if (operation !== "idle") | ||
| 153 | return yield* new ProviderSetupError({ | ||
| 154 | instanceId: options.instanceId, | ||
| 155 | operation: "import", | ||
| 156 | detail: "Finish or cancel the existing sign-in first.", | ||
| 157 | }); | ||
| 158 | operation = "stopping"; | ||
| 159 | }), | ||
| 160 | ); | ||
| 161 | const result = yield* Effect.gen(function* () { | ||
| 162 | yield* stopOwnedSessions; | ||
| 163 | yield* stopSessions; | ||
| 164 | yield* update; | ||
| 165 | yield* refreshMethods; | ||
| 166 | }).pipe(Effect.exit); | ||
| 167 | const state: ProviderAuthState = { | ||
| 168 | ...empty, | ||
| 169 | methods: snapshot.value.state.methods ?? [], | ||
| 170 | phase: Exit.isSuccess(result) ? "succeeded" : "failed", | ||
| 171 | message: Exit.isSuccess(result) ? null : failureMessage(result.cause), | ||
| 172 | }; | ||
| 173 | yield* lock.withPermit( | ||
| 174 | Effect.gen(function* () { | ||
| 175 | yield* SubscriptionRef.set(snapshot, { owner: null, state }); | ||
| 176 | operation = "idle"; | ||
| 177 | }), | ||
| 178 | ); | ||
| 179 | if (Exit.isFailure(result)) return yield* Effect.failCause(result.cause); | ||
| 180 | return state; | ||
| 181 | }).pipe(Effect.uninterruptible), | ||
| 182 | refreshMethods, | ||
| 183 | invalidate: lock.withPermit( | ||
| 184 | Effect.gen(function* () { | ||
| 185 | if (operation !== "idle") return; | ||
| 186 | yield* stopOwnedSessions; | ||
| 187 | yield* SubscriptionRef.set(snapshot, { | ||
| 188 | owner: null, | ||
| 189 | state: { | ||
| 190 | ...empty, | ||
| 191 | methods: snapshot.value.state.methods ?? [], | ||
| 192 | message: "This provider's shared sign-in changed.", | ||
| 193 | }, | ||
| 194 | }); | ||
| 195 | }), | ||
| 196 | ), | ||
| 197 | isChangingCredentials: Effect.sync(() => operation !== "idle"), | ||
| 198 | withAccess: (task) => | ||
| 199 | Effect.uninterruptibleMask((restore) => | ||
| 200 | Effect.gen(function* () { | ||
| 201 | const parent = yield* Scope.Scope; | ||
| 202 | const child = yield* lock.withPermit( | ||
| 203 | Effect.gen(function* () { | ||
| 204 | if (operation !== "idle") | ||
| 205 | return yield* new ProviderSetupError({ | ||
| 206 | instanceId: options.instanceId, | ||
| 207 | operation: "session", | ||
| 208 | detail: "Provider sign-in is changing. Try again after it finishes.", | ||
| 209 | }); | ||
| 210 | const child = yield* Scope.make(); | ||
| 211 | sessions.add(child); | ||
| 212 | yield* Scope.addFinalizer( | ||
| 213 | child, | ||
| 214 | Effect.sync(() => { | ||
| 215 | sessions.delete(child); | ||
| 216 | }), | ||
| 217 | ); | ||
| 218 | yield* Scope.addFinalizer(parent, Scope.close(child, Exit.void)); | ||
| 219 | return child; | ||
| 220 | }), | ||
| 221 | ); | ||
| 222 | const fiber = yield* restore(task).pipe( | ||
| 223 | Effect.provideService(Scope.Scope, child), | ||
| 224 | Effect.forkIn(child), | ||
| 225 | ); | ||
| 226 | return yield* restore(Fiber.await(fiber)).pipe( | ||
| 227 | Effect.flatMap((result) => result), | ||
| 228 | Effect.onExit((result) => | ||
| 229 | Exit.isFailure(result) ? Scope.close(child, Exit.void) : Effect.void, | ||
| 230 | ), | ||
| 231 | ); | ||
| 232 | }), | ||
| 233 | ), | ||
| 234 | start: (owner, stopSessions = Effect.void, selectedMethodId, returnUrl, callbackMode) => | ||
| 235 | lock.withPermit( | ||
| 236 | Effect.gen(function* () { | ||
| 237 | if (operation === "auth" && active?.owner === owner) return snapshot.value.state; | ||
| 238 | if (operation !== "idle") | ||
| 239 | return yield* new ProviderSetupError({ | ||
| 240 | instanceId: options.instanceId, | ||
| 241 | operation: "start", | ||
| 242 | detail: "Provider setup is already in progress.", | ||
| 243 | }); | ||
| 244 | const id = yield* crypto.randomUUIDv4.pipe( | ||
| 245 | Effect.mapError( | ||
| 246 | () => | ||
| 247 | new ProviderSetupError({ | ||
| 248 | instanceId: options.instanceId, | ||
| 249 | operation: "start", | ||
| 250 | detail: "Could not start sign-in. Try again.", | ||
| 251 | }), | ||
| 252 | ), | ||
| 253 | ); | ||
| 254 | const flow: Flow = { | ||
| 255 | id, | ||
| 256 | owner, | ||
| 257 | expiresAt: (yield* Clock.currentTimeMillis) + timeoutMs, | ||
| 258 | respond: undefined, | ||
| 259 | }; | ||
| 260 | active = flow; | ||
| 261 | operation = "auth"; | ||
| 262 | const state: ProviderAuthState = { | ||
| 263 | ...empty, | ||
| 264 | methods: snapshot.value.state.methods ?? [], | ||
| 265 | phase: "starting", | ||
| 266 | flowId: id, | ||
| 267 | expiresAt: DateTime.formatIso(DateTime.makeUnsafe(flow.expiresAt)), | ||
| 268 | message: "Starting sign-in.", | ||
| 269 | }; | ||
| 270 | yield* SubscriptionRef.set(snapshot, { owner, state }); | ||
| 271 | flow.fiber = yield* Effect.gen(function* () { | ||
| 272 | const methods = yield* options.methods; | ||
| 273 | yield* publish(flow, { methods }); | ||
| 274 | const methodId = selectedMethodId ?? options.defaultMethodId ?? methods[0]?.id; | ||
| 275 | if (!methodId || !methods.some((method) => method.id === methodId)) | ||
| 276 | return yield* new ProviderSetupError({ | ||
| 277 | instanceId: options.instanceId, | ||
| 278 | operation: "start", | ||
| 279 | detail: "The provider did not advertise this sign-in method.", | ||
| 280 | }); | ||
| 281 | yield* stopSessions.pipe(Effect.ensuring(stopOwnedSessions)); | ||
| 282 | yield* options.authenticate(methodId, { | ||
| 283 | flowId: id, | ||
| 284 | expiresAt: flow.expiresAt, | ||
| 285 | ...(returnUrl ? { returnUrl } : {}), | ||
| 286 | ...(callbackMode ? { callbackMode } : {}), | ||
| 287 | setInteraction: (interaction, respond, complete) => | ||
| 288 | Effect.gen(function* () { | ||
| 289 | if (active !== flow) return; | ||
| 290 | flow.respond = respond; | ||
| 291 | flow.complete = complete; | ||
| 292 | yield* publish(flow, { | ||
| 293 | phase: "waiting", | ||
| 294 | interaction, | ||
| 295 | authorizationUrl: | ||
| 296 | interaction.type === "browser" || interaction.type === "deviceCode" | ||
| 297 | ? interaction.url | ||
| 298 | : null, | ||
| 299 | message: "Complete sign-in to continue.", | ||
| 300 | }); | ||
| 301 | }), | ||
| 302 | verifying: Effect.gen(function* () { | ||
| 303 | flow.respond = undefined; | ||
| 304 | flow.complete = undefined; | ||
| 305 | yield* publish(flow, { | ||
| 306 | phase: "verifying", | ||
| 307 | interaction: null, | ||
| 308 | authorizationUrl: null, | ||
| 309 | message: "Checking provider sign-in.", | ||
| 310 | }); | ||
| 311 | }), | ||
| 312 | }); | ||
| 313 | }).pipe( | ||
| 314 | Effect.scoped, | ||
| 315 | Effect.timeoutOrElse({ | ||
| 316 | duration: timeoutMs, | ||
| 317 | orElse: () => | ||
| 318 | Effect.fail( | ||
| 319 | new ProviderSetupError({ | ||
| 320 | instanceId: options.instanceId, | ||
| 321 | operation: "start", | ||
| 322 | detail: "Sign-in expired. Start again.", | ||
| 323 | }), | ||
| 324 | ), | ||
| 325 | }), | ||
| 326 | Effect.exit, | ||
| 327 | Effect.flatMap((result) => | ||
| 328 | Effect.gen(function* () { | ||
| 329 | const finishing = yield* lock.withPermit( | ||
| 330 | Effect.sync(() => { | ||
| 331 | if (active !== flow) return false; | ||
| 332 | operation = "stopping"; | ||
| 333 | return true; | ||
| 334 | }), | ||
| 335 | ); | ||
| 336 | if (!finishing) return; | ||
| 337 | if (flow.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 338 | yield* lock.withPermit( | ||
| 339 | Effect.gen(function* () { | ||
| 340 | if (active !== flow) return; | ||
| 341 | if (options.refreshMethodsAfterAuth) yield* refreshMethods; | ||
| 342 | yield* publish(flow, { | ||
| 343 | phase: Exit.isSuccess(result) ? "succeeded" : "failed", | ||
| 344 | interaction: null, | ||
| 345 | authorizationUrl: null, | ||
| 346 | expiresAt: null, | ||
| 347 | message: Exit.isSuccess(result) | ||
| 348 | ? "Sign-in complete." | ||
| 349 | : failureMessage(result.cause), | ||
| 350 | }); | ||
| 351 | active = undefined; | ||
| 352 | operation = "idle"; | ||
| 353 | }), | ||
| 354 | ); | ||
| 355 | }), | ||
| 356 | ), | ||
| 357 | Effect.interruptible, | ||
| 358 | Effect.forkIn(scope), | ||
| 359 | ); | ||
| 360 | return state; | ||
| 361 | }).pipe(Effect.uninterruptible), | ||
| 362 | ), | ||
| 363 | respond: (owner, input) => | ||
| 364 | Effect.uninterruptibleMask((restore) => | ||
| 365 | Effect.gen(function* () { | ||
| 366 | const { flow, fiber, ready } = yield* lock.withPermit( | ||
| 367 | Effect.gen(function* () { | ||
| 368 | const flow = yield* requireFlow(owner, input.flowId); | ||
| 369 | const interaction = snapshot.value.state.interaction; | ||
| 370 | if ( | ||
| 371 | !interaction || | ||
| 372 | interaction.id !== input.interactionId || | ||
| 373 | interaction.type !== input.response.type || | ||
| 374 | !flow.respond | ||
| 375 | ) | ||
| 376 | return yield* new ProviderSetupError({ | ||
| 377 | instanceId: options.instanceId, | ||
| 378 | operation: "respond", | ||
| 379 | detail: "This sign-in interaction is no longer available.", | ||
| 380 | }); | ||
| 381 | if (flow.responseFiber) | ||
| 382 | return yield* new ProviderSetupError({ | ||
| 383 | instanceId: options.instanceId, | ||
| 384 | operation: "respond", | ||
| 385 | detail: "A sign-in response is already in progress.", | ||
| 386 | }); | ||
| 387 | const ready = yield* Deferred.make<void>(); | ||
| 388 | const callback = flow.respond; | ||
| 389 | const fiber = yield* Deferred.await(ready).pipe( | ||
| 390 | Effect.andThen(Effect.suspend(() => callback(input.response))), | ||
| 391 | Effect.interruptible, | ||
| 392 | Effect.forkIn(scope), | ||
| 393 | ); | ||
| 394 | flow.responseFiber = fiber; | ||
| 395 | return { flow, fiber, ready }; | ||
| 396 | }), | ||
| 397 | ); | ||
| 398 | yield* Deferred.succeed(ready, undefined); | ||
| 399 | yield* restore(Fiber.join(fiber)).pipe( | ||
| 400 | Effect.onInterrupt(() => Fiber.interrupt(fiber).pipe(Effect.asVoid)), | ||
| 401 | Effect.ensuring( | ||
| 402 | lock.withPermit( | ||
| 403 | Effect.sync(() => { | ||
| 404 | if (flow.responseFiber === fiber) delete flow.responseFiber; | ||
| 405 | }), | ||
| 406 | ), | ||
| 407 | ), | ||
| 408 | ); | ||
| 409 | return snapshot.value.state; | ||
| 410 | }), | ||
| 411 | ), | ||
| 412 | complete: (owner, input) => | ||
| 413 | lock.withPermit( | ||
| 414 | Effect.gen(function* () { | ||
| 415 | const flow = yield* requireFlow(owner, input.flowId); | ||
| 416 | const interaction = snapshot.value.state.interaction; | ||
| 417 | if ( | ||
| 418 | snapshot.value.state.phase !== "waiting" || | ||
| 419 | interaction?.type !== "browser" || | ||
| 420 | !interaction.acceptsCallback || | ||
| 421 | !flow.complete | ||
| 422 | ) | ||
| 423 | return yield* new ProviderSetupError({ | ||
| 424 | instanceId: options.instanceId, | ||
| 425 | operation: "complete", | ||
| 426 | detail: "This sign-in does not accept a redirect URL.", | ||
| 427 | }); | ||
| 428 | yield* flow.complete(input.callbackUrl); | ||
| 429 | return snapshot.value.state; | ||
| 430 | }), | ||
| 431 | ), | ||
| 432 | cancel: (owner, id) => | ||
| 433 | Effect.gen(function* () { | ||
| 434 | const flow = yield* lock.withPermit( | ||
| 435 | Effect.gen(function* () { | ||
| 436 | const flow = yield* requireFlow(owner, id); | ||
| 437 | yield* publish(flow, { | ||
| 438 | phase: "cancelled", | ||
| 439 | interaction: null, | ||
| 440 | authorizationUrl: null, | ||
| 441 | expiresAt: null, | ||
| 442 | message: "Sign-in cancelled.", | ||
| 443 | }); | ||
| 444 | active = undefined; | ||
| 445 | operation = "stopping"; | ||
| 446 | return flow; | ||
| 447 | }), | ||
| 448 | ); | ||
| 449 | if (flow.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 450 | if (flow.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 451 | operation = "idle"; | ||
| 452 | return snapshot.value.state; | ||
| 453 | }).pipe(Effect.uninterruptible), | ||
| 454 | logout: (stopSessions) => | ||
| 455 | Effect.gen(function* () { | ||
| 456 | const flow = yield* lock.withPermit( | ||
| 457 | Effect.gen(function* () { | ||
| 458 | if (operation !== "idle" && operation !== "auth") | ||
| 459 | return yield* new ProviderSetupError({ | ||
| 460 | instanceId: options.instanceId, | ||
| 461 | operation: "logout", | ||
| 462 | detail: "Provider setup is already stopping.", | ||
| 463 | }); | ||
| 464 | operation = "stopping"; | ||
| 465 | const flow = active; | ||
| 466 | active = undefined; | ||
| 467 | return flow; | ||
| 468 | }), | ||
| 469 | ); | ||
| 470 | const result = yield* Effect.gen(function* () { | ||
| 471 | if (flow?.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 472 | if (flow?.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 473 | yield* stopSessions.pipe(Effect.ensuring(stopOwnedSessions)); | ||
| 474 | const message = yield* options.logout; | ||
| 475 | if (options.refreshMethodsAfterAuth) yield* refreshMethods; | ||
| 476 | return message; | ||
| 477 | }).pipe(Effect.exit); | ||
| 478 | const state: ProviderAuthState = { | ||
| 479 | ...empty, | ||
| 480 | methods: snapshot.value.state.methods ?? [], | ||
| 481 | phase: Exit.isSuccess(result) ? "idle" : "failed", | ||
| 482 | message: Exit.isSuccess(result) | ||
| 483 | ? (result.value ?? "Signed out.") | ||
| 484 | : "Could not sign out. Try again.", | ||
| 485 | }; | ||
| 486 | yield* lock.withPermit( | ||
| 487 | Effect.gen(function* () { | ||
| 488 | yield* SubscriptionRef.set(snapshot, { owner: null, state }); | ||
| 489 | operation = "idle"; | ||
| 490 | }), | ||
| 491 | ); | ||
| 492 | if (Exit.isFailure(result)) return yield* Effect.failCause(result.cause); | ||
| 493 | return state; | ||
| 494 | }).pipe(Effect.uninterruptible), | ||
| 495 | subscribe: (owner) => | ||
| 496 | SubscriptionRef.changes(snapshot).pipe( | ||
| 497 | Stream.map((current) => | ||
| 498 | current.owner === null || current.owner === owner | ||
| 499 | ? current.state | ||
| 500 | : { | ||
| 501 | ...current.state, | ||
| 502 | flowId: null, | ||
| 503 | authorizationUrl: null, | ||
| 504 | interaction: null, | ||
| 505 | expiresAt: null, | ||
| 506 | message: active | ||
| 507 | ? "Sign-in is in progress in another client." | ||
| 508 | : current.state.message, | ||
| 509 | }, | ||
| 510 | ), | ||
| 511 | ), | ||
| 512 | }; | ||
| 513 | yield* Effect.addFinalizer(() => | ||
| 514 | Effect.gen(function* () { | ||
| 515 | operation = "closed"; | ||
| 516 | const flow = active; | ||
| 517 | active = undefined; | ||
| 518 | if (flow?.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 519 | if (flow?.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 520 | // Settings edits rebuild instances; admitted sessions (including those of | ||
| 521 | // peers sharing this binding) end with their own scopes, not this one. | ||
| 522 | }), | ||
| 523 | ); | ||
| 524 | return controller; | ||
| 525 | }); | ||
packages/provider-core/src/server/ProviderContinuationRequests.ts created+76| ... | @@ -0,0 +1,76 @@ | ||
| 1 | import { | ||
| 2 | type OrchestrationV2Notification, | ||
| 3 | MessageId, | ||
| 4 | ProviderDriverKind, | ||
| 5 | ProviderThreadId, | ||
| 6 | RunId, | ||
| 7 | ThreadId, | ||
| 8 | } from "@t3tools/contracts"; | ||
| 9 | import * as Context from "effect/Context"; | ||
| 10 | import * as Effect from "effect/Effect"; | ||
| 11 | import * as Layer from "effect/Layer"; | ||
| 12 | import * as Option from "effect/Option"; | ||
| 13 | import * as Queue from "effect/Queue"; | ||
| 14 | |||
| 15 | export interface ProviderContinuationRequest { | ||
| 16 | readonly threadId: ThreadId; | ||
| 17 | readonly providerThreadId: ProviderThreadId; | ||
| 18 | readonly driver: ProviderDriverKind; | ||
| 19 | readonly detail: string | null; | ||
| 20 | readonly notification?: OrchestrationV2Notification; | ||
| 21 | /** | ||
| 22 | * Durable ownership for an app-owned delegated-task completion delivery. | ||
| 23 | * The continuation worker re-reads the cohort before dispatching so a later | ||
| 24 | * task can join a queued wake and a stopped or acknowledged cohort is dropped. | ||
| 25 | */ | ||
| 26 | readonly delegatedCompletion?: { | ||
| 27 | readonly parentRunId: RunId; | ||
| 28 | readonly generation: number; | ||
| 29 | readonly messageId: MessageId; | ||
| 30 | }; | ||
| 31 | /** | ||
| 32 | * How the continuation turn gets its content. | ||
| 33 | * | ||
| 34 | * `adapter_buffered` (default) is the provider-native wake: the adapter has | ||
| 35 | * already buffered the CLI's wake output, and the dispatched message only | ||
| 36 | * triggers ingestion. `ClaudeAdapterV2` deliberately discards the message | ||
| 37 | * text on that path. | ||
| 38 | * | ||
| 39 | * `message_text` is for app-owned work with no buffered provider output, such | ||
| 40 | * as a delegated child finishing. The text is the entire wake, so it must | ||
| 41 | * reach the provider as a real prompt. | ||
| 42 | */ | ||
| 43 | readonly delivery?: "adapter_buffered" | "message_text"; | ||
| 44 | readonly dispatchIfCurrent?: <A, E, R>( | ||
| 45 | effect: Effect.Effect<A, E, R>, | ||
| 46 | ) => Effect.Effect<Option.Option<A>, E, R>; | ||
| 47 | /** Clears a pending offer that the continuation worker intentionally drops. */ | ||
| 48 | readonly clearIfCurrent?: () => Effect.Effect<void>; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Adapters offer a continuation request when provider-native work completes | ||
| 53 | * outside an active turn (for example a Claude background task wake turn) so | ||
| 54 | * the orchestrator can start a run that ingests it. The default reference | ||
| 55 | * drops requests, keeping adapter construction dependency-free in tests; the | ||
| 56 | * live layer must be shared with the ProviderContinuationService worker that | ||
| 57 | * drains it. | ||
| 58 | */ | ||
| 59 | export class ProviderContinuationRequests extends Context.Reference<{ | ||
| 60 | readonly offer: (request: ProviderContinuationRequest) => Effect.Effect<void>; | ||
| 61 | readonly take: Effect.Effect<ProviderContinuationRequest>; | ||
| 62 | }>("@t3tools/provider-core/server/ProviderContinuationRequests", { | ||
| 63 | defaultValue: () => ({ offer: () => Effect.void, take: Effect.never }), | ||
| 64 | }) {} | ||
| 65 | |||
| 66 | export const layer = Layer.effect( | ||
| 67 | ProviderContinuationRequests, | ||
| 68 | Effect.gen(function* () { | ||
| 69 | const queue = yield* Queue.unbounded<ProviderContinuationRequest>(); | ||
| 70 | return { | ||
| 71 | offer: (request: ProviderContinuationRequest) => | ||
| 72 | Queue.offer(queue, request).pipe(Effect.asVoid), | ||
| 73 | take: Queue.take(queue), | ||
| 74 | }; | ||
| 75 | }), | ||
| 76 | ); | ||
packages/provider-core/src/server/ProviderHost.ts+29-30| ... | @@ -45,33 +45,32 @@ export interface ProviderCredentials { | ... | @@ -45,33 +45,32 @@ export interface ProviderCredentials { |
| 45 | readonly remove: Effect.Effect<void, ProviderCredentialError>; | 45 | readonly remove: Effect.Effect<void, ProviderCredentialError>; |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | interface ProviderHostService { | 48 | export class ProviderHost extends Context.Service< |
| 49 | readonly paths: ProviderHostPaths; | 49 | ProviderHost, |
| 50 | readonly settings: { | 50 | { |
| 51 | readonly get: Effect.Effect<ServerSettings, ServerSettingsError>; | 51 | readonly paths: ProviderHostPaths; |
| 52 | /** Runs `use` on a settings snapshot that no settings write can change until it finishes. */ | 52 | readonly settings: { |
| 53 | readonly withSnapshot: <A, E, R>( | 53 | readonly get: Effect.Effect<ServerSettings, ServerSettingsError>; |
| 54 | use: (settings: ServerSettings) => Effect.Effect<A, E, R>, | 54 | /** Runs `use` on a settings snapshot that no settings write can change until it finishes. */ |
| 55 | ) => Effect.Effect<A, E | ServerSettingsError, R>; | 55 | readonly withSnapshot: <A, E, R>( |
| 56 | /** Every settings change after subscription, starting with the next one. */ | 56 | use: (settings: ServerSettings) => Effect.Effect<A, E, R>, |
| 57 | readonly changes: Stream.Stream<ServerSettings>; | 57 | ) => Effect.Effect<A, E | ServerSettingsError, R>; |
| 58 | /** Changes buffered from the moment the scoped subscription is acquired. */ | 58 | /** Every settings change after subscription, starting with the next one. */ |
| 59 | readonly subscribe: Effect.Effect<Stream.Stream<ServerSettings>, never, Scope.Scope>; | 59 | readonly changes: Stream.Stream<ServerSettings>; |
| 60 | }; | 60 | /** Changes buffered from the moment the scoped subscription is acquired. */ |
| 61 | /** Whether background work for `scope` should run now (client demand and host power). */ | 61 | readonly subscribe: Effect.Effect<Stream.Stream<ServerSettings>, never, Scope.Scope>; |
| 62 | readonly shouldRunBackgroundWork: (scope: BackgroundScope) => Effect.Effect<boolean>; | 62 | }; |
| 63 | /** | 63 | /** Whether background work for `scope` should run now (client demand and host power). */ |
| 64 | * Absolute path of a stored chat attachment, or `null` when its id does not | 64 | readonly shouldRunBackgroundWork: (scope: BackgroundScope) => Effect.Effect<boolean>; |
| 65 | * resolve inside the attachments directory. | 65 | /** |
| 66 | */ | 66 | * Absolute path of a stored chat attachment, or `null` when its id does not |
| 67 | readonly resolveAttachmentPath: (attachment: ChatAttachment) => string | null; | 67 | * resolve inside the attachments directory. |
| 68 | /** The credentials stored for `bindingId`, usually an instance id, under a provider-chosen namespace. */ | 68 | */ |
| 69 | readonly credentials: ( | 69 | readonly resolveAttachmentPath: (attachment: ChatAttachment) => string | null; |
| 70 | namespace: string, | 70 | /** The credentials stored for `bindingId`, usually an instance id, under a provider-chosen namespace. */ |
| 71 | bindingId: string, | 71 | readonly credentials: ( |
| 72 | ) => Effect.Effect<ProviderCredentials>; | 72 | namespace: string, |
| 73 | } | 73 | bindingId: string, |
| 74 | 74 | ) => Effect.Effect<ProviderCredentials>; | |
| 75 | export class ProviderHost extends Context.Service<ProviderHost, ProviderHostService>()( | 75 | } |
| 76 | "@t3tools/provider-core/server/ProviderHost", | 76 | >()("@t3tools/provider-core/server/ProviderHost") {} |
| 77 | ) {} |
packages/provider-core/src/server/adapterDriver.ts+1-1| ... | @@ -39,7 +39,7 @@ export interface ProviderAdapterDriver<Config, R = never> { | ... | @@ -39,7 +39,7 @@ export interface ProviderAdapterDriver<Config, R = never> { |
| 39 | readonly create: ( | 39 | readonly create: ( |
| 40 | input: ProviderAdapterDriverCreateInput<Config>, | 40 | input: ProviderAdapterDriverCreateInput<Config>, |
| 41 | ) => Effect.Effect< | 41 | ) => Effect.Effect< |
| 42 | ProviderAdapter.ProviderAdapterV2Shape, | 42 | ProviderAdapter.ProviderAdapterV2["Service"], |
| 43 | ProviderAdapterDriverCreateError, | 43 | ProviderAdapterDriverCreateError, |
| 44 | R | Scope.Scope | 44 | R | Scope.Scope |
| 45 | >; | 45 | >; |
packages/provider-core/src/server/continuationRequests.ts deleted-76| ... | @@ -1,76 +0,0 @@ | ||
| 1 | import { | ||
| 2 | type OrchestrationV2Notification, | ||
| 3 | MessageId, | ||
| 4 | ProviderDriverKind, | ||
| 5 | ProviderThreadId, | ||
| 6 | RunId, | ||
| 7 | ThreadId, | ||
| 8 | } from "@t3tools/contracts"; | ||
| 9 | import * as Context from "effect/Context"; | ||
| 10 | import * as Effect from "effect/Effect"; | ||
| 11 | import * as Layer from "effect/Layer"; | ||
| 12 | import * as Option from "effect/Option"; | ||
| 13 | import * as Queue from "effect/Queue"; | ||
| 14 | |||
| 15 | export interface ProviderContinuationRequest { | ||
| 16 | readonly threadId: ThreadId; | ||
| 17 | readonly providerThreadId: ProviderThreadId; | ||
| 18 | readonly driver: ProviderDriverKind; | ||
| 19 | readonly detail: string | null; | ||
| 20 | readonly notification?: OrchestrationV2Notification; | ||
| 21 | /** | ||
| 22 | * Durable ownership for an app-owned delegated-task completion delivery. | ||
| 23 | * The continuation worker re-reads the cohort before dispatching so a later | ||
| 24 | * task can join a queued wake and a stopped or acknowledged cohort is dropped. | ||
| 25 | */ | ||
| 26 | readonly delegatedCompletion?: { | ||
| 27 | readonly parentRunId: RunId; | ||
| 28 | readonly generation: number; | ||
| 29 | readonly messageId: MessageId; | ||
| 30 | }; | ||
| 31 | /** | ||
| 32 | * How the continuation turn gets its content. | ||
| 33 | * | ||
| 34 | * `adapter_buffered` (default) is the provider-native wake: the adapter has | ||
| 35 | * already buffered the CLI's wake output, and the dispatched message only | ||
| 36 | * triggers ingestion. `ClaudeAdapterV2` deliberately discards the message | ||
| 37 | * text on that path. | ||
| 38 | * | ||
| 39 | * `message_text` is for app-owned work with no buffered provider output, such | ||
| 40 | * as a delegated child finishing. The text is the entire wake, so it must | ||
| 41 | * reach the provider as a real prompt. | ||
| 42 | */ | ||
| 43 | readonly delivery?: "adapter_buffered" | "message_text"; | ||
| 44 | readonly dispatchIfCurrent?: <A, E, R>( | ||
| 45 | effect: Effect.Effect<A, E, R>, | ||
| 46 | ) => Effect.Effect<Option.Option<A>, E, R>; | ||
| 47 | /** Clears a pending offer that the continuation worker intentionally drops. */ | ||
| 48 | readonly clearIfCurrent?: () => Effect.Effect<void>; | ||
| 49 | } | ||
| 50 | |||
| 51 | /** | ||
| 52 | * Adapters offer a continuation request when provider-native work completes | ||
| 53 | * outside an active turn (for example a Claude background task wake turn) so | ||
| 54 | * the orchestrator can start a run that ingests it. The default reference | ||
| 55 | * drops requests, keeping adapter construction dependency-free in tests; the | ||
| 56 | * live layer must be shared with the ProviderContinuationService worker that | ||
| 57 | * drains it. | ||
| 58 | */ | ||
| 59 | export class ProviderContinuationRequests extends Context.Reference<{ | ||
| 60 | readonly offer: (request: ProviderContinuationRequest) => Effect.Effect<void>; | ||
| 61 | readonly take: Effect.Effect<ProviderContinuationRequest>; | ||
| 62 | }>("@t3tools/provider-core/server/continuationRequests/ProviderContinuationRequests", { | ||
| 63 | defaultValue: () => ({ offer: () => Effect.void, take: Effect.never }), | ||
| 64 | }) {} | ||
| 65 | |||
| 66 | export const layer = Layer.effect( | ||
| 67 | ProviderContinuationRequests, | ||
| 68 | Effect.gen(function* () { | ||
| 69 | const queue = yield* Queue.unbounded<ProviderContinuationRequest>(); | ||
| 70 | return { | ||
| 71 | offer: (request: ProviderContinuationRequest) => | ||
| 72 | Queue.offer(queue, request).pipe(Effect.asVoid), | ||
| 73 | take: Queue.take(queue), | ||
| 74 | }; | ||
| 75 | }), | ||
| 76 | ); | ||
packages/provider-core/src/server/driver.ts+1-1| ... | @@ -101,7 +101,7 @@ export interface ProviderInstance { | ... | @@ -101,7 +101,7 @@ export interface ProviderInstance { |
| 101 | ProviderConsumeResetCreditOutcome, | 101 | ProviderConsumeResetCreditOutcome, |
| 102 | ProviderDriverError | 102 | ProviderDriverError |
| 103 | >; | 103 | >; |
| 104 | readonly orchestrationAdapter: ProviderAdapter.ProviderAdapterV2Shape; | 104 | readonly orchestrationAdapter: ProviderAdapter.ProviderAdapterV2["Service"]; |
| 105 | readonly textGeneration: ProviderTextGeneration; | 105 | readonly textGeneration: ProviderTextGeneration; |
| 106 | readonly auth?: ProviderAuthController; | 106 | readonly auth?: ProviderAuthController; |
| 107 | readonly acpSessionManagement?: { | 107 | readonly acpSessionManagement?: { |
packages/provider-core/src/server/failure.ts+3-5| ... | @@ -13,7 +13,7 @@ import type { | ... | @@ -13,7 +13,7 @@ import type { |
| 13 | import * as DateTime from "effect/DateTime"; | 13 | import * as DateTime from "effect/DateTime"; |
| 14 | import * as Cause from "effect/Cause"; | 14 | import * as Cause from "effect/Cause"; |
| 15 | 15 | ||
| 16 | import type * as IdAllocator from "./IdAllocator.ts"; | 16 | import * as IdAllocator from "./IdAllocator.ts"; |
| 17 | import * as Schema from "effect/Schema"; | 17 | import * as Schema from "effect/Schema"; |
| 18 | 18 | ||
| 19 | /** Raised when portable history does not fit the target provider's context window. */ | 19 | /** Raised when portable history does not fit the target provider's context window. */ |
| ... | @@ -172,7 +172,6 @@ export function makeProviderFailure(input: { | ... | @@ -172,7 +172,6 @@ export function makeProviderFailure(input: { |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | export function makeProviderFailureTurnItem(input: { | 174 | export function makeProviderFailureTurnItem(input: { |
| 175 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | ||
| 176 | readonly driver: ProviderDriverKind; | 175 | readonly driver: ProviderDriverKind; |
| 177 | readonly threadId: ThreadId; | 176 | readonly threadId: ThreadId; |
| 178 | readonly runId: RunId | null; | 177 | readonly runId: RunId | null; |
| ... | @@ -186,7 +185,7 @@ export function makeProviderFailureTurnItem(input: { | ... | @@ -186,7 +185,7 @@ export function makeProviderFailureTurnItem(input: { |
| 186 | readonly occurredAt: DateTime.Utc; | 185 | readonly occurredAt: DateTime.Utc; |
| 187 | }): Extract<OrchestrationV2TurnItem, { readonly type: "error" }> { | 186 | }): Extract<OrchestrationV2TurnItem, { readonly type: "error" }> { |
| 188 | return { | 187 | return { |
| 189 | id: input.idAllocator.derive.turnItemFromProviderItem({ | 188 | id: IdAllocator.derive.turnItemFromProviderItem({ |
| 190 | driver: input.driver, | 189 | driver: input.driver, |
| 191 | nativeItemId: `terminal-failure:${input.providerTurnId}`, | 190 | nativeItemId: `terminal-failure:${input.providerTurnId}`, |
| 192 | }), | 191 | }), |
| ... | @@ -210,7 +209,6 @@ export function makeProviderFailureTurnItem(input: { | ... | @@ -210,7 +209,6 @@ export function makeProviderFailureTurnItem(input: { |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | export function makeProviderRetryTurnItem(input: { | 211 | export function makeProviderRetryTurnItem(input: { |
| 213 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | ||
| 214 | readonly driver: ProviderDriverKind; | 212 | readonly driver: ProviderDriverKind; |
| 215 | readonly threadId: ThreadId; | 213 | readonly threadId: ThreadId; |
| 216 | readonly runId: RunId | null; | 214 | readonly runId: RunId | null; |
| ... | @@ -237,7 +235,7 @@ export function makeProviderRetryTurnItem(input: { | ... | @@ -237,7 +235,7 @@ export function makeProviderRetryTurnItem(input: { |
| 237 | title = "Provider retry stopped"; | 235 | title = "Provider retry stopped"; |
| 238 | } | 236 | } |
| 239 | return { | 237 | return { |
| 240 | id: input.idAllocator.derive.turnItemFromProviderItem({ | 238 | id: IdAllocator.derive.turnItemFromProviderItem({ |
| 241 | driver: input.driver, | 239 | driver: input.driver, |
| 242 | nativeItemId: `terminal-failure:${input.providerTurnId}`, | 240 | nativeItemId: `terminal-failure:${input.providerTurnId}`, |
| 243 | }), | 241 | }), |
packages/provider-core/src/server/providerAuthFlow.test.ts created+559| ... | @@ -0,0 +1,559 @@ | ||
| 1 | import * as NodeServices from "@effect/platform-node/NodeServices"; | ||
| 2 | import { assert, it } from "@effect/vitest"; | ||
| 3 | import { | ||
| 4 | ProviderInstanceId, | ||
| 5 | ProviderSetupError, | ||
| 6 | type ProviderAuthInteraction, | ||
| 7 | type ProviderAuthResponse, | ||
| 8 | type ProviderAuthState, | ||
| 9 | } from "@t3tools/contracts"; | ||
| 10 | import * as Fiber from "effect/Fiber"; | ||
| 11 | import * as Exit from "effect/Exit"; | ||
| 12 | import * as Scope from "effect/Scope"; | ||
| 13 | import * as Deferred from "effect/Deferred"; | ||
| 14 | import * as Effect from "effect/Effect"; | ||
| 15 | import * as Option from "effect/Option"; | ||
| 16 | import * as Stream from "effect/Stream"; | ||
| 17 | import * as TestClock from "effect/testing/TestClock"; | ||
| 18 | |||
| 19 | import * as ProviderAuthFlow from "./providerAuthFlow.ts"; | ||
| 20 | |||
| 21 | const instanceId = ProviderInstanceId.make("auth-flow-test"); | ||
| 22 | const method = { id: "browser", name: "Browser", description: null, type: "agent" as const }; | ||
| 23 | |||
| 24 | it.effect("distinguishes pending method discovery from an agent with no sign-in methods", () => | ||
| 25 | Effect.gen(function* () { | ||
| 26 | const discovered = yield* Deferred.make<ReadonlyArray<typeof method>>(); | ||
| 27 | const controller = yield* ProviderAuthFlow.make({ | ||
| 28 | instanceId, | ||
| 29 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 30 | methods: Deferred.await(discovered), | ||
| 31 | authenticate: () => Effect.void, | ||
| 32 | logout: Effect.void, | ||
| 33 | }); | ||
| 34 | const pending = yield* controller | ||
| 35 | .subscribe("owner") | ||
| 36 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 37 | assert.isUndefined(pending.methods); | ||
| 38 | yield* Deferred.succeed(discovered, []); | ||
| 39 | const ready = yield* controller.subscribe("owner").pipe( | ||
| 40 | Stream.filter((state) => state.methods !== undefined), | ||
| 41 | Stream.runHead, | ||
| 42 | Effect.map(Option.getOrThrow), | ||
| 43 | ); | ||
| 44 | assert.deepEqual(ready.methods, []); | ||
| 45 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 46 | ); | ||
| 47 | |||
| 48 | const makeHarness = Effect.gen(function* () { | ||
| 49 | const approved = yield* Deferred.make<void>(); | ||
| 50 | const verified = yield* Deferred.make<void>(); | ||
| 51 | const started = yield* Deferred.make<void>(); | ||
| 52 | let attempts = 0; | ||
| 53 | const controller = yield* ProviderAuthFlow.make({ | ||
| 54 | instanceId, | ||
| 55 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 56 | methods: Effect.succeed([method]), | ||
| 57 | authenticate: (_, context) => | ||
| 58 | Effect.gen(function* () { | ||
| 59 | attempts++; | ||
| 60 | yield* context.setInteraction( | ||
| 61 | { | ||
| 62 | type: "browser", | ||
| 63 | id: "consent", | ||
| 64 | url: "https://example.com/login", | ||
| 65 | requiresConsent: true, | ||
| 66 | }, | ||
| 67 | (response) => | ||
| 68 | response.type === "browser" && response.action === "accept" | ||
| 69 | ? Deferred.succeed(approved, undefined).pipe(Effect.asVoid) | ||
| 70 | : Effect.void, | ||
| 71 | ); | ||
| 72 | yield* Deferred.succeed(started, undefined); | ||
| 73 | yield* Deferred.await(approved); | ||
| 74 | yield* context.verifying; | ||
| 75 | yield* Deferred.await(verified); | ||
| 76 | }), | ||
| 77 | logout: Effect.void, | ||
| 78 | }); | ||
| 79 | const phase = (phase: ProviderAuthState["phase"], owner = "owner") => | ||
| 80 | controller.subscribe(owner).pipe( | ||
| 81 | Stream.filter((state) => state.phase === phase), | ||
| 82 | Stream.runHead, | ||
| 83 | Effect.map(Option.getOrThrow), | ||
| 84 | ); | ||
| 85 | return { controller, phase, started, verified, attempts: () => attempts }; | ||
| 86 | }); | ||
| 87 | |||
| 88 | it.effect("requires owner consent and provider verification before success", () => | ||
| 89 | Effect.gen(function* () { | ||
| 90 | const { controller, phase, started, verified, attempts } = yield* makeHarness; | ||
| 91 | const state = yield* controller.start("owner"); | ||
| 92 | yield* Deferred.await(started); | ||
| 93 | const response = { | ||
| 94 | instanceId, | ||
| 95 | flowId: state.flowId!, | ||
| 96 | interactionId: "consent", | ||
| 97 | response: { type: "browser" as const, action: "accept" as const }, | ||
| 98 | }; | ||
| 99 | const other = yield* phase("waiting", "other"); | ||
| 100 | assert.isNull(other.interaction); | ||
| 101 | assert.isNull(other.flowId); | ||
| 102 | assert.isTrue( | ||
| 103 | (yield* controller.respond!("other", response).pipe(Effect.result))._tag === "Failure", | ||
| 104 | ); | ||
| 105 | assert.isTrue( | ||
| 106 | (yield* controller.respond!("owner", { ...response, interactionId: "stale" }).pipe( | ||
| 107 | Effect.result, | ||
| 108 | ))._tag === "Failure", | ||
| 109 | ); | ||
| 110 | yield* controller.start("owner"); | ||
| 111 | assert.strictEqual(attempts(), 1); | ||
| 112 | yield* controller.respond!("owner", response); | ||
| 113 | yield* phase("verifying"); | ||
| 114 | yield* Deferred.succeed(verified, undefined); | ||
| 115 | assert.strictEqual((yield* phase("succeeded")).phase, "succeeded"); | ||
| 116 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 117 | ); | ||
| 118 | |||
| 119 | it.effect("cancellation rejects late consent and permits another login", () => | ||
| 120 | Effect.gen(function* () { | ||
| 121 | const { controller, started, phase } = yield* makeHarness; | ||
| 122 | const state = yield* controller.start("owner"); | ||
| 123 | yield* Deferred.await(started); | ||
| 124 | yield* controller.cancel("owner", state.flowId!); | ||
| 125 | assert.strictEqual((yield* phase("cancelled")).phase, "cancelled"); | ||
| 126 | assert.isTrue( | ||
| 127 | (yield* controller.respond!("owner", { | ||
| 128 | instanceId, | ||
| 129 | flowId: state.flowId!, | ||
| 130 | interactionId: "consent", | ||
| 131 | response: { type: "browser", action: "accept" }, | ||
| 132 | }).pipe(Effect.result))._tag === "Failure", | ||
| 133 | ); | ||
| 134 | const next = yield* controller.start("other"); | ||
| 135 | assert.notStrictEqual(next.flowId, state.flowId); | ||
| 136 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 137 | ); | ||
| 138 | |||
| 139 | it.effect("expires pending login and rejects its response", () => | ||
| 140 | Effect.gen(function* () { | ||
| 141 | const { controller, started, phase } = yield* makeHarness; | ||
| 142 | const state = yield* controller.start("owner"); | ||
| 143 | yield* Deferred.await(started); | ||
| 144 | yield* TestClock.adjust(300_001); | ||
| 145 | assert.include((yield* phase("failed")).message ?? "", "expired"); | ||
| 146 | assert.isTrue( | ||
| 147 | (yield* controller.respond!("owner", { | ||
| 148 | instanceId, | ||
| 149 | flowId: state.flowId!, | ||
| 150 | interactionId: "consent", | ||
| 151 | response: { type: "browser", action: "accept" }, | ||
| 152 | }).pipe(Effect.result))._tag === "Failure", | ||
| 153 | ); | ||
| 154 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 155 | ); | ||
| 156 | |||
| 157 | it.effect("closes admitted provider processes and blocks new ones while login is pending", () => | ||
| 158 | Effect.gen(function* () { | ||
| 159 | const { controller, started } = yield* makeHarness; | ||
| 160 | let closed = false; | ||
| 161 | yield* controller.withAccess!( | ||
| 162 | Effect.addFinalizer(() => | ||
| 163 | Effect.sync(() => { | ||
| 164 | closed = true; | ||
| 165 | }), | ||
| 166 | ), | ||
| 167 | ); | ||
| 168 | yield* controller.start("owner"); | ||
| 169 | yield* Deferred.await(started); | ||
| 170 | assert.isTrue(closed); | ||
| 171 | assert.isTrue( | ||
| 172 | (yield* controller.withAccess!(Effect.void).pipe(Effect.result))._tag === "Failure", | ||
| 173 | ); | ||
| 174 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 175 | ); | ||
| 176 | |||
| 177 | it.effect("shared credential invalidation closes admitted processes before permitting reuse", () => | ||
| 178 | Effect.gen(function* () { | ||
| 179 | const { controller } = yield* makeHarness; | ||
| 180 | let closed = false; | ||
| 181 | yield* controller.withAccess!( | ||
| 182 | Effect.addFinalizer(() => | ||
| 183 | Effect.sync(() => { | ||
| 184 | closed = true; | ||
| 185 | }), | ||
| 186 | ), | ||
| 187 | ); | ||
| 188 | yield* controller.invalidate!; | ||
| 189 | assert.isTrue(closed); | ||
| 190 | assert.strictEqual(yield* controller.withAccess!(Effect.succeed("new process")), "new process"); | ||
| 191 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 192 | ); | ||
| 193 | |||
| 194 | it.effect.each([ | ||
| 195 | { | ||
| 196 | interaction: { type: "terminal", id: "terminal", output: "Log in" }, | ||
| 197 | response: { type: "terminal", data: "input", size: { cols: 80, rows: 24 } }, | ||
| 198 | }, | ||
| 199 | { | ||
| 200 | interaction: { | ||
| 201 | type: "credentials", | ||
| 202 | id: "credentials", | ||
| 203 | fields: [{ name: "token", label: "Token", secret: true }], | ||
| 204 | }, | ||
| 205 | response: { type: "credentials", values: { token: "private-token" } }, | ||
| 206 | }, | ||
| 207 | ] satisfies ReadonlyArray<{ | ||
| 208 | interaction: ProviderAuthInteraction; | ||
| 209 | response: ProviderAuthResponse; | ||
| 210 | }>)( | ||
| 211 | "keeps $interaction.type responses private and waits for adapter verification", | ||
| 212 | ({ interaction, response }) => | ||
| 213 | Effect.gen(function* () { | ||
| 214 | const received = yield* Deferred.make<ProviderAuthResponse>(); | ||
| 215 | const controller = yield* ProviderAuthFlow.make({ | ||
| 216 | instanceId, | ||
| 217 | credentialBinding: { owner: "t3", key: "binding" }, | ||
| 218 | methods: Effect.succeed([method]), | ||
| 219 | authenticate: (_, context) => | ||
| 220 | Effect.gen(function* () { | ||
| 221 | yield* context.setInteraction(interaction, (response) => | ||
| 222 | Deferred.succeed(received, response).pipe(Effect.asVoid), | ||
| 223 | ); | ||
| 224 | yield* Deferred.await(received); | ||
| 225 | yield* context.verifying; | ||
| 226 | return yield* Effect.never; | ||
| 227 | }), | ||
| 228 | logout: Effect.void, | ||
| 229 | }); | ||
| 230 | const state = yield* controller.start("owner"); | ||
| 231 | const pending = yield* controller.subscribe("owner").pipe( | ||
| 232 | Stream.filter((state) => state.phase === "waiting"), | ||
| 233 | Stream.runHead, | ||
| 234 | Effect.map(Option.getOrThrow), | ||
| 235 | ); | ||
| 236 | assert.deepStrictEqual(pending.interaction, interaction); | ||
| 237 | const hidden = yield* controller | ||
| 238 | .subscribe("other") | ||
| 239 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 240 | assert.isNull(hidden.interaction); | ||
| 241 | yield* controller.respond!("owner", { | ||
| 242 | instanceId, | ||
| 243 | flowId: state.flowId!, | ||
| 244 | interactionId: interaction.id, | ||
| 245 | response, | ||
| 246 | }); | ||
| 247 | assert.deepStrictEqual(yield* Deferred.await(received), response); | ||
| 248 | const verifying = yield* controller.subscribe("owner").pipe( | ||
| 249 | Stream.filter((state) => state.phase === "verifying"), | ||
| 250 | Stream.runHead, | ||
| 251 | Effect.map(Option.getOrThrow), | ||
| 252 | ); | ||
| 253 | assert.isNull(verifying.interaction); | ||
| 254 | assert.notInclude(verifying.message ?? "", "private-token"); | ||
| 255 | yield* controller.cancel("owner", state.flowId!); | ||
| 256 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 257 | ); | ||
| 258 | |||
| 259 | it.effect("shows a device code only to its owner without treating it as authenticated", () => | ||
| 260 | Effect.gen(function* () { | ||
| 261 | const controller = yield* ProviderAuthFlow.make({ | ||
| 262 | instanceId, | ||
| 263 | credentialBinding: { owner: "provider", key: "device" }, | ||
| 264 | methods: Effect.succeed([method]), | ||
| 265 | authenticate: (_, context) => | ||
| 266 | context | ||
| 267 | .setInteraction({ | ||
| 268 | type: "deviceCode", | ||
| 269 | id: "code", | ||
| 270 | url: "https://example.com/device", | ||
| 271 | userCode: "ABCD-EFGH", | ||
| 272 | }) | ||
| 273 | .pipe(Effect.andThen(Effect.never)), | ||
| 274 | logout: Effect.void, | ||
| 275 | }); | ||
| 276 | const start = yield* controller.start("owner"); | ||
| 277 | const waiting = yield* controller.subscribe("owner").pipe( | ||
| 278 | Stream.filter((state) => state.phase === "waiting"), | ||
| 279 | Stream.runHead, | ||
| 280 | Effect.map(Option.getOrThrow), | ||
| 281 | ); | ||
| 282 | assert.strictEqual(waiting.interaction?.type, "deviceCode"); | ||
| 283 | assert.strictEqual(waiting.authorizationUrl, "https://example.com/device"); | ||
| 284 | const other = yield* controller | ||
| 285 | .subscribe("other") | ||
| 286 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 287 | assert.isNull(other.interaction); | ||
| 288 | assert.isNull(other.authorizationUrl); | ||
| 289 | yield* controller.cancel("owner", start.flowId!); | ||
| 290 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 291 | ); | ||
| 292 | |||
| 293 | it.effect.each([ | ||
| 294 | { | ||
| 295 | failure: Effect.fail( | ||
| 296 | new ProviderSetupError({ | ||
| 297 | instanceId, | ||
| 298 | operation: "authenticate", | ||
| 299 | detail: "This account cannot sign in. Choose another account.", | ||
| 300 | }), | ||
| 301 | ), | ||
| 302 | message: "This account cannot sign in. Choose another account.", | ||
| 303 | }, | ||
| 304 | { | ||
| 305 | failure: Effect.die(new Error("private-token in native diagnostics")), | ||
| 306 | message: "Sign-in failed. Start again.", | ||
| 307 | }, | ||
| 308 | ])("publishes only safe authentication failure text %#", ({ failure, message }) => | ||
| 309 | Effect.gen(function* () { | ||
| 310 | const controller = yield* ProviderAuthFlow.make({ | ||
| 311 | instanceId, | ||
| 312 | credentialBinding: { owner: "t3", key: "failure" }, | ||
| 313 | methods: Effect.succeed([method]), | ||
| 314 | authenticate: () => failure, | ||
| 315 | logout: Effect.void, | ||
| 316 | }); | ||
| 317 | yield* controller.start("owner"); | ||
| 318 | const failed = yield* controller.subscribe("owner").pipe( | ||
| 319 | Stream.filter((state) => state.phase === "failed"), | ||
| 320 | Stream.runHead, | ||
| 321 | Effect.map(Option.getOrThrow), | ||
| 322 | ); | ||
| 323 | assert.strictEqual(failed.message, message); | ||
| 324 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 325 | ); | ||
| 326 | |||
| 327 | const makeBlockingResponseHarness = Effect.gen(function* () { | ||
| 328 | const entered = yield* Deferred.make<void>(); | ||
| 329 | const cleanupStarted = yield* Deferred.make<void>(); | ||
| 330 | const cleanupReleased = yield* Deferred.make<void>(); | ||
| 331 | const cleanupFinished = yield* Deferred.make<void>(); | ||
| 332 | const authenticationFinished = yield* Deferred.make<void>(); | ||
| 333 | let responses = 0; | ||
| 334 | const controller = yield* ProviderAuthFlow.make({ | ||
| 335 | instanceId, | ||
| 336 | credentialBinding: { owner: "t3", key: "blocked-response" }, | ||
| 337 | methods: Effect.succeed([method]), | ||
| 338 | authenticate: (_, context) => | ||
| 339 | Effect.gen(function* () { | ||
| 340 | yield* context.setInteraction( | ||
| 341 | { | ||
| 342 | type: "browser", | ||
| 343 | id: "blocked", | ||
| 344 | url: "https://example.com/login", | ||
| 345 | requiresConsent: true, | ||
| 346 | }, | ||
| 347 | () => | ||
| 348 | Effect.gen(function* () { | ||
| 349 | responses++; | ||
| 350 | yield* Deferred.succeed(entered, undefined); | ||
| 351 | return yield* Effect.never; | ||
| 352 | }).pipe( | ||
| 353 | Effect.ensuring( | ||
| 354 | Effect.gen(function* () { | ||
| 355 | yield* Deferred.succeed(cleanupStarted, undefined); | ||
| 356 | yield* Deferred.await(cleanupReleased); | ||
| 357 | yield* Deferred.succeed(cleanupFinished, undefined); | ||
| 358 | }), | ||
| 359 | ), | ||
| 360 | ), | ||
| 361 | ); | ||
| 362 | yield* Deferred.await(authenticationFinished); | ||
| 363 | }), | ||
| 364 | logout: Effect.void, | ||
| 365 | }); | ||
| 366 | const start = yield* controller.start("owner"); | ||
| 367 | yield* controller.subscribe("owner").pipe( | ||
| 368 | Stream.filter((state) => state.phase === "waiting"), | ||
| 369 | Stream.runHead, | ||
| 370 | ); | ||
| 371 | const input = { | ||
| 372 | instanceId, | ||
| 373 | flowId: start.flowId!, | ||
| 374 | interactionId: "blocked", | ||
| 375 | response: { type: "browser" as const, action: "accept" as const }, | ||
| 376 | }; | ||
| 377 | const response = yield* controller.respond!("owner", input).pipe(Effect.exit, Effect.forkChild); | ||
| 378 | yield* Deferred.await(entered); | ||
| 379 | return { | ||
| 380 | controller, | ||
| 381 | input, | ||
| 382 | response, | ||
| 383 | cleanupStarted, | ||
| 384 | cleanupReleased, | ||
| 385 | cleanupFinished, | ||
| 386 | authenticationFinished, | ||
| 387 | responses: () => responses, | ||
| 388 | }; | ||
| 389 | }); | ||
| 390 | |||
| 391 | it.effect.each(["cancel", "logout"] as const)( | ||
| 392 | "%s interrupts and awaits a blocked adapter response before admitting another sign-in", | ||
| 393 | (action) => | ||
| 394 | Effect.gen(function* () { | ||
| 395 | const harness = yield* makeBlockingResponseHarness; | ||
| 396 | const duplicate = yield* Effect.flip(harness.controller.respond!("owner", harness.input)); | ||
| 397 | assert.include(duplicate.detail, "already in progress"); | ||
| 398 | assert.equal(harness.responses(), 1); | ||
| 399 | const stopping = yield* ( | ||
| 400 | action === "cancel" | ||
| 401 | ? harness.controller.cancel("owner", harness.input.flowId) | ||
| 402 | : harness.controller.logout(Effect.void) | ||
| 403 | ).pipe(Effect.forkChild); | ||
| 404 | yield* Deferred.await(harness.cleanupStarted); | ||
| 405 | assert.isTrue(yield* harness.controller.isChangingCredentials!); | ||
| 406 | assert.isUndefined(stopping.pollUnsafe()); | ||
| 407 | const premature = yield* Effect.flip(harness.controller.start("other")); | ||
| 408 | assert.include(premature.detail, "in progress"); | ||
| 409 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 410 | yield* Fiber.join(stopping); | ||
| 411 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 412 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 413 | assert.isFalse(yield* harness.controller.isChangingCredentials!); | ||
| 414 | assert.notEqual((yield* harness.controller.start("other")).flowId, harness.input.flowId); | ||
| 415 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 416 | ); | ||
| 417 | |||
| 418 | it.effect("timeout interrupts and drains a blocked response before publishing failure", () => | ||
| 419 | Effect.gen(function* () { | ||
| 420 | const harness = yield* makeBlockingResponseHarness; | ||
| 421 | yield* TestClock.adjust(300_001); | ||
| 422 | yield* Deferred.await(harness.cleanupStarted); | ||
| 423 | assert.isTrue(yield* harness.controller.isChangingCredentials!); | ||
| 424 | const duringCleanup = yield* harness.controller | ||
| 425 | .subscribe("owner") | ||
| 426 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 427 | assert.notEqual(duringCleanup.phase, "failed"); | ||
| 428 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 429 | const failed = yield* harness.controller.subscribe("owner").pipe( | ||
| 430 | Stream.filter((state) => state.phase === "failed"), | ||
| 431 | Stream.runHead, | ||
| 432 | Effect.map(Option.getOrThrow), | ||
| 433 | ); | ||
| 434 | assert.include(failed.message ?? "", "expired"); | ||
| 435 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 436 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 437 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 438 | ); | ||
| 439 | |||
| 440 | it.effect( | ||
| 441 | "successful authentication drains a still-running response before admitting provider access", | ||
| 442 | () => | ||
| 443 | Effect.gen(function* () { | ||
| 444 | const harness = yield* makeBlockingResponseHarness; | ||
| 445 | yield* Deferred.succeed(harness.authenticationFinished, undefined); | ||
| 446 | yield* Deferred.await(harness.cleanupStarted); | ||
| 447 | const denied = yield* Effect.flip(harness.controller.withAccess!(Effect.void)); | ||
| 448 | assert.include(denied.detail, "changing"); | ||
| 449 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 450 | const succeeded = yield* harness.controller.subscribe("owner").pipe( | ||
| 451 | Stream.filter((state) => state.phase === "succeeded"), | ||
| 452 | Stream.runHead, | ||
| 453 | Effect.map(Option.getOrThrow), | ||
| 454 | ); | ||
| 455 | assert.equal(succeeded.phase, "succeeded"); | ||
| 456 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 457 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 458 | yield* harness.controller.withAccess!(Effect.void); | ||
| 459 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 460 | ); | ||
| 461 | |||
| 462 | it.effect("closing the controller scope interrupts and drains its adapter response", () => | ||
| 463 | Effect.gen(function* () { | ||
| 464 | const scope = yield* Scope.make(); | ||
| 465 | const harness = yield* makeBlockingResponseHarness.pipe( | ||
| 466 | Effect.provideService(Scope.Scope, scope), | ||
| 467 | ); | ||
| 468 | const closing = yield* Scope.close(scope, Exit.void).pipe(Effect.forkChild); | ||
| 469 | yield* Deferred.await(harness.cleanupStarted); | ||
| 470 | assert.isUndefined(closing.pollUnsafe()); | ||
| 471 | yield* Deferred.succeed(harness.cleanupReleased, undefined); | ||
| 472 | yield* Fiber.join(closing); | ||
| 473 | assert.isTrue(yield* Deferred.isDone(harness.cleanupFinished)); | ||
| 474 | assert.isTrue(Exit.isFailure(yield* Fiber.join(harness.response))); | ||
| 475 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 476 | ); | ||
| 477 | |||
| 478 | it.effect("a failed method refresh keeps the last discovered methods", () => | ||
| 479 | Effect.gen(function* () { | ||
| 480 | let fail = false; | ||
| 481 | const controller = yield* ProviderAuthFlow.make({ | ||
| 482 | instanceId, | ||
| 483 | credentialBinding: { owner: "provider", key: "shared-agent" }, | ||
| 484 | methods: Effect.suspend(() => | ||
| 485 | fail | ||
| 486 | ? Effect.fail( | ||
| 487 | new ProviderSetupError({ instanceId, operation: "status", detail: "interrupted" }), | ||
| 488 | ) | ||
| 489 | : Effect.succeed([method]), | ||
| 490 | ), | ||
| 491 | authenticate: () => Effect.void, | ||
| 492 | logout: Effect.void, | ||
| 493 | }); | ||
| 494 | yield* controller.refreshMethods!; | ||
| 495 | fail = true; | ||
| 496 | yield* controller.refreshMethods!; | ||
| 497 | const state = yield* controller | ||
| 498 | .subscribe("owner") | ||
| 499 | .pipe(Stream.runHead, Effect.map(Option.getOrThrow)); | ||
| 500 | assert.deepEqual(state.methods, [method]); | ||
| 501 | assert.strictEqual(state.message, "interrupted"); | ||
| 502 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 503 | ); | ||
| 504 | |||
| 505 | it.effect("rebuilding a controller leaves sessions it admitted to their owners", () => | ||
| 506 | Effect.gen(function* () { | ||
| 507 | const scope = yield* Scope.make(); | ||
| 508 | const { controller } = yield* makeHarness.pipe(Effect.provideService(Scope.Scope, scope)); | ||
| 509 | let closed = false; | ||
| 510 | yield* controller.withAccess!( | ||
| 511 | Effect.addFinalizer(() => | ||
| 512 | Effect.sync(() => { | ||
| 513 | closed = true; | ||
| 514 | }), | ||
| 515 | ), | ||
| 516 | ); | ||
| 517 | yield* Scope.close(scope, Exit.void); | ||
| 518 | assert.isFalse(closed); | ||
| 519 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 520 | ); | ||
| 521 | |||
| 522 | it.effect("profile import stops owned sessions and gates access until credentials are saved", () => | ||
| 523 | Effect.gen(function* () { | ||
| 524 | const controller = yield* ProviderAuthFlow.make({ | ||
| 525 | instanceId, | ||
| 526 | credentialBinding: { owner: "t3", key: "handoff-binding" }, | ||
| 527 | methods: Effect.succeed([method]), | ||
| 528 | authenticate: () => Effect.void, | ||
| 529 | logout: Effect.void, | ||
| 530 | }); | ||
| 531 | let closed = false; | ||
| 532 | yield* controller.withAccess!( | ||
| 533 | Effect.addFinalizer(() => | ||
| 534 | Effect.sync(() => { | ||
| 535 | closed = true; | ||
| 536 | }), | ||
| 537 | ), | ||
| 538 | ); | ||
| 539 | const writing = yield* Deferred.make<void>(); | ||
| 540 | const release = yield* Deferred.make<void>(); | ||
| 541 | const imported = yield* controller.adoptCredentials!( | ||
| 542 | Deferred.succeed(writing, undefined).pipe(Effect.andThen(Deferred.await(release))), | ||
| 543 | Effect.sync(() => { | ||
| 544 | assert.isTrue(closed); | ||
| 545 | }), | ||
| 546 | ).pipe(Effect.forkChild); | ||
| 547 | yield* Deferred.await(writing); | ||
| 548 | const denied = yield* controller.withAccess!(Effect.succeed("old credential process")).pipe( | ||
| 549 | Effect.result, | ||
| 550 | ); | ||
| 551 | assert.strictEqual(denied._tag, "Failure"); | ||
| 552 | yield* Deferred.succeed(release, undefined); | ||
| 553 | assert.strictEqual((yield* Fiber.join(imported)).phase, "succeeded"); | ||
| 554 | assert.strictEqual( | ||
| 555 | yield* controller.withAccess!(Effect.succeed("new credential process")), | ||
| 556 | "new credential process", | ||
| 557 | ); | ||
| 558 | }).pipe(Effect.scoped, Effect.provide(NodeServices.layer)), | ||
| 559 | ); | ||
packages/provider-core/src/server/providerAuthFlow.ts created+525| ... | @@ -0,0 +1,525 @@ | ||
| 1 | import { | ||
| 2 | ProviderSetupError, | ||
| 3 | type ProviderAuthInteraction, | ||
| 4 | type ProviderAuthMethod, | ||
| 5 | type ProviderAuthResponse, | ||
| 6 | type ProviderAuthState, | ||
| 7 | type ProviderInstanceId, | ||
| 8 | } from "@t3tools/contracts"; | ||
| 9 | import * as Cause from "effect/Cause"; | ||
| 10 | import * as Option from "effect/Option"; | ||
| 11 | import * as Schema from "effect/Schema"; | ||
| 12 | import * as Clock from "effect/Clock"; | ||
| 13 | import * as Crypto from "effect/Crypto"; | ||
| 14 | import * as DateTime from "effect/DateTime"; | ||
| 15 | import * as Effect from "effect/Effect"; | ||
| 16 | import * as Deferred from "effect/Deferred"; | ||
| 17 | import * as Exit from "effect/Exit"; | ||
| 18 | import * as Fiber from "effect/Fiber"; | ||
| 19 | import * as Scope from "effect/Scope"; | ||
| 20 | import * as Semaphore from "effect/Semaphore"; | ||
| 21 | import * as Stream from "effect/Stream"; | ||
| 22 | import * as SubscriptionRef from "effect/SubscriptionRef"; | ||
| 23 | |||
| 24 | import type * as ProviderAuth from "./auth.ts"; | ||
| 25 | |||
| 26 | export interface ProviderAuthFlowContext { | ||
| 27 | readonly flowId: string; | ||
| 28 | /** The lifetime timeout interrupts authenticate before publishing its expired result. */ | ||
| 29 | readonly expiresAt: number; | ||
| 30 | readonly returnUrl?: string; | ||
| 31 | readonly callbackMode?: "server" | "client"; | ||
| 32 | readonly setInteraction: ( | ||
| 33 | interaction: ProviderAuthInteraction, | ||
| 34 | respond?: (response: ProviderAuthResponse) => Effect.Effect<void, ProviderSetupError>, | ||
| 35 | complete?: (callbackUrl: string) => Effect.Effect<void, ProviderSetupError>, | ||
| 36 | ) => Effect.Effect<void>; | ||
| 37 | readonly verifying: Effect.Effect<void>; | ||
| 38 | } | ||
| 39 | |||
| 40 | const isSetupError = Schema.is(ProviderSetupError); | ||
| 41 | |||
| 42 | const failureMessage = (cause: Cause.Cause<ProviderSetupError>) => { | ||
| 43 | const error = Cause.findErrorOption(cause); | ||
| 44 | return Option.isSome(error) && isSetupError(error.value) | ||
| 45 | ? error.value.detail | ||
| 46 | : "Sign-in failed. Start again."; | ||
| 47 | }; | ||
| 48 | |||
| 49 | interface Flow { | ||
| 50 | readonly id: string; | ||
| 51 | readonly owner: string; | ||
| 52 | readonly expiresAt: number; | ||
| 53 | complete?: ((callbackUrl: string) => Effect.Effect<void, ProviderSetupError>) | undefined; | ||
| 54 | fiber?: Fiber.Fiber<void>; | ||
| 55 | responseFiber?: Fiber.Fiber<void, ProviderSetupError>; | ||
| 56 | respond: | ||
| 57 | | ((response: ProviderAuthResponse) => Effect.Effect<void, ProviderSetupError>) | ||
| 58 | | undefined; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** Adapters do login and credential handling; this owns client consent and flow lifetime. */ | ||
| 62 | export const make = Effect.fn("ProviderAuthFlow.make")(function* (options: { | ||
| 63 | readonly instanceId: ProviderInstanceId; | ||
| 64 | readonly credentialBinding: NonNullable<ProviderAuth.ProviderAuthController["credentialBinding"]>; | ||
| 65 | readonly methods: Effect.Effect<ReadonlyArray<ProviderAuthMethod>, ProviderSetupError>; | ||
| 66 | readonly defaultMethodId?: string; | ||
| 67 | /** Stored account profiles can change the advertised methods after auth/logout. */ | ||
| 68 | readonly refreshMethodsAfterAuth?: boolean; | ||
| 69 | /** Fail with ProviderSetupError containing safe text for the user, never native token data. */ | ||
| 70 | readonly authenticate: ( | ||
| 71 | methodId: string, | ||
| 72 | context: ProviderAuthFlowContext, | ||
| 73 | ) => Effect.Effect<void, ProviderSetupError, Scope.Scope>; | ||
| 74 | readonly logout: Effect.Effect<void | string, ProviderSetupError>; | ||
| 75 | readonly timeoutMs?: number; | ||
| 76 | }) { | ||
| 77 | const scope = yield* Scope.Scope; | ||
| 78 | const crypto = yield* Crypto.Crypto; | ||
| 79 | const lock = yield* Semaphore.make(1); | ||
| 80 | const timeoutMs = options.timeoutMs ?? 300_000; | ||
| 81 | const empty: ProviderAuthState = { | ||
| 82 | instanceId: options.instanceId, | ||
| 83 | phase: "idle", | ||
| 84 | flowId: null, | ||
| 85 | authorizationUrl: null, | ||
| 86 | expiresAt: null, | ||
| 87 | message: null, | ||
| 88 | interaction: null, | ||
| 89 | credentialOwner: options.credentialBinding.owner, | ||
| 90 | }; | ||
| 91 | const snapshot = yield* SubscriptionRef.make({ owner: null as string | null, state: empty }); | ||
| 92 | let active: Flow | undefined; | ||
| 93 | let operation: "idle" | "auth" | "stopping" | "closed" = "idle"; | ||
| 94 | const sessions = new Set<Scope.Closeable>(); | ||
| 95 | const stopOwnedSessions = Effect.suspend(() => | ||
| 96 | Effect.forEach(Array.from(sessions), (session) => Scope.close(session, Exit.void), { | ||
| 97 | discard: true, | ||
| 98 | concurrency: "unbounded", | ||
| 99 | }), | ||
| 100 | ); | ||
| 101 | const publish = (flow: Flow, patch: Partial<ProviderAuthState>) => | ||
| 102 | Effect.suspend(() => | ||
| 103 | active === flow | ||
| 104 | ? SubscriptionRef.update(snapshot, (current) => ({ | ||
| 105 | owner: flow.owner, | ||
| 106 | state: { ...current.state, ...patch }, | ||
| 107 | })) | ||
| 108 | : Effect.void, | ||
| 109 | ); | ||
| 110 | |||
| 111 | const requireFlow = Effect.fnUntraced(function* (owner: string, id: string) { | ||
| 112 | if ( | ||
| 113 | operation !== "auth" || | ||
| 114 | !active || | ||
| 115 | active.owner !== owner || | ||
| 116 | active.id !== id || | ||
| 117 | (yield* Clock.currentTimeMillis) >= active.expiresAt | ||
| 118 | ) { | ||
| 119 | return yield* new ProviderSetupError({ | ||
| 120 | instanceId: options.instanceId, | ||
| 121 | operation: "respond", | ||
| 122 | detail: "This sign-in is no longer active in this client.", | ||
| 123 | }); | ||
| 124 | } | ||
| 125 | return active; | ||
| 126 | }); | ||
| 127 | |||
| 128 | // Method discovery does not start a sign-in flow. | ||
| 129 | const refreshMethods = options.methods.pipe( | ||
| 130 | Effect.flatMap((methods) => | ||
| 131 | SubscriptionRef.update(snapshot, (current) => ({ | ||
| 132 | ...current, | ||
| 133 | state: { ...current.state, methods }, | ||
| 134 | })), | ||
| 135 | ), | ||
| 136 | // Keep the last known methods when a refresh fails or is interrupted. | ||
| 137 | Effect.catch((error) => | ||
| 138 | SubscriptionRef.update(snapshot, (current) => ({ | ||
| 139 | ...current, | ||
| 140 | state: { ...current.state, methods: current.state.methods ?? [], message: error.detail }, | ||
| 141 | })), | ||
| 142 | ), | ||
| 143 | ); | ||
| 144 | yield* refreshMethods.pipe(Effect.forkIn(scope)); | ||
| 145 | |||
| 146 | const controller: ProviderAuth.ProviderAuthController = { | ||
| 147 | credentialBinding: options.credentialBinding, | ||
| 148 | adoptCredentials: (update, stopSessions) => | ||
| 149 | Effect.gen(function* () { | ||
| 150 | yield* lock.withPermit( | ||
| 151 | Effect.gen(function* () { | ||
| 152 | if (operation !== "idle") | ||
| 153 | return yield* new ProviderSetupError({ | ||
| 154 | instanceId: options.instanceId, | ||
| 155 | operation: "import", | ||
| 156 | detail: "Finish or cancel the existing sign-in first.", | ||
| 157 | }); | ||
| 158 | operation = "stopping"; | ||
| 159 | }), | ||
| 160 | ); | ||
| 161 | const result = yield* Effect.gen(function* () { | ||
| 162 | yield* stopOwnedSessions; | ||
| 163 | yield* stopSessions; | ||
| 164 | yield* update; | ||
| 165 | yield* refreshMethods; | ||
| 166 | }).pipe(Effect.exit); | ||
| 167 | const state: ProviderAuthState = { | ||
| 168 | ...empty, | ||
| 169 | methods: snapshot.value.state.methods ?? [], | ||
| 170 | phase: Exit.isSuccess(result) ? "succeeded" : "failed", | ||
| 171 | message: Exit.isSuccess(result) ? null : failureMessage(result.cause), | ||
| 172 | }; | ||
| 173 | yield* lock.withPermit( | ||
| 174 | Effect.gen(function* () { | ||
| 175 | yield* SubscriptionRef.set(snapshot, { owner: null, state }); | ||
| 176 | operation = "idle"; | ||
| 177 | }), | ||
| 178 | ); | ||
| 179 | if (Exit.isFailure(result)) return yield* Effect.failCause(result.cause); | ||
| 180 | return state; | ||
| 181 | }).pipe(Effect.uninterruptible), | ||
| 182 | refreshMethods, | ||
| 183 | invalidate: lock.withPermit( | ||
| 184 | Effect.gen(function* () { | ||
| 185 | if (operation !== "idle") return; | ||
| 186 | yield* stopOwnedSessions; | ||
| 187 | yield* SubscriptionRef.set(snapshot, { | ||
| 188 | owner: null, | ||
| 189 | state: { | ||
| 190 | ...empty, | ||
| 191 | methods: snapshot.value.state.methods ?? [], | ||
| 192 | message: "This provider's shared sign-in changed.", | ||
| 193 | }, | ||
| 194 | }); | ||
| 195 | }), | ||
| 196 | ), | ||
| 197 | isChangingCredentials: Effect.sync(() => operation !== "idle"), | ||
| 198 | withAccess: (task) => | ||
| 199 | Effect.uninterruptibleMask((restore) => | ||
| 200 | Effect.gen(function* () { | ||
| 201 | const parent = yield* Scope.Scope; | ||
| 202 | const child = yield* lock.withPermit( | ||
| 203 | Effect.gen(function* () { | ||
| 204 | if (operation !== "idle") | ||
| 205 | return yield* new ProviderSetupError({ | ||
| 206 | instanceId: options.instanceId, | ||
| 207 | operation: "session", | ||
| 208 | detail: "Provider sign-in is changing. Try again after it finishes.", | ||
| 209 | }); | ||
| 210 | const child = yield* Scope.make(); | ||
| 211 | sessions.add(child); | ||
| 212 | yield* Scope.addFinalizer( | ||
| 213 | child, | ||
| 214 | Effect.sync(() => { | ||
| 215 | sessions.delete(child); | ||
| 216 | }), | ||
| 217 | ); | ||
| 218 | yield* Scope.addFinalizer(parent, Scope.close(child, Exit.void)); | ||
| 219 | return child; | ||
| 220 | }), | ||
| 221 | ); | ||
| 222 | const fiber = yield* restore(task).pipe( | ||
| 223 | Effect.provideService(Scope.Scope, child), | ||
| 224 | Effect.forkIn(child), | ||
| 225 | ); | ||
| 226 | return yield* restore(Fiber.await(fiber)).pipe( | ||
| 227 | Effect.flatMap((result) => result), | ||
| 228 | Effect.onExit((result) => | ||
| 229 | Exit.isFailure(result) ? Scope.close(child, Exit.void) : Effect.void, | ||
| 230 | ), | ||
| 231 | ); | ||
| 232 | }), | ||
| 233 | ), | ||
| 234 | start: (owner, stopSessions = Effect.void, selectedMethodId, returnUrl, callbackMode) => | ||
| 235 | lock.withPermit( | ||
| 236 | Effect.gen(function* () { | ||
| 237 | if (operation === "auth" && active?.owner === owner) return snapshot.value.state; | ||
| 238 | if (operation !== "idle") | ||
| 239 | return yield* new ProviderSetupError({ | ||
| 240 | instanceId: options.instanceId, | ||
| 241 | operation: "start", | ||
| 242 | detail: "Provider setup is already in progress.", | ||
| 243 | }); | ||
| 244 | const id = yield* crypto.randomUUIDv4.pipe( | ||
| 245 | Effect.mapError( | ||
| 246 | () => | ||
| 247 | new ProviderSetupError({ | ||
| 248 | instanceId: options.instanceId, | ||
| 249 | operation: "start", | ||
| 250 | detail: "Could not start sign-in. Try again.", | ||
| 251 | }), | ||
| 252 | ), | ||
| 253 | ); | ||
| 254 | const flow: Flow = { | ||
| 255 | id, | ||
| 256 | owner, | ||
| 257 | expiresAt: (yield* Clock.currentTimeMillis) + timeoutMs, | ||
| 258 | respond: undefined, | ||
| 259 | }; | ||
| 260 | active = flow; | ||
| 261 | operation = "auth"; | ||
| 262 | const state: ProviderAuthState = { | ||
| 263 | ...empty, | ||
| 264 | methods: snapshot.value.state.methods ?? [], | ||
| 265 | phase: "starting", | ||
| 266 | flowId: id, | ||
| 267 | expiresAt: DateTime.formatIso(DateTime.makeUnsafe(flow.expiresAt)), | ||
| 268 | message: "Starting sign-in.", | ||
| 269 | }; | ||
| 270 | yield* SubscriptionRef.set(snapshot, { owner, state }); | ||
| 271 | flow.fiber = yield* Effect.gen(function* () { | ||
| 272 | const methods = yield* options.methods; | ||
| 273 | yield* publish(flow, { methods }); | ||
| 274 | const methodId = selectedMethodId ?? options.defaultMethodId ?? methods[0]?.id; | ||
| 275 | if (!methodId || !methods.some((method) => method.id === methodId)) | ||
| 276 | return yield* new ProviderSetupError({ | ||
| 277 | instanceId: options.instanceId, | ||
| 278 | operation: "start", | ||
| 279 | detail: "The provider did not advertise this sign-in method.", | ||
| 280 | }); | ||
| 281 | yield* stopSessions.pipe(Effect.ensuring(stopOwnedSessions)); | ||
| 282 | yield* options.authenticate(methodId, { | ||
| 283 | flowId: id, | ||
| 284 | expiresAt: flow.expiresAt, | ||
| 285 | ...(returnUrl ? { returnUrl } : {}), | ||
| 286 | ...(callbackMode ? { callbackMode } : {}), | ||
| 287 | setInteraction: (interaction, respond, complete) => | ||
| 288 | Effect.gen(function* () { | ||
| 289 | if (active !== flow) return; | ||
| 290 | flow.respond = respond; | ||
| 291 | flow.complete = complete; | ||
| 292 | yield* publish(flow, { | ||
| 293 | phase: "waiting", | ||
| 294 | interaction, | ||
| 295 | authorizationUrl: | ||
| 296 | interaction.type === "browser" || interaction.type === "deviceCode" | ||
| 297 | ? interaction.url | ||
| 298 | : null, | ||
| 299 | message: "Complete sign-in to continue.", | ||
| 300 | }); | ||
| 301 | }), | ||
| 302 | verifying: Effect.gen(function* () { | ||
| 303 | flow.respond = undefined; | ||
| 304 | flow.complete = undefined; | ||
| 305 | yield* publish(flow, { | ||
| 306 | phase: "verifying", | ||
| 307 | interaction: null, | ||
| 308 | authorizationUrl: null, | ||
| 309 | message: "Checking provider sign-in.", | ||
| 310 | }); | ||
| 311 | }), | ||
| 312 | }); | ||
| 313 | }).pipe( | ||
| 314 | Effect.scoped, | ||
| 315 | Effect.timeoutOrElse({ | ||
| 316 | duration: timeoutMs, | ||
| 317 | orElse: () => | ||
| 318 | Effect.fail( | ||
| 319 | new ProviderSetupError({ | ||
| 320 | instanceId: options.instanceId, | ||
| 321 | operation: "start", | ||
| 322 | detail: "Sign-in expired. Start again.", | ||
| 323 | }), | ||
| 324 | ), | ||
| 325 | }), | ||
| 326 | Effect.exit, | ||
| 327 | Effect.flatMap((result) => | ||
| 328 | Effect.gen(function* () { | ||
| 329 | const finishing = yield* lock.withPermit( | ||
| 330 | Effect.sync(() => { | ||
| 331 | if (active !== flow) return false; | ||
| 332 | operation = "stopping"; | ||
| 333 | return true; | ||
| 334 | }), | ||
| 335 | ); | ||
| 336 | if (!finishing) return; | ||
| 337 | if (flow.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 338 | yield* lock.withPermit( | ||
| 339 | Effect.gen(function* () { | ||
| 340 | if (active !== flow) return; | ||
| 341 | if (options.refreshMethodsAfterAuth) yield* refreshMethods; | ||
| 342 | yield* publish(flow, { | ||
| 343 | phase: Exit.isSuccess(result) ? "succeeded" : "failed", | ||
| 344 | interaction: null, | ||
| 345 | authorizationUrl: null, | ||
| 346 | expiresAt: null, | ||
| 347 | message: Exit.isSuccess(result) | ||
| 348 | ? "Sign-in complete." | ||
| 349 | : failureMessage(result.cause), | ||
| 350 | }); | ||
| 351 | active = undefined; | ||
| 352 | operation = "idle"; | ||
| 353 | }), | ||
| 354 | ); | ||
| 355 | }), | ||
| 356 | ), | ||
| 357 | Effect.interruptible, | ||
| 358 | Effect.forkIn(scope), | ||
| 359 | ); | ||
| 360 | return state; | ||
| 361 | }).pipe(Effect.uninterruptible), | ||
| 362 | ), | ||
| 363 | respond: (owner, input) => | ||
| 364 | Effect.uninterruptibleMask((restore) => | ||
| 365 | Effect.gen(function* () { | ||
| 366 | const { flow, fiber, ready } = yield* lock.withPermit( | ||
| 367 | Effect.gen(function* () { | ||
| 368 | const flow = yield* requireFlow(owner, input.flowId); | ||
| 369 | const interaction = snapshot.value.state.interaction; | ||
| 370 | if ( | ||
| 371 | !interaction || | ||
| 372 | interaction.id !== input.interactionId || | ||
| 373 | interaction.type !== input.response.type || | ||
| 374 | !flow.respond | ||
| 375 | ) | ||
| 376 | return yield* new ProviderSetupError({ | ||
| 377 | instanceId: options.instanceId, | ||
| 378 | operation: "respond", | ||
| 379 | detail: "This sign-in interaction is no longer available.", | ||
| 380 | }); | ||
| 381 | if (flow.responseFiber) | ||
| 382 | return yield* new ProviderSetupError({ | ||
| 383 | instanceId: options.instanceId, | ||
| 384 | operation: "respond", | ||
| 385 | detail: "A sign-in response is already in progress.", | ||
| 386 | }); | ||
| 387 | const ready = yield* Deferred.make<void>(); | ||
| 388 | const callback = flow.respond; | ||
| 389 | const fiber = yield* Deferred.await(ready).pipe( | ||
| 390 | Effect.andThen(Effect.suspend(() => callback(input.response))), | ||
| 391 | Effect.interruptible, | ||
| 392 | Effect.forkIn(scope), | ||
| 393 | ); | ||
| 394 | flow.responseFiber = fiber; | ||
| 395 | return { flow, fiber, ready }; | ||
| 396 | }), | ||
| 397 | ); | ||
| 398 | yield* Deferred.succeed(ready, undefined); | ||
| 399 | yield* restore(Fiber.join(fiber)).pipe( | ||
| 400 | Effect.onInterrupt(() => Fiber.interrupt(fiber).pipe(Effect.asVoid)), | ||
| 401 | Effect.ensuring( | ||
| 402 | lock.withPermit( | ||
| 403 | Effect.sync(() => { | ||
| 404 | if (flow.responseFiber === fiber) delete flow.responseFiber; | ||
| 405 | }), | ||
| 406 | ), | ||
| 407 | ), | ||
| 408 | ); | ||
| 409 | return snapshot.value.state; | ||
| 410 | }), | ||
| 411 | ), | ||
| 412 | complete: (owner, input) => | ||
| 413 | lock.withPermit( | ||
| 414 | Effect.gen(function* () { | ||
| 415 | const flow = yield* requireFlow(owner, input.flowId); | ||
| 416 | const interaction = snapshot.value.state.interaction; | ||
| 417 | if ( | ||
| 418 | snapshot.value.state.phase !== "waiting" || | ||
| 419 | interaction?.type !== "browser" || | ||
| 420 | !interaction.acceptsCallback || | ||
| 421 | !flow.complete | ||
| 422 | ) | ||
| 423 | return yield* new ProviderSetupError({ | ||
| 424 | instanceId: options.instanceId, | ||
| 425 | operation: "complete", | ||
| 426 | detail: "This sign-in does not accept a redirect URL.", | ||
| 427 | }); | ||
| 428 | yield* flow.complete(input.callbackUrl); | ||
| 429 | return snapshot.value.state; | ||
| 430 | }), | ||
| 431 | ), | ||
| 432 | cancel: (owner, id) => | ||
| 433 | Effect.gen(function* () { | ||
| 434 | const flow = yield* lock.withPermit( | ||
| 435 | Effect.gen(function* () { | ||
| 436 | const flow = yield* requireFlow(owner, id); | ||
| 437 | yield* publish(flow, { | ||
| 438 | phase: "cancelled", | ||
| 439 | interaction: null, | ||
| 440 | authorizationUrl: null, | ||
| 441 | expiresAt: null, | ||
| 442 | message: "Sign-in cancelled.", | ||
| 443 | }); | ||
| 444 | active = undefined; | ||
| 445 | operation = "stopping"; | ||
| 446 | return flow; | ||
| 447 | }), | ||
| 448 | ); | ||
| 449 | if (flow.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 450 | if (flow.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 451 | operation = "idle"; | ||
| 452 | return snapshot.value.state; | ||
| 453 | }).pipe(Effect.uninterruptible), | ||
| 454 | logout: (stopSessions) => | ||
| 455 | Effect.gen(function* () { | ||
| 456 | const flow = yield* lock.withPermit( | ||
| 457 | Effect.gen(function* () { | ||
| 458 | if (operation !== "idle" && operation !== "auth") | ||
| 459 | return yield* new ProviderSetupError({ | ||
| 460 | instanceId: options.instanceId, | ||
| 461 | operation: "logout", | ||
| 462 | detail: "Provider setup is already stopping.", | ||
| 463 | }); | ||
| 464 | operation = "stopping"; | ||
| 465 | const flow = active; | ||
| 466 | active = undefined; | ||
| 467 | return flow; | ||
| 468 | }), | ||
| 469 | ); | ||
| 470 | const result = yield* Effect.gen(function* () { | ||
| 471 | if (flow?.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 472 | if (flow?.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 473 | yield* stopSessions.pipe(Effect.ensuring(stopOwnedSessions)); | ||
| 474 | const message = yield* options.logout; | ||
| 475 | if (options.refreshMethodsAfterAuth) yield* refreshMethods; | ||
| 476 | return message; | ||
| 477 | }).pipe(Effect.exit); | ||
| 478 | const state: ProviderAuthState = { | ||
| 479 | ...empty, | ||
| 480 | methods: snapshot.value.state.methods ?? [], | ||
| 481 | phase: Exit.isSuccess(result) ? "idle" : "failed", | ||
| 482 | message: Exit.isSuccess(result) | ||
| 483 | ? (result.value ?? "Signed out.") | ||
| 484 | : "Could not sign out. Try again.", | ||
| 485 | }; | ||
| 486 | yield* lock.withPermit( | ||
| 487 | Effect.gen(function* () { | ||
| 488 | yield* SubscriptionRef.set(snapshot, { owner: null, state }); | ||
| 489 | operation = "idle"; | ||
| 490 | }), | ||
| 491 | ); | ||
| 492 | if (Exit.isFailure(result)) return yield* Effect.failCause(result.cause); | ||
| 493 | return state; | ||
| 494 | }).pipe(Effect.uninterruptible), | ||
| 495 | subscribe: (owner) => | ||
| 496 | SubscriptionRef.changes(snapshot).pipe( | ||
| 497 | Stream.map((current) => | ||
| 498 | current.owner === null || current.owner === owner | ||
| 499 | ? current.state | ||
| 500 | : { | ||
| 501 | ...current.state, | ||
| 502 | flowId: null, | ||
| 503 | authorizationUrl: null, | ||
| 504 | interaction: null, | ||
| 505 | expiresAt: null, | ||
| 506 | message: active | ||
| 507 | ? "Sign-in is in progress in another client." | ||
| 508 | : current.state.message, | ||
| 509 | }, | ||
| 510 | ), | ||
| 511 | ), | ||
| 512 | }; | ||
| 513 | yield* Effect.addFinalizer(() => | ||
| 514 | Effect.gen(function* () { | ||
| 515 | operation = "closed"; | ||
| 516 | const flow = active; | ||
| 517 | active = undefined; | ||
| 518 | if (flow?.responseFiber) yield* Fiber.interrupt(flow.responseFiber); | ||
| 519 | if (flow?.fiber) yield* Fiber.interrupt(flow.fiber); | ||
| 520 | // Settings edits rebuild instances; admitted sessions (including those of | ||
| 521 | // peers sharing this binding) end with their own scopes, not this one. | ||
| 522 | }), | ||
| 523 | ); | ||
| 524 | return controller; | ||
| 525 | }); | ||
packages/provider-core/src/server/snapshotSettings.ts+20-14| ... | @@ -3,7 +3,7 @@ import * as Effect from "effect/Effect"; | ... | @@ -3,7 +3,7 @@ import * as Effect from "effect/Effect"; |
| 3 | import * as Equal from "effect/Equal"; | 3 | import * as Equal from "effect/Equal"; |
| 4 | import * as Stream from "effect/Stream"; | 4 | import * as Stream from "effect/Stream"; |
| 5 | 5 | ||
| 6 | import type * as ProviderHost from "./ProviderHost.ts"; | 6 | import * as ProviderHost from "./ProviderHost.ts"; |
| 7 | 7 | ||
| 8 | export interface ProviderSnapshotSettings<Settings> { | 8 | export interface ProviderSnapshotSettings<Settings> { |
| 9 | readonly provider: Settings; | 9 | readonly provider: Settings; |
| ... | @@ -27,17 +27,23 @@ export function haveProviderSnapshotSettingsChanged<Settings>( | ... | @@ -27,17 +27,23 @@ export function haveProviderSnapshotSettingsChanged<Settings>( |
| 27 | return !Equal.equals(previous, next); | 27 | return !Equal.equals(previous, next); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | export function makeProviderSnapshotSettingsSource<Settings>( | 30 | /** The instance's settings paired with the host's server settings, as snapshots read them. */ |
| 31 | export const makeProviderSnapshotSettingsSource = <Settings>( | ||
| 31 | provider: Settings, | 32 | provider: Settings, |
| 32 | settings: ProviderHost.ProviderHost["Service"]["settings"], | 33 | ): Effect.Effect< |
| 33 | ): { | 34 | { |
| 34 | readonly getSettings: Effect.Effect<ProviderSnapshotSettings<Settings>, ServerSettingsError>; | 35 | readonly getSettings: Effect.Effect<ProviderSnapshotSettings<Settings>, ServerSettingsError>; |
| 35 | readonly streamSettings: Stream.Stream<ProviderSnapshotSettings<Settings>>; | 36 | readonly streamSettings: Stream.Stream<ProviderSnapshotSettings<Settings>>; |
| 36 | } { | 37 | }, |
| 37 | const mapSettings = (settings: ServerSettings) => | 38 | never, |
| 38 | makeProviderSnapshotSettings(provider, settings); | 39 | ProviderHost.ProviderHost |
| 39 | return { | 40 | > => |
| 40 | getSettings: settings.get.pipe(Effect.map(mapSettings)), | 41 | Effect.gen(function* () { |
| 41 | streamSettings: settings.changes.pipe(Stream.map(mapSettings)), | 42 | const { settings } = yield* ProviderHost.ProviderHost; |
| 42 | }; | 43 | const mapSettings = (current: ServerSettings) => |
| 43 | } | 44 | makeProviderSnapshotSettings(provider, current); |
| 45 | return { | ||
| 46 | getSettings: settings.get.pipe(Effect.map(mapSettings)), | ||
| 47 | streamSettings: settings.changes.pipe(Stream.map(mapSettings)), | ||
| 48 | }; | ||
| 49 | }); |
packages/provider-cursor/src/server/adapter.ts+1-1| ... | @@ -239,7 +239,7 @@ function providerSession(input: { | ... | @@ -239,7 +239,7 @@ function providerSession(input: { |
| 239 | } | 239 | } |
| 240 | 240 | ||
| 241 | function makeProviderThread(input: { | 241 | function makeProviderThread(input: { |
| 242 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 242 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 243 | readonly providerInstanceId: ProviderInstanceId; | 243 | readonly providerInstanceId: ProviderInstanceId; |
| 244 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; | 244 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; |
| 245 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; | 245 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; |
packages/provider-cursor/src/server/driver.ts+1-1| ... | @@ -223,7 +223,7 @@ export const CursorDriver: ProviderDriver<CursorSettings, CursorDriverEnv> = { | ... | @@ -223,7 +223,7 @@ export const CursorDriver: ProviderDriver<CursorSettings, CursorDriverEnv> = { |
| 223 | Effect.provide(CursorSdkCatalog.layer), | 223 | Effect.provide(CursorSdkCatalog.layer), |
| 224 | ); | 224 | ); |
| 225 | 225 | ||
| 226 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 226 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 227 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<CursorSettings>>({ | 227 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<CursorSettings>>({ |
| 228 | resolveMaintenance: () => Effect.succeed(MAINTENANCE_CAPABILITIES), | 228 | resolveMaintenance: () => Effect.succeed(MAINTENANCE_CAPABILITIES), |
| 229 | getSettings: snapshotSettings.getSettings, | 229 | getSettings: snapshotSettings.getSettings, |
packages/provider-grok/src/server/adapter.ts+1-1| ... | @@ -58,7 +58,7 @@ import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPol | ... | @@ -58,7 +58,7 @@ import { acpPermissionDisposition } from "@t3tools/provider-acp/server/clientPol |
| 58 | import * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime"; | 58 | import * as AcpSessionRuntime from "@t3tools/provider-acp/server/AcpSessionRuntime"; |
| 59 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; | 59 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 60 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 60 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 61 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 61 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 62 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | 62 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 63 | import { | 63 | import { |
| 64 | ProviderAdapterDriverCreateError, | 64 | ProviderAdapterDriverCreateError, |
packages/provider-grok/src/server/driver.ts+1-1| ... | @@ -160,7 +160,7 @@ export const GrokDriver: ProviderDriver<GrokSettings, GrokDriverEnv> = { | ... | @@ -160,7 +160,7 @@ export const GrokDriver: ProviderDriver<GrokSettings, GrokDriverEnv> = { |
| 160 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), | 160 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 161 | ); | 161 | ); |
| 162 | 162 | ||
| 163 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 163 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 164 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<GrokSettings>>({ | 164 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<GrokSettings>>({ |
| 165 | resolveMaintenance, | 165 | resolveMaintenance, |
| 166 | getSettings: snapshotSettings.getSettings, | 166 | getSettings: snapshotSettings.getSettings, |
packages/provider-muse/src/server/adapter.test.ts+2-2| ... | @@ -36,7 +36,7 @@ import type { MuseItem } from "./protocol.ts"; | ... | @@ -36,7 +36,7 @@ import type { MuseItem } from "./protocol.ts"; |
| 36 | import type { MuseSdkHost } from "./sdk.ts"; | 36 | import type { MuseSdkHost } from "./sdk.ts"; |
| 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 38 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | 38 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 39 | import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; | 39 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 40 | import { makeMuseAdapterV2, type MuseAdapterV2Options } from "./adapter.ts"; | 40 | import { makeMuseAdapterV2, type MuseAdapterV2Options } from "./adapter.ts"; |
| 41 | 41 | ||
| 42 | const testLayer = Layer.mergeAll( | 42 | const testLayer = Layer.mergeAll( |
| ... | @@ -766,7 +766,7 @@ describe("MuseAdapterV2", () => { | ... | @@ -766,7 +766,7 @@ describe("MuseAdapterV2", () => { |
| 766 | it.effect("lets a user turn take a held Muse report turn, approvals included", () => | 766 | it.effect("lets a user turn take a held Muse report turn, approvals included", () => |
| 767 | Effect.gen(function* () { | 767 | Effect.gen(function* () { |
| 768 | const fake = yield* makeFakeMuse(); | 768 | const fake = yield* makeFakeMuse(); |
| 769 | const offers: Array<ProviderContinuationRequest> = []; | 769 | const offers: Array<ProviderContinuationRequests.ProviderContinuationRequest> = []; |
| 770 | const harness = yield* makeHarness( | 770 | const harness = yield* makeHarness( |
| 771 | fake, | 771 | fake, |
| 772 | INSTANCE_ID, | 772 | INSTANCE_ID, |
packages/provider-muse/src/server/adapter.ts+1-1| ... | @@ -74,7 +74,7 @@ import { | ... | @@ -74,7 +74,7 @@ import { |
| 74 | backgroundWorkNotification, | 74 | backgroundWorkNotification, |
| 75 | type BackgroundWorkReport, | 75 | type BackgroundWorkReport, |
| 76 | } from "@t3tools/provider-core/server/notification"; | 76 | } from "@t3tools/provider-core/server/notification"; |
| 77 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 77 | import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 78 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; | 78 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; |
| 79 | import { turnScopedSelectionTransition } from "@t3tools/provider-core/server/selectionTransition"; | 79 | import { turnScopedSelectionTransition } from "@t3tools/provider-core/server/selectionTransition"; |
| 80 | import { museItemStatus, museToolPresentation } from "./itemPresentation.ts"; | 80 | import { museItemStatus, museToolPresentation } from "./itemPresentation.ts"; |
packages/provider-muse/src/server/driver.ts+2-2| ... | @@ -14,7 +14,7 @@ import { makeMuseTextGeneration } from "./textGeneration.ts"; | ... | @@ -14,7 +14,7 @@ import { makeMuseTextGeneration } from "./textGeneration.ts"; |
| 14 | import { ProviderDriverError } from "@t3tools/provider-core/server/errors"; | 14 | import { ProviderDriverError } from "@t3tools/provider-core/server/errors"; |
| 15 | import { makeMuseAdapterV2 } from "./adapter.ts"; | 15 | import { makeMuseAdapterV2 } from "./adapter.ts"; |
| 16 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 16 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 17 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 17 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 18 | import { checkMuseProviderStatus, makePendingMuseProvider } from "./status.ts"; | 18 | import { checkMuseProviderStatus, makePendingMuseProvider } from "./status.ts"; |
| 19 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; | 19 | import * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers"; |
| 20 | import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; | 20 | import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; |
| ... | @@ -86,7 +86,7 @@ export const MuseDriver: ProviderDriver<MuseSettings, MuseDriverEnv> = { | ... | @@ -86,7 +86,7 @@ export const MuseDriver: ProviderDriver<MuseSettings, MuseDriverEnv> = { |
| 86 | accentColor, | 86 | accentColor, |
| 87 | continuationGroupKey: continuationIdentity.continuationKey, | 87 | continuationGroupKey: continuationIdentity.continuationKey, |
| 88 | }); | 88 | }); |
| 89 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 89 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 90 | const resolveInstallation = yield* makeCachedProviderMaintenanceResolution( | 90 | const resolveInstallation = yield* makeCachedProviderMaintenanceResolution( |
| 91 | resolveProviderMaintenanceCapabilitiesEffect(museMaintenance, { | 91 | resolveProviderMaintenanceCapabilitiesEffect(museMaintenance, { |
| 92 | binaryPath: effectiveConfig.binaryPath, | 92 | binaryPath: effectiveConfig.binaryPath, |
packages/provider-opencode/src/server/adapter.ts+2-2| ... | @@ -459,7 +459,7 @@ function formatOpenCodeProtocolLogPayload(event: OpenCodeProtocolLogEvent) { | ... | @@ -459,7 +459,7 @@ function formatOpenCodeProtocolLogPayload(event: OpenCodeProtocolLogEvent) { |
| 459 | 459 | ||
| 460 | export function makeOpenCodeProtocolLogger(input: { | 460 | export function makeOpenCodeProtocolLogger(input: { |
| 461 | readonly nativeEventLogger: ProviderEventLoggers.EventNdjsonLogger | undefined; | 461 | readonly nativeEventLogger: ProviderEventLoggers.EventNdjsonLogger | undefined; |
| 462 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 462 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 463 | readonly providerInstanceId: ProviderInstanceId; | 463 | readonly providerInstanceId: ProviderInstanceId; |
| 464 | readonly providerSessionId: ProviderSessionId; | 464 | readonly providerSessionId: ProviderSessionId; |
| 465 | readonly threadId: ThreadId; | 465 | readonly threadId: ThreadId; |
| ... | @@ -830,7 +830,7 @@ function taskSessionId(part: ToolPart): string | null { | ... | @@ -830,7 +830,7 @@ function taskSessionId(part: ToolPart): string | null { |
| 830 | } | 830 | } |
| 831 | 831 | ||
| 832 | function makeProviderThread(input: { | 832 | function makeProviderThread(input: { |
| 833 | readonly idAllocator: IdAllocator.IdAllocatorV2Shape; | 833 | readonly idAllocator: IdAllocator.IdAllocatorV2["Service"]; |
| 834 | readonly providerInstanceId: ProviderInstanceId; | 834 | readonly providerInstanceId: ProviderInstanceId; |
| 835 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; | 835 | readonly providerSessionId: OrchestrationV2ProviderThread["providerSessionId"]; |
| 836 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; | 836 | readonly appThreadId: OrchestrationV2ProviderThread["appThreadId"]; |
packages/provider-opencode/src/server/driver.ts+4-4| ... | @@ -123,9 +123,9 @@ function byOpenCodeRuntime<A, E, R, PE>( | ... | @@ -123,9 +123,9 @@ function byOpenCodeRuntime<A, E, R, PE>( |
| 123 | */ | 123 | */ |
| 124 | function selectOpenCodeRuntimeAdapter(input: { | 124 | function selectOpenCodeRuntimeAdapter(input: { |
| 125 | readonly probe: OpenCodeRuntimeProbe; | 125 | readonly probe: OpenCodeRuntimeProbe; |
| 126 | readonly v1: ProviderAdapter.ProviderAdapterV2Shape; | 126 | readonly v1: ProviderAdapter.ProviderAdapterV2["Service"]; |
| 127 | readonly v2: ProviderAdapter.ProviderAdapterV2Shape; | 127 | readonly v2: ProviderAdapter.ProviderAdapterV2["Service"]; |
| 128 | }): ProviderAdapter.ProviderAdapterV2Shape { | 128 | }): ProviderAdapter.ProviderAdapterV2["Service"] { |
| 129 | const pick = <PE>(probed: Effect.Effect<ProbedOpenCode | undefined, PE>) => | 129 | const pick = <PE>(probed: Effect.Effect<ProbedOpenCode | undefined, PE>) => |
| 130 | byOpenCodeRuntime(probed, { v1: Effect.succeed(input.v1), v2: Effect.succeed(input.v2) }); | 130 | byOpenCodeRuntime(probed, { v1: Effect.succeed(input.v1), v2: Effect.succeed(input.v2) }); |
| 131 | const hot = pick(Effect.map(input.probe.lastSuccess, Option.getOrUndefined)); | 131 | const hot = pick(Effect.map(input.probe.lastSuccess, Option.getOrUndefined)); |
| ... | @@ -445,7 +445,7 @@ export const OpenCodeDriver: ProviderDriver<OpenCodeSettings, OpenCodeDriverEnv> | ... | @@ -445,7 +445,7 @@ export const OpenCodeDriver: ProviderDriver<OpenCodeSettings, OpenCodeDriverEnv> |
| 445 | ), | 445 | ), |
| 446 | ); | 446 | ); |
| 447 | 447 | ||
| 448 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 448 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 449 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<OpenCodeSettings>>( | 449 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<OpenCodeSettings>>( |
| 450 | { | 450 | { |
| 451 | resolveMaintenance, | 451 | resolveMaintenance, |
packages/provider-opencode/src/server/v2/adapter.ts+2-2| ... | @@ -88,7 +88,7 @@ import { | ... | @@ -88,7 +88,7 @@ import { |
| 88 | backgroundWorkNotification, | 88 | backgroundWorkNotification, |
| 89 | type BackgroundWorkReport, | 89 | type BackgroundWorkReport, |
| 90 | } from "@t3tools/provider-core/server/notification"; | 90 | } from "@t3tools/provider-core/server/notification"; |
| 91 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 91 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 92 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; | 92 | import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; |
| 93 | import { | 93 | import { |
| 94 | makeSubagentChildThread, | 94 | makeSubagentChildThread, |
| ... | @@ -858,7 +858,7 @@ export const make = Effect.fn("OpenCode2Adapter.make")(function* (instanceId: Pr | ... | @@ -858,7 +858,7 @@ export const make = Effect.fn("OpenCode2Adapter.make")(function* (instanceId: Pr |
| 858 | }); | 858 | }); |
| 859 | 859 | ||
| 860 | const openSession = Effect.fn("OpenCode2Adapter.openSession")(function* ( | 860 | const openSession = Effect.fn("OpenCode2Adapter.openSession")(function* ( |
| 861 | input: Parameters<ProviderAdapter.ProviderAdapterV2Shape["openSession"]>[0], | 861 | input: Parameters<ProviderAdapter.ProviderAdapterV2["Service"]["openSession"]>[0], |
| 862 | initial: { | 862 | initial: { |
| 863 | readonly connection: OpenCode2Server.OpenCode2Connection; | 863 | readonly connection: OpenCode2Server.OpenCode2Connection; |
| 864 | readonly scope: Scope.Closeable; | 864 | readonly scope: Scope.Closeable; |
packages/provider-pi/src/server/adapter.test.ts+1-1| ... | @@ -32,7 +32,7 @@ import * as TestClock from "effect/testing/TestClock"; | ... | @@ -32,7 +32,7 @@ import * as TestClock from "effect/testing/TestClock"; |
| 32 | import { ChildProcess, ChildProcessSpawner } from "effect/process"; | 32 | import { ChildProcess, ChildProcessSpawner } from "effect/process"; |
| 33 | 33 | ||
| 34 | import { layerTestProviderHost } from "@t3tools/provider-testing/host"; | 34 | import { layerTestProviderHost } from "@t3tools/provider-testing/host"; |
| 35 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 35 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 36 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; | 36 | import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; |
| 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 37 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 38 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | 38 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
packages/provider-pi/src/server/adapter.ts+1-2| ... | @@ -67,7 +67,7 @@ import { parsePiCompactCommand, type PiCompactCommand } from "./commands.ts"; | ... | @@ -67,7 +67,7 @@ import { parsePiCompactCommand, type PiCompactCommand } from "./commands.ts"; |
| 67 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; | 67 | import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; |
| 68 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; | 68 | import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; |
| 69 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; | 69 | import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; |
| 70 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; | 70 | import * as ProviderContinuationRequests from "@t3tools/provider-core/server/ProviderContinuationRequests"; |
| 71 | import { | 71 | import { |
| 72 | ProviderAdapterDriverCreateError, | 72 | ProviderAdapterDriverCreateError, |
| 73 | type ProviderAdapterDriver, | 73 | type ProviderAdapterDriver, |
| ... | @@ -775,7 +775,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( | ... | @@ -775,7 +775,6 @@ export const makePiAdapterV2 = Effect.fn("makePiAdapterV2")(function* ( |
| 775 | type: "turn_item.updated", | 775 | type: "turn_item.updated", |
| 776 | driver: PI_PROVIDER, | 776 | driver: PI_PROVIDER, |
| 777 | turnItem: makeProviderRetryTurnItem({ | 777 | turnItem: makeProviderRetryTurnItem({ |
| 778 | idAllocator, | ||
| 779 | driver: PI_PROVIDER, | 778 | driver: PI_PROVIDER, |
| 780 | threadId: turn.turnInput.threadId, | 779 | threadId: turn.turnInput.threadId, |
| 781 | runId: turn.turnInput.runId, | 780 | runId: turn.turnInput.runId, |
packages/provider-pi/src/server/driver.ts+1-1| ... | @@ -142,7 +142,7 @@ export const PiDriver: ProviderDriver<PiSettings, PiDriverEnv> = { | ... | @@ -142,7 +142,7 @@ export const PiDriver: ProviderDriver<PiSettings, PiDriverEnv> = { |
| 142 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), | 142 | Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner), |
| 143 | ); | 143 | ); |
| 144 | 144 | ||
| 145 | const snapshotSettings = makeProviderSnapshotSettingsSource(effectiveConfig, host.settings); | 145 | const snapshotSettings = yield* makeProviderSnapshotSettingsSource(effectiveConfig); |
| 146 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<PiSettings>>({ | 146 | const snapshot = yield* makeManagedServerProvider<ProviderSnapshotSettings<PiSettings>>({ |
| 147 | resolveMaintenance, | 147 | resolveMaintenance, |
| 148 | getSettings: snapshotSettings.getSettings, | 148 | getSettings: snapshotSettings.getSettings, |