authorgravatar for julius0216@outlook.comJulius Marminge <julius0216@outlook.com> 2026-10-08 18:05:10-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2026-10-09 01:05:10+00:00
log2c7a446e657e705c257db28540819f4c0115b2fc
tree36f0376370207f6a7fbca2c57098834b064614a0
parentb0ee7dd48f868c5c02884345f723bebaf616b13d
signature Signed by PGP key B5690EEEBB952194

refactor(providers): namespace-import service modules in core, Muse, Pi, and testing (#17375)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>

14 files changed, 112 insertions(+), 117 deletions(-)

packages/provider-core/src/server/adapterDriver.ts+6-2
...@@ -7,7 +7,7 @@ import * as Schema from "effect/Schema";...@@ -7,7 +7,7 @@ import * as Schema from "effect/Schema";
7import type * as Effect from "effect/Effect";7import type * as Effect from "effect/Effect";
8import type * as Scope from "effect/Scope";8import type * as Scope from "effect/Scope";
99
10import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter";10import type * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
1111
12export class ProviderAdapterDriverCreateError extends Schema.TaggedError<ProviderAdapterDriverCreateError>()(12export class ProviderAdapterDriverCreateError extends Schema.TaggedError<ProviderAdapterDriverCreateError>()(
13 "ProviderAdapterDriverCreateError",13 "ProviderAdapterDriverCreateError",
...@@ -38,7 +38,11 @@ export interface ProviderAdapterDriver<Config, R = never> {...@@ -38,7 +38,11 @@ export interface ProviderAdapterDriver<Config, R = never> {
38 readonly defaultConfig: () => Config;38 readonly defaultConfig: () => Config;
39 readonly create: (39 readonly create: (
40 input: ProviderAdapterDriverCreateInput<Config>,40 input: ProviderAdapterDriverCreateInput<Config>,
41 ) => Effect.Effect<ProviderAdapterV2Shape, ProviderAdapterDriverCreateError, R | Scope.Scope>;41 ) => Effect.Effect<
42 ProviderAdapter.ProviderAdapterV2Shape,
43 ProviderAdapterDriverCreateError,
44 R | Scope.Scope
45 >;
42}46}
4347
44export type AnyProviderAdapterDriver<R = never> = ProviderAdapterDriver<any, R>;48export type AnyProviderAdapterDriver<R = never> = ProviderAdapterDriver<any, R>;
packages/provider-core/src/server/driver.ts+2-2
...@@ -37,7 +37,7 @@ import type * as Effect from "effect/Effect";...@@ -37,7 +37,7 @@ import type * as Effect from "effect/Effect";
37import type * as Schema from "effect/Schema";37import type * as Schema from "effect/Schema";
38import type * as Scope from "effect/Scope";38import type * as Scope from "effect/Scope";
3939
40import type { ProviderAdapterV2Shape } from "./ProviderAdapter.ts";40import type * as ProviderAdapter from "./ProviderAdapter.ts";
41import type { ProviderAuthController } from "./auth.ts";41import type { ProviderAuthController } from "./auth.ts";
42import type { ProviderDriverError } from "./errors.ts";42import type { ProviderDriverError } from "./errors.ts";
43import type { ServerProviderShape } from "./snapshot.ts";43import type { ServerProviderShape } from "./snapshot.ts";
...@@ -101,7 +101,7 @@ export interface ProviderInstance {...@@ -101,7 +101,7 @@ export interface ProviderInstance {
101 ProviderConsumeResetCreditOutcome,101 ProviderConsumeResetCreditOutcome,
102 ProviderDriverError102 ProviderDriverError
103 >;103 >;
104 readonly orchestrationAdapter: ProviderAdapterV2Shape;104 readonly orchestrationAdapter: ProviderAdapter.ProviderAdapterV2Shape;
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.test.ts+2-2
...@@ -19,7 +19,7 @@ import {...@@ -19,7 +19,7 @@ import {
19 ContextHandoffBudgetError,19 ContextHandoffBudgetError,
20} from "./failure.ts";20} from "./failure.ts";
21import * as IdAllocator from "./IdAllocator.ts";21import * as IdAllocator from "./IdAllocator.ts";
22import { ProviderAdapterTurnStartError } from "@t3tools/provider-core/server/ProviderAdapter";22import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
2323
24it("redacts credentials and URL secrets from provider failures", () => {24it("redacts credentials and URL secrets from provider failures", () => {
25 const failure = makeProviderFailure({25 const failure = makeProviderFailure({
...@@ -88,7 +88,7 @@ it("does not expose arbitrary cause messages and preserves explicit messages", (...@@ -88,7 +88,7 @@ it("does not expose arbitrary cause messages and preserves explicit messages", (
88});88});
8989
90it("preserves actionable handoff errors wrapped by turn startup", () => {90it("preserves actionable handoff errors wrapped by turn startup", () => {
91 const cause = new ProviderAdapterTurnStartError({91 const cause = new ProviderAdapter.ProviderAdapterTurnStartError({
92 driver: ProviderDriverKind.make("codex"),92 driver: ProviderDriverKind.make("codex"),
93 threadId: ThreadId.make("thread:handoff-error"),93 threadId: ThreadId.make("thread:handoff-error"),
94 providerThreadId: ProviderThreadId.make("provider-thread:handoff-error"),94 providerThreadId: ProviderThreadId.make("provider-thread:handoff-error"),
packages/provider-core/src/server/failure.ts+3-3
...@@ -13,7 +13,7 @@ import type {...@@ -13,7 +13,7 @@ import type {
13import * as DateTime from "effect/DateTime";13import * as DateTime from "effect/DateTime";
14import * as Cause from "effect/Cause";14import * as Cause from "effect/Cause";
1515
16import type { IdAllocatorV2Shape } from "./IdAllocator.ts";16import type * as IdAllocator from "./IdAllocator.ts";
17import * as Schema from "effect/Schema";17import * as Schema from "effect/Schema";
1818
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,7 @@ export function makeProviderFailure(input: {...@@ -172,7 +172,7 @@ export function makeProviderFailure(input: {
172}172}
173173
174export function makeProviderFailureTurnItem(input: {174export function makeProviderFailureTurnItem(input: {
175 readonly idAllocator: IdAllocatorV2Shape;175 readonly idAllocator: IdAllocator.IdAllocatorV2Shape;
176 readonly driver: ProviderDriverKind;176 readonly driver: ProviderDriverKind;
177 readonly threadId: ThreadId;177 readonly threadId: ThreadId;
178 readonly runId: RunId | null;178 readonly runId: RunId | null;
...@@ -210,7 +210,7 @@ export function makeProviderFailureTurnItem(input: {...@@ -210,7 +210,7 @@ export function makeProviderFailureTurnItem(input: {
210}210}
211211
212export function makeProviderRetryTurnItem(input: {212export function makeProviderRetryTurnItem(input: {
213 readonly idAllocator: IdAllocatorV2Shape;213 readonly idAllocator: IdAllocator.IdAllocatorV2Shape;
214 readonly driver: ProviderDriverKind;214 readonly driver: ProviderDriverKind;
215 readonly threadId: ThreadId;215 readonly threadId: ThreadId;
216 readonly runId: RunId | null;216 readonly runId: RunId | null;
packages/provider-core/src/server/managedProvider.test.ts+5-5
...@@ -16,7 +16,7 @@ import * as Ref from "effect/Ref";...@@ -16,7 +16,7 @@ import * as Ref from "effect/Ref";
16import * as Stream from "effect/Stream";16import * as Stream from "effect/Stream";
17import { TestClock } from "effect/testing";17import { TestClock } from "effect/testing";
1818
19import { ProviderHost, type ProviderHostShape } from "./ProviderHost.ts";19import * as ProviderHost from "./ProviderHost.ts";
20import { makeManagedServerProvider } from "./managedProvider.ts";20import { makeManagedServerProvider } from "./managedProvider.ts";
2121
22const emptyCapabilities = createModelCapabilities({ optionDescriptors: [] });22const emptyCapabilities = createModelCapabilities({ optionDescriptors: [] });
...@@ -99,11 +99,11 @@ const refreshedSnapshotSecond: ServerProvider = {...@@ -99,11 +99,11 @@ const refreshedSnapshotSecond: ServerProvider = {
99/** A host whose settings never change and whose background demand is fixed. */99/** A host whose settings never change and whose background demand is fixed. */
100function layerProviderHost(input: {100function layerProviderHost(input: {
101 readonly runBackgroundWork: boolean;101 readonly runBackgroundWork: boolean;
102 readonly settings?: Pick<ProviderHostShape, "settings">["settings"];102 readonly settings?: Pick<ProviderHost.ProviderHostShape, "settings">["settings"];
103}) {103}) {
104 return Layer.succeed(104 return Layer.succeed(
105 ProviderHost,105 ProviderHost.ProviderHost,
106 ProviderHost.of({106 ProviderHost.ProviderHost.of({
107 paths: {107 paths: {
108 cwd: process.cwd(),108 cwd: process.cwd(),
109 baseDir: "/t3",109 baseDir: "/t3",
...@@ -281,7 +281,7 @@ describe("makeManagedServerProvider", () => {...@@ -281,7 +281,7 @@ describe("makeManagedServerProvider", () => {
281 };281 };
282 const serverSettingsRef = yield* Ref.make(initialServerSettings);282 const serverSettingsRef = yield* Ref.make(initialServerSettings);
283 const serverSettingsChanges = yield* PubSub.unbounded<typeof initialServerSettings>();283 const serverSettingsChanges = yield* PubSub.unbounded<typeof initialServerSettings>();
284 const hostSettings: ProviderHostShape["settings"] = {284 const hostSettings: ProviderHost.ProviderHostShape["settings"] = {
285 get: Ref.get(serverSettingsRef),285 get: Ref.get(serverSettingsRef),
286 changes: Stream.empty,286 changes: Stream.empty,
287 subscribe: PubSub.subscribe(serverSettingsChanges).pipe(287 subscribe: PubSub.subscribe(serverSettingsChanges).pipe(
packages/provider-core/src/server/managedProvider.ts+7-3
...@@ -15,7 +15,7 @@ import * as Scope from "effect/Scope";...@@ -15,7 +15,7 @@ import * as Scope from "effect/Scope";
15import * as Stream from "effect/Stream";15import * as Stream from "effect/Stream";
16import * as Semaphore from "effect/Semaphore";16import * as Semaphore from "effect/Semaphore";
1717
18import { ProviderHost } from "./ProviderHost.ts";18import * as ProviderHost from "./ProviderHost.ts";
19import { applyUsageLimitsUpdate, resolveUsageLimitsAfterProbe } from "./usageLimits.ts";19import { applyUsageLimitsUpdate, resolveUsageLimitsAfterProbe } from "./usageLimits.ts";
20import type { ServerProviderShape } from "./snapshot.ts";20import type { ServerProviderShape } from "./snapshot.ts";
2121
...@@ -53,8 +53,12 @@ export const makeManagedServerProvider = Effect.fn("makeManagedServerProvider")(...@@ -53,8 +53,12 @@ export const makeManagedServerProvider = Effect.fn("makeManagedServerProvider")(
53 readonly refreshInterval?: Duration.Input;53 readonly refreshInterval?: Duration.Input;
54 readonly refreshOnInterval?: boolean;54 readonly refreshOnInterval?: boolean;
55 readonly checkProviderOnSettingsChange?: (previous: Settings, next: Settings) => boolean;55 readonly checkProviderOnSettingsChange?: (previous: Settings, next: Settings) => boolean;
56}): Effect.fn.Return<ServerProviderShape, ServerSettingsError, Scope.Scope | ProviderHost> {56}): Effect.fn.Return<
57 const host = yield* ProviderHost;57 ServerProviderShape,
58 ServerSettingsError,
59 Scope.Scope | ProviderHost.ProviderHost
60> {
61 const host = yield* ProviderHost.ProviderHost;
58 const refreshSemaphore = yield* Semaphore.make(1);62 const refreshSemaphore = yield* Semaphore.make(1);
59 const changesPubSub = yield* Effect.acquireRelease(63 const changesPubSub = yield* Effect.acquireRelease(
60 PubSub.unbounded<ServerProvider>(),64 PubSub.unbounded<ServerProvider>(),
packages/provider-core/src/server/snapshotSettings.ts+2-2
...@@ -3,7 +3,7 @@ import * as Effect from "effect/Effect";...@@ -3,7 +3,7 @@ import * as Effect from "effect/Effect";
3import * as Equal from "effect/Equal";3import * as Equal from "effect/Equal";
4import * as Stream from "effect/Stream";4import * as Stream from "effect/Stream";
55
6import type { ProviderHostShape } from "./ProviderHost.ts";6import type * as ProviderHost from "./ProviderHost.ts";
77
8export interface ProviderSnapshotSettings<Settings> {8export interface ProviderSnapshotSettings<Settings> {
9 readonly provider: Settings;9 readonly provider: Settings;
...@@ -29,7 +29,7 @@ export function haveProviderSnapshotSettingsChanged<Settings>(...@@ -29,7 +29,7 @@ export function haveProviderSnapshotSettingsChanged<Settings>(
2929
30export function makeProviderSnapshotSettingsSource<Settings>(30export function makeProviderSnapshotSettingsSource<Settings>(
31 provider: Settings,31 provider: Settings,
32 settings: ProviderHostShape["settings"],32 settings: ProviderHost.ProviderHostShape["settings"],
33): {33): {
34 readonly getSettings: Effect.Effect<ProviderSnapshotSettings<Settings>, ServerSettingsError>;34 readonly getSettings: Effect.Effect<ProviderSnapshotSettings<Settings>, ServerSettingsError>;
35 readonly streamSettings: Stream.Stream<ProviderSnapshotSettings<Settings>>;35 readonly streamSettings: Stream.Stream<ProviderSnapshotSettings<Settings>>;
packages/provider-muse/src/server/adapter.test.ts+20-17
...@@ -31,17 +31,13 @@ import * as Queue from "effect/Queue";...@@ -31,17 +31,13 @@ import * as Queue from "effect/Queue";
31import * as Schema from "effect/Schema";31import * as Schema from "effect/Schema";
32import * as Stream from "effect/Stream";32import * as Stream from "effect/Stream";
3333
34import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost";34import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
35import { layerTestProviderHost } from "@t3tools/provider-testing/host";35import { layerTestProviderHost } from "@t3tools/provider-testing/host";
36import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";36import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";
37import type { MuseItem } from "./protocol.ts";37import type { MuseItem } from "./protocol.ts";
38import type { MuseSdkHost } from "./sdk.ts";38import type { MuseSdkHost } from "./sdk.ts";
39import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";39import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
40import {40import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
41 ProviderAdapterV2RuntimePolicy,
42 type ProviderAdapterV2Event,
43 type ProviderAdapterV2TurnInput,
44} from "@t3tools/provider-core/server/ProviderAdapter";
45import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests";41import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests";
46import { makeMuseAdapterV2, type MuseAdapterV2Options } from "./adapter.ts";42import { makeMuseAdapterV2, type MuseAdapterV2Options } from "./adapter.ts";
4743
...@@ -55,7 +51,7 @@ const INSTANCE_ID = ProviderInstanceId.make("muse_work");...@@ -55,7 +51,7 @@ const INSTANCE_ID = ProviderInstanceId.make("muse_work");
55const THREAD_ID = ThreadId.make("thread-muse-test");51const THREAD_ID = ThreadId.make("thread-muse-test");
56const MODEL = "muse-spark-1.3-contributor";52const MODEL = "muse-spark-1.3-contributor";
57const museSettings = Schema.decodeSync(MuseSettings)({ enabled: true });53const museSettings = Schema.decodeSync(MuseSettings)({ enabled: true });
58const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({54const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({
59 runtimeMode: "full-access",55 runtimeMode: "full-access",
60 interactionMode: "default",56 interactionMode: "default",
61 cwd: null,57 cwd: null,
...@@ -204,7 +200,7 @@ const makeHarness = Effect.fnUntraced(function* (...@@ -204,7 +200,7 @@ const makeHarness = Effect.fnUntraced(function* (
204 settings: museSettings,200 settings: museSettings,
205 environment: { PATH: "/fake/bin" },201 environment: { PATH: "/fake/bin" },
206 idAllocator: yield* IdAllocator.IdAllocatorV2,202 idAllocator: yield* IdAllocator.IdAllocatorV2,
207 host: yield* ProviderHost,203 host: yield* ProviderHost.ProviderHost,
208 fileSystem: yield* FileSystem.FileSystem,204 fileSystem: yield* FileSystem.FileSystem,
209 createHost: async () => (hostCount++ === 0 ? fake.host : (replacement ?? fake).host),205 createHost: async () => (hostCount++ === 0 ? fake.host : (replacement ?? fake).host),
210 ...overrides,206 ...overrides,
...@@ -216,8 +212,8 @@ const makeHarness = Effect.fnUntraced(function* (...@@ -216,8 +212,8 @@ const makeHarness = Effect.fnUntraced(function* (
216 runtimePolicy: policy,212 runtimePolicy: policy,
217 ...(initialNativeThreadId ? { initialNativeThreadId } : {}),213 ...(initialNativeThreadId ? { initialNativeThreadId } : {}),
218 });214 });
219 const emitted = yield* Queue.unbounded<ProviderAdapterV2Event>();215 const emitted = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>();
220 const allEvents: ProviderAdapterV2Event[] = [];216 const allEvents: ProviderAdapter.ProviderAdapterV2Event[] = [];
221 const eventsEnded = yield* Deferred.make<Exit.Exit<void, Stream.Error<typeof runtime.events>>>();217 const eventsEnded = yield* Deferred.make<Exit.Exit<void, Stream.Error<typeof runtime.events>>>();
222 yield* runtime.events.pipe(218 yield* runtime.events.pipe(
223 Stream.runForEach((event) =>219 Stream.runForEach((event) =>
...@@ -236,14 +232,21 @@ const makeHarness = Effect.fnUntraced(function* (...@@ -236,14 +232,21 @@ const makeHarness = Effect.fnUntraced(function* (
236 runtimePolicy: policy,232 runtimePolicy: policy,
237 ...(existingProviderThread ? { existingProviderThread } : {}),233 ...(existingProviderThread ? { existingProviderThread } : {}),
238 });234 });
239 const takeEvent = Effect.fnUntraced(function* <T extends ProviderAdapterV2Event["type"]>(235 const takeEvent = Effect.fnUntraced(function* <
236 T extends ProviderAdapter.ProviderAdapterV2Event["type"],
237 >(
240 type: T,238 type: T,
241 predicate: (event: Extract<ProviderAdapterV2Event, { type: T }>) => boolean = () => true,239 predicate: (
240 event: Extract<ProviderAdapter.ProviderAdapterV2Event, { type: T }>,
241 ) => boolean = () => true,
242 ) {242 ) {
243 while (true) {243 while (true) {
244 const event = yield* Queue.take(emitted);244 const event = yield* Queue.take(emitted);
245 if (event.type === type && predicate(event as Extract<ProviderAdapterV2Event, { type: T }>)) {245 if (
246 return event as Extract<ProviderAdapterV2Event, { type: T }>;246 event.type === type &&
247 predicate(event as Extract<ProviderAdapter.ProviderAdapterV2Event, { type: T }>)
248 ) {
249 return event as Extract<ProviderAdapter.ProviderAdapterV2Event, { type: T }>;
247 }250 }
248 }251 }
249 });252 });
...@@ -275,7 +278,7 @@ const turnInput = Effect.fnUntraced(function* (...@@ -275,7 +278,7 @@ const turnInput = Effect.fnUntraced(function* (
275 providerThread: OrchestrationV2ProviderThread,278 providerThread: OrchestrationV2ProviderThread,
276 runOrdinal = 1,279 runOrdinal = 1,
277 policy = runtimePolicy,280 policy = runtimePolicy,
278): Effect.fn.Return<ProviderAdapterV2TurnInput> {281): Effect.fn.Return<ProviderAdapter.ProviderAdapterV2TurnInput> {
279 const now = yield* DateTime.now;282 const now = yield* DateTime.now;
280 const threadId = providerThread.appThreadId ?? THREAD_ID;283 const threadId = providerThread.appThreadId ?? THREAD_ID;
281 const selection = modelSelection(providerThread.providerInstanceId);284 const selection = modelSelection(providerThread.providerInstanceId);
...@@ -436,7 +439,7 @@ describe("MuseAdapterV2", () => {...@@ -436,7 +439,7 @@ describe("MuseAdapterV2", () => {
436 settings: museSettings,439 settings: museSettings,
437 environment: { PATH: "/fake/bin" },440 environment: { PATH: "/fake/bin" },
438 idAllocator: yield* IdAllocator.IdAllocatorV2,441 idAllocator: yield* IdAllocator.IdAllocatorV2,
439 host: yield* ProviderHost,442 host: yield* ProviderHost.ProviderHost,
440 fileSystem: yield* FileSystem.FileSystem,443 fileSystem: yield* FileSystem.FileSystem,
441 createHost: async () => fake.host,444 createHost: async () => fake.host,
442 });445 });
...@@ -833,7 +836,7 @@ describe("MuseAdapterV2", () => {...@@ -833,7 +836,7 @@ describe("MuseAdapterV2", () => {
833 it.effect("keeps a workflow child's approval pending for the user past the turn's end", () =>836 it.effect("keeps a workflow child's approval pending for the user past the turn's end", () =>
834 Effect.gen(function* () {837 Effect.gen(function* () {
835 const fake = yield* makeFakeMuse();838 const fake = yield* makeFakeMuse();
836 const policy = ProviderAdapterV2RuntimePolicy.make({839 const policy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({
837 ...runtimePolicy,840 ...runtimePolicy,
838 runtimeMode: "approval-required",841 runtimeMode: "approval-required",
839 });842 });
packages/provider-muse/src/server/adapter.ts+39-52
...@@ -35,7 +35,7 @@ import * as Semaphore from "effect/Semaphore";...@@ -35,7 +35,7 @@ import * as Semaphore from "effect/Semaphore";
35import * as Scope from "effect/Scope";35import * as Scope from "effect/Scope";
36import * as Stream from "effect/Stream";36import * as Stream from "effect/Stream";
3737
38import type { ProviderHostShape } from "@t3tools/provider-core/server/ProviderHost";38import type * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
39import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";39import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";
40import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions";40import { buildRuntimeInstructions } from "@t3tools/provider-core/server/runtimeInstructions";
41import { museModelCapabilities, resolveMuseReasoningEffort } from "./modelCatalog.ts";41import { museModelCapabilities, resolveMuseReasoningEffort } from "./modelCatalog.ts";
...@@ -63,35 +63,13 @@ import {...@@ -63,35 +63,13 @@ import {
63 type createMuseSdkHost,63 type createMuseSdkHost,
64 type MuseSdkHost,64 type MuseSdkHost,
65} from "./sdk.ts";65} from "./sdk.ts";
66import type { EventNdjsonLogger } from "@t3tools/provider-core/server/ProviderEventLoggers";66import type * as ProviderEventLoggers from "@t3tools/provider-core/server/ProviderEventLoggers";
67import {67import {
68 providerMessageTextWithAttachmentPaths,68 providerMessageTextWithAttachmentPaths,
69 isProviderNativeImageAttachment,69 isProviderNativeImageAttachment,
70} from "@t3tools/provider-core/server/attachmentPrompt";70} from "@t3tools/provider-core/server/attachmentPrompt";
71import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";71import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
72import {72import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
73 ProviderAdapterEnsureThreadError,
74 ProviderAdapterForkThreadError,
75 ProviderAdapterInterruptError,
76 ProviderAdapterOpenSessionError,
77 ProviderAdapterProtocolError,
78 ProviderAdapterReadThreadSnapshotError,
79 ProviderAdapterResumeThreadError,
80 ProviderAdapterRollbackThreadError,
81 ProviderAdapterRuntimeRequestResponseError,
82 ProviderAdapterSteerRunError,
83 ProviderAdapterTurnStartError,
84 ProviderAdapterV2,
85 type ProviderAdapterV2Error,
86 type ProviderAdapterV2Event,
87 type ProviderAdapterV2EnsureThreadInput,
88 type ProviderAdapterV2OpenSessionInput,
89 type ProviderAdapterV2SessionRuntime,
90 type ProviderAdapterV2Shape,
91 type ProviderAdapterV2ThreadSnapshot,
92 type ProviderAdapterV2TurnInput,
93 type ProviderAdapterV2TurnMessage,
94} from "@t3tools/provider-core/server/ProviderAdapter";
95import {73import {
96 backgroundWorkNotification,74 backgroundWorkNotification,
97 type BackgroundWorkReport,75 type BackgroundWorkReport,
...@@ -102,8 +80,8 @@ import { turnScopedSelectionTransition } from "@t3tools/provider-core/server/sel...@@ -102,8 +80,8 @@ import { turnScopedSelectionTransition } from "@t3tools/provider-core/server/sel
102import { museItemStatus, museToolPresentation } from "./itemPresentation.ts";80import { museItemStatus, museToolPresentation } from "./itemPresentation.ts";
10381
104const MUSE_PROVIDER = ProviderDriverKind.make("muse");82const MUSE_PROVIDER = ProviderDriverKind.make("muse");
105const isOpenSessionError = Schema.is(ProviderAdapterOpenSessionError);83const isOpenSessionError = Schema.is(ProviderAdapter.ProviderAdapterOpenSessionError);
106const isProtocolError = Schema.is(ProviderAdapterProtocolError);84const isProtocolError = Schema.is(ProviderAdapter.ProviderAdapterProtocolError);
10785
108const MuseProviderCapabilitiesV2 = {86const MuseProviderCapabilitiesV2 = {
109 runtimePolicy: { enforcement: "native" },87 runtimePolicy: { enforcement: "native" },
...@@ -204,12 +182,12 @@ export interface MuseAdapterV2Options {...@@ -204,12 +182,12 @@ export interface MuseAdapterV2Options {
204 readonly settings: MuseSettings;182 readonly settings: MuseSettings;
205 readonly environment: NodeJS.ProcessEnv;183 readonly environment: NodeJS.ProcessEnv;
206 readonly idAllocator: IdAllocator.IdAllocatorV2["Service"];184 readonly idAllocator: IdAllocator.IdAllocatorV2["Service"];
207 readonly host: ProviderHostShape;185 readonly host: ProviderHost.ProviderHostShape;
208 readonly fileSystem: FileSystem.FileSystem;186 readonly fileSystem: FileSystem.FileSystem;
209 readonly modelCatalog?: Effect.Effect<ReadonlyArray<ServerProviderModel>>;187 readonly modelCatalog?: Effect.Effect<ReadonlyArray<ServerProviderModel>>;
210 readonly createHost?: typeof createMuseSdkHost;188 readonly createHost?: typeof createMuseSdkHost;
211 readonly requestTimeoutMs?: number;189 readonly requestTimeoutMs?: number;
212 readonly nativeEventLogger?: EventNdjsonLogger;190 readonly nativeEventLogger?: ProviderEventLoggers.EventNdjsonLogger;
213 /** Where a turn Muse starts on its own (a finished workflow's report) asks for its run. */191 /** Where a turn Muse starts on its own (a finished workflow's report) asks for its run. */
214 readonly continuationRequests?: {192 readonly continuationRequests?: {
215 readonly offer: (193 readonly offer: (
...@@ -219,7 +197,7 @@ export interface MuseAdapterV2Options {...@@ -219,7 +197,7 @@ export interface MuseAdapterV2Options {
219}197}
220198
221interface ActiveTurn {199interface ActiveTurn {
222 readonly input: ProviderAdapterV2TurnInput;200 readonly input: ProviderAdapter.ProviderAdapterV2TurnInput;
223 providerTurn: OrchestrationV2ProviderTurn;201 providerTurn: OrchestrationV2ProviderTurn;
224 readonly nativeId: string;202 readonly nativeId: string;
225 /** Turns Muse started on its own while this run was active, which this run shows. */203 /** Turns Muse started on its own while this run was active, which this run shows. */
...@@ -267,21 +245,23 @@ const TOOLS_WITH_NATIVE_ROWS = new Set(["write_todos", "request_user_input", "wo...@@ -267,21 +245,23 @@ const TOOLS_WITH_NATIVE_ROWS = new Set(["write_todos", "request_user_input", "wo
267const responseAnswerSchema = Schema.Union([Schema.String, Schema.Array(Schema.String)]);245const responseAnswerSchema = Schema.Union([Schema.String, Schema.Array(Schema.String)]);
268246
269/** One scoped Muse host owns one native session; the orchestrator owns app runs and queuing. */247/** One scoped Muse host owns one native session; the orchestrator owns app runs and queuing. */
270export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapterV2Shape {248export function makeMuseAdapterV2(
249 options: MuseAdapterV2Options,
250): ProviderAdapter.ProviderAdapterV2Shape {
271 const { idAllocator } = options;251 const { idAllocator } = options;
272 const protocolError = (detail: string, payload?: unknown) =>252 const protocolError = (detail: string, payload?: unknown) =>
273 new ProviderAdapterProtocolError({253 new ProviderAdapter.ProviderAdapterProtocolError({
274 driver: MUSE_PROVIDER,254 driver: MUSE_PROVIDER,
275 detail,255 detail,
276 ...(payload === undefined ? {} : { payload }),256 ...(payload === undefined ? {} : { payload }),
277 });257 });
278 return ProviderAdapterV2.of({258 return ProviderAdapter.ProviderAdapterV2.of({
279 instanceId: options.instanceId,259 instanceId: options.instanceId,
280 driver: MUSE_PROVIDER,260 driver: MUSE_PROVIDER,
281 getCapabilities: () => Effect.succeed(MuseProviderCapabilitiesV2),261 getCapabilities: () => Effect.succeed(MuseProviderCapabilitiesV2),
282 planSelectionTransition: () => Effect.succeed(turnScopedSelectionTransition()),262 planSelectionTransition: () => Effect.succeed(turnScopedSelectionTransition()),
283 openSession: Effect.fn("MuseAdapterV2.openSession")(function* (263 openSession: Effect.fn("MuseAdapterV2.openSession")(function* (
284 input: ProviderAdapterV2OpenSessionInput,264 input: ProviderAdapter.ProviderAdapterV2OpenSessionInput,
285 ) {265 ) {
286 if (!options.settings.enabled) return yield* protocolError("Muse Code is disabled");266 if (!options.settings.enabled) return yield* protocolError("Muse Code is disabled");
287 if (input.runtimePolicy.interactionMode === "plan")267 if (input.runtimePolicy.interactionMode === "plan")
...@@ -307,8 +287,8 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -307,8 +287,8 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
307 lastError: null,287 lastError: null,
308 };288 };
309 const events = yield* Queue.unbounded<289 const events = yield* Queue.unbounded<
310 ProviderAdapterV2Event,290 ProviderAdapter.ProviderAdapterV2Event,
311 ProviderAdapterV2Error | Cause.Done291 ProviderAdapter.ProviderAdapterV2Error | Cause.Done
312 >();292 >();
313 type Inbox =293 type Inbox =
314 | { type: "notification"; method: string; params: unknown; epoch: number }294 | { type: "notification"; method: string; params: unknown; epoch: number }
...@@ -344,7 +324,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -344,7 +324,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
344 let wake:324 let wake:
345 | { readonly nativeId: string; readonly events: Array<[string, unknown]> }325 | { readonly nativeId: string; readonly events: Array<[string, unknown]> }
346 | undefined;326 | undefined;
347 const emit = (event: ProviderAdapterV2Event) =>327 const emit = (event: ProviderAdapter.ProviderAdapterV2Event) =>
348 Queue.offer(events, event).pipe(Effect.asVoid);328 Queue.offer(events, event).pipe(Effect.asVoid);
349 const decode = <A, I>(schema: Schema.Codec<A, I>, data: unknown) =>329 const decode = <A, I>(schema: Schema.Codec<A, I>, data: unknown) =>
350 Schema.decodeUnknownEffect(schema)(data).pipe(330 Schema.decodeUnknownEffect(schema)(data).pipe(
...@@ -1400,7 +1380,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1400,7 +1380,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1400 ).pipe(1380 ).pipe(
1401 Effect.mapError(1381 Effect.mapError(
1402 (error) =>1382 (error) =>
1403 new ProviderAdapterOpenSessionError({1383 new ProviderAdapter.ProviderAdapterOpenSessionError({
1404 driver: MUSE_PROVIDER,1384 driver: MUSE_PROVIDER,
1405 providerSessionId: input.providerSessionId,1385 providerSessionId: input.providerSessionId,
1406 cause: error.cause,1386 cause: error.cause,
...@@ -1472,7 +1452,9 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1472,7 +1452,9 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1472 );1452 );
1473 yield* launchHost();1453 yield* launchHost();
14741454
1475 const register = Effect.fnUntraced(function* (args: ProviderAdapterV2EnsureThreadInput) {1455 const register = Effect.fnUntraced(function* (
1456 args: ProviderAdapter.ProviderAdapterV2EnsureThreadInput,
1457 ) {
1476 if (broken || closed)1458 if (broken || closed)
1477 return yield* protocolError("Muse host is unavailable; reopen the session");1459 return yield* protocolError("Muse host is unavailable; reopen the session");
1478 if (active)1460 if (active)
...@@ -1592,7 +1574,9 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1592,7 +1574,9 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1592 ),1574 ),
1593 );1575 );
1594 });1576 });
1595 const prompt = Effect.fnUntraced(function* (message: ProviderAdapterV2TurnMessage) {1577 const prompt = Effect.fnUntraced(function* (
1578 message: ProviderAdapter.ProviderAdapterV2TurnMessage,
1579 ) {
1596 const parts: SendUserTurnOptions<unknown>["input"] = [];1580 const parts: SendUserTurnOptions<unknown>["input"] = [];
1597 const text = providerMessageTextWithAttachmentPaths({1581 const text = providerMessageTextWithAttachmentPaths({
1598 text: message.text,1582 text: message.text,
...@@ -1635,7 +1619,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1635,7 +1619,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1635 );1619 );
1636 });1620 });
1637 const start = Effect.fnUntraced(function* (1621 const start = Effect.fnUntraced(function* (
1638 turnInput: ProviderAdapterV2TurnInput,1622 turnInput: ProviderAdapter.ProviderAdapterV2TurnInput,
1639 compact = false,1623 compact = false,
1640 ) {1624 ) {
1641 if (!validateThread(turnInput.providerThread) || broken || closed)1625 if (!validateThread(turnInput.providerThread) || broken || closed)
...@@ -1783,7 +1767,10 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1783,7 +1767,10 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1783 // Only messages are read back; T3 owns turn and item history.1767 // Only messages are read back; T3 owns turn and item history.
1784 const snapshot = Effect.fnUntraced(function* (1768 const snapshot = Effect.fnUntraced(function* (
1785 current: OrchestrationV2ProviderThread,1769 current: OrchestrationV2ProviderThread,
1786 ): Effect.fn.Return<ProviderAdapterV2ThreadSnapshot, ProviderAdapterV2Error> {1770 ): Effect.fn.Return<
1771 ProviderAdapter.ProviderAdapterV2ThreadSnapshot,
1772 ProviderAdapter.ProviderAdapterV2Error
1773 > {
1787 const result = yield* request("session/read", { excludeItems: false }, false).pipe(1774 const result = yield* request("session/read", { excludeItems: false }, false).pipe(
1788 Effect.flatMap((value) => decode(MuseSessionResult, value)),1775 Effect.flatMap((value) => decode(MuseSessionResult, value)),
1789 );1776 );
...@@ -1821,7 +1808,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1821,7 +1808,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1821 providerPayload: items,1808 providerPayload: items,
1822 };1809 };
1823 });1810 });
1824 const runtime: ProviderAdapterV2SessionRuntime = {1811 const runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime = {
1825 instanceId: options.instanceId,1812 instanceId: options.instanceId,
1826 driver: MUSE_PROVIDER,1813 driver: MUSE_PROVIDER,
1827 providerSessionId: input.providerSessionId,1814 providerSessionId: input.providerSessionId,
...@@ -1836,7 +1823,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1836,7 +1823,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1836 commands.withPermits(1),1823 commands.withPermits(1),
1837 Effect.mapError(1824 Effect.mapError(
1838 (cause) =>1825 (cause) =>
1839 new ProviderAdapterEnsureThreadError({1826 new ProviderAdapter.ProviderAdapterEnsureThreadError({
1840 driver: MUSE_PROVIDER,1827 driver: MUSE_PROVIDER,
1841 threadId: args.threadId,1828 threadId: args.threadId,
1842 cause,1829 cause,
...@@ -1853,7 +1840,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1853,7 +1840,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1853 commands.withPermits(1),1840 commands.withPermits(1),
1854 Effect.mapError(1841 Effect.mapError(
1855 (cause) =>1842 (cause) =>
1856 new ProviderAdapterResumeThreadError({1843 new ProviderAdapter.ProviderAdapterResumeThreadError({
1857 driver: MUSE_PROVIDER,1844 driver: MUSE_PROVIDER,
1858 providerSessionId: input.providerSessionId,1845 providerSessionId: input.providerSessionId,
1859 providerThreadId: args.providerThread.id,1846 providerThreadId: args.providerThread.id,
...@@ -1866,7 +1853,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1866,7 +1853,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1866 commands.withPermits(1),1853 commands.withPermits(1),
1867 Effect.mapError(1854 Effect.mapError(
1868 (cause) =>1855 (cause) =>
1869 new ProviderAdapterTurnStartError({1856 new ProviderAdapter.ProviderAdapterTurnStartError({
1870 driver: MUSE_PROVIDER,1857 driver: MUSE_PROVIDER,
1871 threadId: args.threadId,1858 threadId: args.threadId,
1872 providerThreadId: args.providerThread.id,1859 providerThreadId: args.providerThread.id,
...@@ -1897,7 +1884,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1897,7 +1884,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1897 commands.withPermits(1),1884 commands.withPermits(1),
1898 Effect.mapError(1885 Effect.mapError(
1899 (cause) =>1886 (cause) =>
1900 new ProviderAdapterSteerRunError({1887 new ProviderAdapter.ProviderAdapterSteerRunError({
1901 driver: MUSE_PROVIDER,1888 driver: MUSE_PROVIDER,
1902 providerThreadId: args.providerThread.id,1889 providerThreadId: args.providerThread.id,
1903 providerTurnId: args.providerTurnId,1890 providerTurnId: args.providerTurnId,
...@@ -1946,7 +1933,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1946,7 +1933,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1946 commands.withPermits(1),1933 commands.withPermits(1),
1947 Effect.mapError(1934 Effect.mapError(
1948 (cause) =>1935 (cause) =>
1949 new ProviderAdapterInterruptError({1936 new ProviderAdapter.ProviderAdapterInterruptError({
1950 driver: MUSE_PROVIDER,1937 driver: MUSE_PROVIDER,
1951 providerThreadId: args.providerThread.id,1938 providerThreadId: args.providerThread.id,
1952 providerTurnId: args.providerTurnId,1939 providerTurnId: args.providerTurnId,
...@@ -1999,7 +1986,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -1999,7 +1986,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
1999 }).pipe(1986 }).pipe(
2000 Effect.mapError(1987 Effect.mapError(
2001 (cause) =>1988 (cause) =>
2002 new ProviderAdapterRuntimeRequestResponseError({1989 new ProviderAdapter.ProviderAdapterRuntimeRequestResponseError({
2003 driver: MUSE_PROVIDER,1990 driver: MUSE_PROVIDER,
2004 requestId: args.requestId,1991 requestId: args.requestId,
2005 cause,1992 cause,
...@@ -2014,7 +2001,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -2014,7 +2001,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
2014 commands.withPermits(1),2001 commands.withPermits(1),
2015 Effect.mapError(2002 Effect.mapError(
2016 (cause) =>2003 (cause) =>
2017 new ProviderAdapterReadThreadSnapshotError({2004 new ProviderAdapter.ProviderAdapterReadThreadSnapshotError({
2018 driver: MUSE_PROVIDER,2005 driver: MUSE_PROVIDER,
2019 providerThreadId: args.providerThread.id,2006 providerThreadId: args.providerThread.id,
2020 cause,2007 cause,
...@@ -2025,7 +2012,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -2025,7 +2012,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
2025 // portable context handoff for forks and does not rewind Muse conversations.2012 // portable context handoff for forks and does not rewind Muse conversations.
2026 rollbackThread: (args) =>2013 rollbackThread: (args) =>
2027 Effect.fail(2014 Effect.fail(
2028 new ProviderAdapterRollbackThreadError({2015 new ProviderAdapter.ProviderAdapterRollbackThreadError({
2029 driver: MUSE_PROVIDER,2016 driver: MUSE_PROVIDER,
2030 providerThreadId: args.providerThread.id,2017 providerThreadId: args.providerThread.id,
2031 checkpointId: args.target.checkpointId,2018 checkpointId: args.target.checkpointId,
...@@ -2034,7 +2021,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte...@@ -2034,7 +2021,7 @@ export function makeMuseAdapterV2(options: MuseAdapterV2Options): ProviderAdapte
2034 ),2021 ),
2035 forkThread: (args) =>2022 forkThread: (args) =>
2036 Effect.fail(2023 Effect.fail(
2037 new ProviderAdapterForkThreadError({2024 new ProviderAdapter.ProviderAdapterForkThreadError({
2038 driver: MUSE_PROVIDER,2025 driver: MUSE_PROVIDER,
2039 providerThreadId: args.sourceProviderThread.id,2026 providerThreadId: args.sourceProviderThread.id,
2040 cause: "Muse Code does not support native forks in T3 Code.",2027 cause: "Muse Code does not support native forks in T3 Code.",
packages/provider-muse/src/server/driver.ts+3-3
...@@ -8,7 +8,7 @@ import * as Schema from "effect/Schema";...@@ -8,7 +8,7 @@ import * as Schema from "effect/Schema";
8import { HttpClient } from "effect/http";8import { HttpClient } from "effect/http";
9import { ChildProcessSpawner } from "effect/process";9import { ChildProcessSpawner } from "effect/process";
1010
11import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost";11import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
12import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion";12import { expandHomePath } from "@t3tools/provider-core/server/pathExpansion";
13import { makeMuseTextGeneration } from "./textGeneration.ts";13import { makeMuseTextGeneration } from "./textGeneration.ts";
14import { ProviderDriverError } from "@t3tools/provider-core/server/errors";14import { ProviderDriverError } from "@t3tools/provider-core/server/errors";
...@@ -42,7 +42,7 @@ const decodeMuseSettings = Schema.decodeSync(MuseSettings);...@@ -42,7 +42,7 @@ const decodeMuseSettings = Schema.decodeSync(MuseSettings);
4242
43export type MuseDriverEnv =43export type MuseDriverEnv =
44 | IdAllocator.IdAllocatorV244 | IdAllocator.IdAllocatorV2
45 | ProviderHost45 | ProviderHost.ProviderHost
46 | ChildProcessSpawner.ChildProcessSpawner46 | ChildProcessSpawner.ChildProcessSpawner
47 | FileSystem.FileSystem47 | FileSystem.FileSystem
48 | HttpClient.HttpClient48 | HttpClient.HttpClient
...@@ -60,7 +60,7 @@ export const MuseDriver: ProviderDriver<MuseSettings, MuseDriverEnv> = {...@@ -60,7 +60,7 @@ export const MuseDriver: ProviderDriver<MuseSettings, MuseDriverEnv> = {
60 const fileSystem = yield* FileSystem.FileSystem;60 const fileSystem = yield* FileSystem.FileSystem;
61 const path = yield* Path.Path;61 const path = yield* Path.Path;
62 const httpClient = yield* HttpClient.HttpClient;62 const httpClient = yield* HttpClient.HttpClient;
63 const host = yield* ProviderHost;63 const host = yield* ProviderHost.ProviderHost;
64 const eventLoggers = yield* ProviderEventLoggers.ProviderEventLoggers;64 const eventLoggers = yield* ProviderEventLoggers.ProviderEventLoggers;
65 const { cwd } = host.paths;65 const { cwd } = host.paths;
66 const idAllocator = yield* IdAllocator.IdAllocatorV2;66 const idAllocator = yield* IdAllocator.IdAllocatorV2;
packages/provider-pi/src/server/adapter.test.ts+10-13
...@@ -33,16 +33,12 @@ import * as TestClock from "effect/testing/TestClock";...@@ -33,16 +33,12 @@ import * as TestClock from "effect/testing/TestClock";
33import { ChildProcess, ChildProcessSpawner } from "effect/process";33import { ChildProcess, ChildProcessSpawner } from "effect/process";
34import { HostProcessEnvironment } from "@t3tools/shared/hostProcess";34import { HostProcessEnvironment } from "@t3tools/shared/hostProcess";
3535
36import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost";36import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
37import { layerTestProviderHost } from "@t3tools/provider-testing/host";37import { layerTestProviderHost } from "@t3tools/provider-testing/host";
38import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests";38import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests";
39import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";39import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";
40import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";40import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator";
41import {41import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter";
42 ProviderAdapterV2RuntimePolicy,
43 type ProviderAdapterV2Event,
44 type ProviderAdapterV2SessionRuntime,
45} from "@t3tools/provider-core/server/ProviderAdapter";
46import { handoffBudget } from "@t3tools/provider-core/server/handoffBudget";42import { handoffBudget } from "@t3tools/provider-core/server/handoffBudget";
47import {43import {
48 makePiAdapterV2,44 makePiAdapterV2,
...@@ -68,7 +64,7 @@ const FAKE_SESSION_FILE = "/fake/.pi/agent/sessions/--workspace--/0001_abc.jsonl...@@ -68,7 +64,7 @@ const FAKE_SESSION_FILE = "/fake/.pi/agent/sessions/--workspace--/0001_abc.jsonl
68/** Deliberately outside the valid pid range so a group-kill can never land. */64/** Deliberately outside the valid pid range so a group-kill can never land. */
69const FAKE_PID = 999_999_999;65const FAKE_PID = 999_999_999;
7066
71const runtimePolicy = ProviderAdapterV2RuntimePolicy.make({67const runtimePolicy = ProviderAdapter.ProviderAdapterV2RuntimePolicy.make({
72 runtimeMode: "full-access",68 runtimeMode: "full-access",
73 interactionMode: "default",69 interactionMode: "default",
74 cwd: null,70 cwd: null,
...@@ -331,7 +327,7 @@ const makeAdapter = Effect.fnUntraced(function* (...@@ -331,7 +327,7 @@ const makeAdapter = Effect.fnUntraced(function* (
331 continuationRequests?: PiAdapterV2Options["continuationRequests"],327 continuationRequests?: PiAdapterV2Options["continuationRequests"],
332) {328) {
333 const idAllocator = yield* IdAllocator.IdAllocatorV2;329 const idAllocator = yield* IdAllocator.IdAllocatorV2;
334 const host = yield* ProviderHost;330 const host = yield* ProviderHost.ProviderHost;
335 const fileSystem = yield* FileSystem.FileSystem;331 const fileSystem = yield* FileSystem.FileSystem;
336 const spawner =332 const spawner =
337 forkFake === undefined333 forkFake === undefined
...@@ -383,12 +379,12 @@ const openRuntime = Effect.fnUntraced(function* (...@@ -383,12 +379,12 @@ const openRuntime = Effect.fnUntraced(function* (
383 modelSelection: modelSelection(model),379 modelSelection: modelSelection(model),
384 runtimePolicy,380 runtimePolicy,
385 });381 });
386 const emitted = yield* Queue.unbounded<ProviderAdapterV2Event>();382 const emitted = yield* Queue.unbounded<ProviderAdapter.ProviderAdapterV2Event>();
387 yield* runtime.events.pipe(383 yield* runtime.events.pipe(
388 Stream.runForEach((event) => Queue.offer(emitted, event)),384 Stream.runForEach((event) => Queue.offer(emitted, event)),
389 Effect.forkScoped,385 Effect.forkScoped,
390 );386 );
391 const takeEvent = (predicate: (event: ProviderAdapterV2Event) => boolean) =>387 const takeEvent = (predicate: (event: ProviderAdapter.ProviderAdapterV2Event) => boolean) =>
392 Effect.gen(function* () {388 Effect.gen(function* () {
393 while (true) {389 while (true) {
394 const event = yield* Queue.take(emitted);390 const event = yield* Queue.take(emitted);
...@@ -426,7 +422,7 @@ const makeAppThread = Effect.fnUntraced(function* (model: string, threadId = THR...@@ -426,7 +422,7 @@ const makeAppThread = Effect.fnUntraced(function* (model: string, threadId = THR
426});422});
427423
428const startTurn = Effect.fnUntraced(function* (424const startTurn = Effect.fnUntraced(function* (
429 runtime: ProviderAdapterV2SessionRuntime,425 runtime: ProviderAdapter.ProviderAdapterV2SessionRuntime,
430 providerThread: OrchestrationV2ProviderThread,426 providerThread: OrchestrationV2ProviderThread,
431 model = "default",427 model = "default",
432 attachments: ReadonlyArray<ChatAttachment> = [],428 attachments: ReadonlyArray<ChatAttachment> = [],
...@@ -832,8 +828,9 @@ describe("PiAdapterV2", () => {...@@ -832,8 +828,9 @@ describe("PiAdapterV2", () => {
832 });828 });
833 yield* fake.emit({ type: "agent_start" });829 yield* fake.emit({ type: "agent_start" });
834 yield* Queue.take(offers);830 yield* Queue.take(offers);
835 const requests: Array<Extract<ProviderAdapterV2Event, { type: "runtime_request.updated" }>> =831 const requests: Array<
836 [];832 Extract<ProviderAdapter.ProviderAdapterV2Event, { type: "runtime_request.updated" }>
833 > = [];
837 fake.deferNextModelSelection();834 fake.deferNextModelSelection();
838 const starting = yield* startTurn(835 const starting = yield* startTurn(
839 runtime,836 runtime,
packages/provider-pi/src/server/adapter.ts+5-5
...@@ -60,7 +60,7 @@ import * as Semaphore from "effect/Semaphore";...@@ -60,7 +60,7 @@ import * as Semaphore from "effect/Semaphore";
60import * as Stream from "effect/Stream";60import * as Stream from "effect/Stream";
61import { ChildProcessSpawner } from "effect/process";61import { ChildProcessSpawner } from "effect/process";
6262
63import { ProviderHost, type ProviderHostShape } from "@t3tools/provider-core/server/ProviderHost";63import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
64import { mcpToolPresentation } from "@t3tools/provider-core/server/mcpToolPresentation";64import { mcpToolPresentation } from "@t3tools/provider-core/server/mcpToolPresentation";
65import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";65import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession";
66import {66import {
...@@ -231,7 +231,7 @@ export interface PiAdapterV2Options {...@@ -231,7 +231,7 @@ export interface PiAdapterV2Options {
231 readonly spawner: ChildProcessSpawner.ChildProcessSpawner["Service"];231 readonly spawner: ChildProcessSpawner.ChildProcessSpawner["Service"];
232 readonly fileSystem: FileSystem.FileSystem;232 readonly fileSystem: FileSystem.FileSystem;
233 readonly idAllocator: IdAllocator.IdAllocatorV2["Service"];233 readonly idAllocator: IdAllocator.IdAllocatorV2["Service"];
234 readonly host: ProviderHostShape;234 readonly host: ProviderHost.ProviderHostShape;
235 readonly continuationRequests?: {235 readonly continuationRequests?: {
236 readonly offer: (236 readonly offer: (
237 request: ProviderContinuationRequests.ProviderContinuationRequest,237 request: ProviderContinuationRequests.ProviderContinuationRequest,
...@@ -3201,7 +3201,7 @@ export type PiAdapterV2DriverEnv =...@@ -3201,7 +3201,7 @@ export type PiAdapterV2DriverEnv =
3201 | ChildProcessSpawner.ChildProcessSpawner3201 | ChildProcessSpawner.ChildProcessSpawner
3202 | FileSystem.FileSystem3202 | FileSystem.FileSystem
3203 | IdAllocator.IdAllocatorV23203 | IdAllocator.IdAllocatorV2
3204 | ProviderHost;3204 | ProviderHost.ProviderHost;
32053205
3206export const PiAdapterV2Driver: ProviderAdapterDriver<PiSettings, PiAdapterV2DriverEnv> = {3206export const PiAdapterV2Driver: ProviderAdapterDriver<PiSettings, PiAdapterV2DriverEnv> = {
3207 driverKind: PI_DRIVER_KIND,3207 driverKind: PI_DRIVER_KIND,
...@@ -3213,7 +3213,7 @@ export const PiAdapterV2Driver: ProviderAdapterDriver<PiSettings, PiAdapterV2Dri...@@ -3213,7 +3213,7 @@ export const PiAdapterV2Driver: ProviderAdapterDriver<PiSettings, PiAdapterV2Dri
3213 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;3213 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
3214 const fileSystem = yield* FileSystem.FileSystem;3214 const fileSystem = yield* FileSystem.FileSystem;
3215 const idAllocator = yield* IdAllocator.IdAllocatorV2;3215 const idAllocator = yield* IdAllocator.IdAllocatorV2;
3216 const host = yield* ProviderHost;3216 const host = yield* ProviderHost.ProviderHost;
3217 const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests;3217 const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests;
3218 return makePiAdapterV2({3218 return makePiAdapterV2({
3219 instanceId: input.instanceId,3219 instanceId: input.instanceId,
...@@ -3249,7 +3249,7 @@ const layer: Layer.Layer<ProviderAdapter.ProviderAdapterV2, never, PiAdapterV2Dr...@@ -3249,7 +3249,7 @@ const layer: Layer.Layer<ProviderAdapter.ProviderAdapterV2, never, PiAdapterV2Dr
3249 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;3249 const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
3250 const fileSystem = yield* FileSystem.FileSystem;3250 const fileSystem = yield* FileSystem.FileSystem;
3251 const idAllocator = yield* IdAllocator.IdAllocatorV2;3251 const idAllocator = yield* IdAllocator.IdAllocatorV2;
3252 const host = yield* ProviderHost;3252 const host = yield* ProviderHost.ProviderHost;
3253 const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests;3253 const continuationRequests = yield* ProviderContinuationRequests.ProviderContinuationRequests;
3254 return makePiAdapterV2({3254 return makePiAdapterV2({
3255 instanceId: PI_DEFAULT_INSTANCE_ID,3255 instanceId: PI_DEFAULT_INSTANCE_ID,
packages/provider-pi/src/server/driver.ts+3-3
...@@ -15,7 +15,7 @@ import * as Schema from "effect/Schema";...@@ -15,7 +15,7 @@ import * as Schema from "effect/Schema";
15import { HttpClient } from "effect/http";15import { HttpClient } from "effect/http";
16import { ChildProcessSpawner } from "effect/process";16import { ChildProcessSpawner } from "effect/process";
1717
18import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost";18import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
19import { makePiTextGeneration } from "./textGeneration.ts";19import { makePiTextGeneration } from "./textGeneration.ts";
20import { PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "./adapter.ts";20import { PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "./adapter.ts";
21import { ProviderDriverError } from "@t3tools/provider-core/server/errors";21import { ProviderDriverError } from "@t3tools/provider-core/server/errors";
...@@ -56,7 +56,7 @@ const UPDATE = makePackageManagedProviderMaintenanceResolver({...@@ -56,7 +56,7 @@ const UPDATE = makePackageManagedProviderMaintenanceResolver({
5656
57export type PiDriverEnv =57export type PiDriverEnv =
58 | PiAdapterV2DriverEnv58 | PiAdapterV2DriverEnv
59 | ProviderHost59 | ProviderHost.ProviderHost
60 | ChildProcessSpawner.ChildProcessSpawner60 | ChildProcessSpawner.ChildProcessSpawner
61 | FileSystem.FileSystem61 | FileSystem.FileSystem
62 | HttpClient.HttpClient62 | HttpClient.HttpClient
...@@ -92,7 +92,7 @@ export const PiDriver: ProviderDriver<PiSettings, PiDriverEnv> = {...@@ -92,7 +92,7 @@ export const PiDriver: ProviderDriver<PiSettings, PiDriverEnv> = {
92 const fileSystem = yield* FileSystem.FileSystem;92 const fileSystem = yield* FileSystem.FileSystem;
93 const pathService = yield* Path.Path;93 const pathService = yield* Path.Path;
94 const httpClient = yield* HttpClient.HttpClient;94 const httpClient = yield* HttpClient.HttpClient;
95 const host = yield* ProviderHost;95 const host = yield* ProviderHost.ProviderHost;
96 const { cwd } = host.paths;96 const { cwd } = host.paths;
97 const processEnv = mergeProviderInstanceEnvironment(environment);97 const processEnv = mergeProviderInstanceEnvironment(environment);
98 const continuationIdentity = defaultProviderContinuationIdentity({98 const continuationIdentity = defaultProviderContinuationIdentity({
packages/provider-testing/src/host.ts+5-5
...@@ -1,12 +1,12 @@...@@ -1,12 +1,12 @@
1/**1/**
2 * A `ProviderHost` for driver and adapter tests. Its directories live in a2 * A `ProviderHost.ProviderHost` for driver and adapter tests. Its directories live in a
3 * scoped temp directory, settings are fixed, and background work always runs3 * scoped temp directory, settings are fixed, and background work always runs
4 * unless the test says otherwise.4 * unless the test says otherwise.
5 *5 *
6 * @module provider-testing/host6 * @module provider-testing/host
7 */7 */
8import { DEFAULT_SERVER_SETTINGS, type ServerSettings } from "@t3tools/contracts";8import { DEFAULT_SERVER_SETTINGS, type ServerSettings } from "@t3tools/contracts";
9import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost";9import * as ProviderHost from "@t3tools/provider-core/server/ProviderHost";
10import * as Effect from "effect/Effect";10import * as Effect from "effect/Effect";
11import * as FileSystem from "effect/FileSystem";11import * as FileSystem from "effect/FileSystem";
12import * as Layer from "effect/Layer";12import * as Layer from "effect/Layer";
...@@ -23,9 +23,9 @@ export interface TestProviderHostOptions {...@@ -23,9 +23,9 @@ export interface TestProviderHostOptions {
2323
24export const layerTestProviderHost = (24export const layerTestProviderHost = (
25 options: TestProviderHostOptions = {},25 options: TestProviderHostOptions = {},
26): Layer.Layer<ProviderHost, never, FileSystem.FileSystem | Path.Path> =>26): Layer.Layer<ProviderHost.ProviderHost, never, FileSystem.FileSystem | Path.Path> =>
27 Layer.effect(27 Layer.effect(
28 ProviderHost,28 ProviderHost.ProviderHost,
29 Effect.gen(function* () {29 Effect.gen(function* () {
30 const fileSystem = yield* FileSystem.FileSystem;30 const fileSystem = yield* FileSystem.FileSystem;
31 const path = yield* Path.Path;31 const path = yield* Path.Path;
...@@ -39,7 +39,7 @@ export const layerTestProviderHost = (...@@ -39,7 +39,7 @@ export const layerTestProviderHost = (
39 yield* fileSystem.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);39 yield* fileSystem.makeDirectory(directory, { recursive: true }).pipe(Effect.orDie);
40 }40 }
41 const settings = options.settings ?? DEFAULT_SERVER_SETTINGS;41 const settings = options.settings ?? DEFAULT_SERVER_SETTINGS;
42 return ProviderHost.of({42 return ProviderHost.ProviderHost.of({
43 paths: { cwd: options.cwd ?? process.cwd(), baseDir, stateDir, providerStatusCacheDir },43 paths: { cwd: options.cwd ?? process.cwd(), baseDir, stateDir, providerStatusCacheDir },
44 settings: {44 settings: {
45 get: Effect.succeed(settings),45 get: Effect.succeed(settings),