From 19822fa90e262b729f10dbcc8c4e762fd2e6e2b0 Mon Sep 17 00:00:00 2001 From: chrisblaschke Date: Sat, 14 Nov 2026 02:03:43 -0600 Subject: [PATCH 1/2] fix(server): allow explicit Pi models before discovery --- .../src/mcp/OrchestratorMcpService.test.ts | 58 +++++++++++++++++++ apps/server/src/mcp/OrchestratorMcpService.ts | 10 +++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/apps/server/src/mcp/OrchestratorMcpService.test.ts b/apps/server/src/mcp/OrchestratorMcpService.test.ts index 8df18bb356cf6..afee46f4a788b 100644 --- a/apps/server/src/mcp/OrchestratorMcpService.test.ts +++ b/apps/server/src/mcp/OrchestratorMcpService.test.ts @@ -30,6 +30,7 @@ import { type ServerProvider, } from "@t3tools/contracts"; import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; +import { buildInitialPiProviderSnapshot } from "../../../../packages/provider-pi/src/server/status.ts"; import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; import * as Duration from "effect/Duration"; @@ -1461,6 +1462,63 @@ describe("OrchestratorMcpService provider resolution", () => { skills: [], }); + it.effect.each([ + { status: "warning", customModels: [] }, + { status: "ready", customModels: [] }, + { status: "ready", customModels: ["custom/model"] }, + ] as const)("accepts an explicit Pi model before discovery: %j", (row) => + Effect.gen(function* () { + const initial = yield* buildInitialPiProviderSnapshot({ + enabled: true, + binaryPath: "pi", + launchArgs: "", + customModels: [...row.customModels], + }); + yield* OrchestratorMcpService.requireAdvertisedModel( + { + ...initial, + instanceId: ProviderInstanceId.make("pi"), + driver: ProviderDriverKind.make("pi"), + status: row.status, + }, + "anthropic/claude-opus", + ); + }), + ); + + it.effect.each(["discovered", "unauthenticated", "other provider"] as const)( + "rejects an unadvertised model with a %s inventory", + (inventory) => + Effect.gen(function* () { + const provider = providerSnapshot({ + instanceId: ProviderInstanceId.make("test"), + driver: ProviderDriverKind.make(inventory === "other provider" ? "muse" : "pi"), + model: "default", + }); + const error = yield* OrchestratorMcpService.requireAdvertisedModel( + { + ...provider, + auth: { status: inventory === "unauthenticated" ? "unauthenticated" : "unknown" }, + models: + inventory === "discovered" + ? [ + ...provider.models, + { + slug: "anthropic/claude-sonnet", + name: "Claude Sonnet", + subProvider: "anthropic", + isCustom: false, + capabilities: null, + }, + ] + : provider.models, + }, + "anthropic/claude-opus", + ).pipe(Effect.flip); + assert.equal(error.code, "model_unavailable"); + }), + ); + const providerRegistryLayer = (providers: ReadonlyArray) => Layer.mock(ProviderRegistry.ProviderRegistry)({ getProviders: Effect.succeed(providers), diff --git a/apps/server/src/mcp/OrchestratorMcpService.ts b/apps/server/src/mcp/OrchestratorMcpService.ts index 0bbef0d92a606..c6238a20c4b2c 100644 --- a/apps/server/src/mcp/OrchestratorMcpService.ts +++ b/apps/server/src/mcp/OrchestratorMcpService.ts @@ -395,9 +395,15 @@ const advertisedModel = (provider: ServerProvider, model: string) => candidate.aliases?.some((alias) => alias.toLowerCase() === model.toLowerCase()), ); -/** A provider that lists no models accepts any slug. */ +/** Empty inventories and Pi's undiscovered placeholder inventory accept any slug. */ export const requireAdvertisedModel = (provider: ServerProvider, model: string) => - provider.models.length > 0 && advertisedModel(provider, model) === undefined + provider.models.length > 0 && + (provider.driver !== "pi" || + provider.auth.status !== "unknown" || + provider.models.some( + (candidate) => !candidate.isCustom && candidate.subProvider !== undefined, + )) && + advertisedModel(provider, model) === undefined ? Effect.fail( failure( "model_unavailable", From 24dafe03db77bb2be934c2380ca07c227602f8ab Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Sun, 15 Nov 2026 06:10:10 +0000 Subject: [PATCH 2/2] test(server): cover Pi model validation in one table Co-Authored-By: Claude Opus 5.5 --- .../src/mcp/OrchestratorMcpService.test.ts | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/apps/server/src/mcp/OrchestratorMcpService.test.ts b/apps/server/src/mcp/OrchestratorMcpService.test.ts index afee46f4a788b..53ab5093da7cf 100644 --- a/apps/server/src/mcp/OrchestratorMcpService.test.ts +++ b/apps/server/src/mcp/OrchestratorMcpService.test.ts @@ -30,7 +30,6 @@ import { type ServerProvider, } from "@t3tools/contracts"; import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; -import { buildInitialPiProviderSnapshot } from "../../../../packages/provider-pi/src/server/status.ts"; import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; import * as Duration from "effect/Duration"; @@ -1463,62 +1462,64 @@ describe("OrchestratorMcpService provider resolution", () => { }); it.effect.each([ - { status: "warning", customModels: [] }, - { status: "ready", customModels: [] }, - { status: "ready", customModels: ["custom/model"] }, - ] as const)("accepts an explicit Pi model before discovery: %j", (row) => + { + case: "Pi before discovery", + driver: "pi", + auth: "unknown", + discovered: false, + accepted: true, + }, + { + case: "Pi after discovery", + driver: "pi", + auth: "unknown", + discovered: true, + accepted: false, + }, + { + case: "unauthenticated Pi", + driver: "pi", + auth: "unauthenticated", + discovered: false, + accepted: false, + }, + { + case: "another provider", + driver: "muse", + auth: "unknown", + discovered: false, + accepted: false, + }, + ] as const)("validates an explicit model for $case", (row) => Effect.gen(function* () { - const initial = yield* buildInitialPiProviderSnapshot({ - enabled: true, - binaryPath: "pi", - launchArgs: "", - customModels: [...row.customModels], + const provider = providerSnapshot({ + instanceId: ProviderInstanceId.make("test"), + driver: ProviderDriverKind.make(row.driver), + model: "default", }); - yield* OrchestratorMcpService.requireAdvertisedModel( + const result = yield* OrchestratorMcpService.requireAdvertisedModel( { - ...initial, - instanceId: ProviderInstanceId.make("pi"), - driver: ProviderDriverKind.make("pi"), - status: row.status, + ...provider, + auth: { status: row.auth }, + models: [ + ...provider.models, + row.discovered + ? { + slug: "anthropic/claude-sonnet", + name: "Claude Sonnet", + subProvider: "anthropic", + isCustom: false, + capabilities: null, + } + : { slug: "custom/model", name: "custom/model", isCustom: true, capabilities: null }, + ], }, "anthropic/claude-opus", - ); + ).pipe(Effect.result); + assert.equal(Result.isSuccess(result), row.accepted); }), ); - it.effect.each(["discovered", "unauthenticated", "other provider"] as const)( - "rejects an unadvertised model with a %s inventory", - (inventory) => - Effect.gen(function* () { - const provider = providerSnapshot({ - instanceId: ProviderInstanceId.make("test"), - driver: ProviderDriverKind.make(inventory === "other provider" ? "muse" : "pi"), - model: "default", - }); - const error = yield* OrchestratorMcpService.requireAdvertisedModel( - { - ...provider, - auth: { status: inventory === "unauthenticated" ? "unauthenticated" : "unknown" }, - models: - inventory === "discovered" - ? [ - ...provider.models, - { - slug: "anthropic/claude-sonnet", - name: "Claude Sonnet", - subProvider: "anthropic", - isCustom: false, - capabilities: null, - }, - ] - : provider.models, - }, - "anthropic/claude-opus", - ).pipe(Effect.flip); - assert.equal(error.code, "model_unavailable"); - }), - ); - const providerRegistryLayer = (providers: ReadonlyArray) => Layer.mock(ProviderRegistry.ProviderRegistry)({ getProviders: Effect.succeed(providers),