From 9b0df1358f9f9c3277bcb33777c2435b88ee75c4 Mon Sep 17 00:00:00 2001 From: Julius Marminge Date: Thu, 8 Oct 2026 14:18:17 -0700 Subject: [PATCH] refactor(provider-pi): move Pi into its own provider package (#17302) Co-authored-by: Claude Opus 5.5 --- apps/mobile/package.json | 2 + apps/mobile/src/components/ProviderIcon.tsx | 23 ++-- apps/mobile/src/lib/providerClients.ts | 11 ++ apps/server/package.json | 1 + .../scripts/record-grok-acp-replay-fixture.ts | 2 +- .../scripts/record-pi-rpc-replay-fixture.ts | 2 +- ...OrchestratorMcpToolkit.integration.test.ts | 2 +- .../Adapters/AcpAdapterV2.test.ts | 2 +- .../orchestration-v2/Adapters/AcpAdapterV2.ts | 2 +- .../Adapters/ClaudeAdapterV2.test.ts | 2 +- .../Adapters/ClaudeAdapterV2.ts | 2 +- .../Adapters/CodexAdapterV2.test.ts | 4 +- .../Adapters/CodexAdapterV2.ts | 4 +- .../Adapters/GrokAdapterV2.testkit.ts | 2 +- .../Adapters/GrokAdapterV2.ts | 2 +- .../Adapters/MuseAdapterV2.test.ts | 2 +- .../Adapters/MuseAdapterV2.testkit.ts | 2 +- .../Adapters/MuseAdapterV2.ts | 2 +- .../Adapters/OpenCode2AdapterV2.test.ts | 4 +- .../Adapters/OpenCode2AdapterV2.ts | 2 +- .../Adapters/PiAdapterV2.testkit.ts | 2 +- .../ContextHandoffBudget.test.ts | 2 +- .../ContextHandoffDelivery.ts | 6 +- .../orchestration-v2/ContextHandoffService.ts | 2 +- .../OpenCode2OrchestratorV2.live.test.ts | 2 +- .../src/orchestration-v2/Orchestrator.ts | 2 +- .../ProviderContinuationService.test.ts | 2 +- .../ProviderContinuationService.ts | 2 +- .../ProviderTurnStartService.ts | 2 +- .../builtInProviderAdapterDrivers.ts | 2 +- .../src/orchestration-v2/runtimeLayer.ts | 2 +- .../testkit/ProviderReplayHarness.ts | 2 +- .../ProviderSwitch.integration.test.ts | 2 +- .../src/provider/AntigravityProvider.ts | 2 +- .../src/provider/Drivers/AcpRegistryDriver.ts | 4 +- .../src/provider/Drivers/AntigravityDriver.ts | 2 +- .../src/provider/Drivers/ClaudeDriver.ts | 4 +- .../src/provider/Drivers/CodexDriver.ts | 4 +- .../provider/Drivers/CodexManagedProvider.ts | 2 +- .../src/provider/Drivers/CursorDriver.ts | 4 +- .../server/src/provider/Drivers/GrokDriver.ts | 4 +- .../server/src/provider/Drivers/MuseDriver.ts | 6 +- .../src/provider/Drivers/OpenCodeDriver.ts | 4 +- ...viderOrchestrationAdapterInfrastructure.ts | 2 +- apps/server/src/provider/builtInDrivers.ts | 2 +- apps/web/package.json | 1 + apps/web/src/components/Icons.tsx | 15 --- .../components/chat/ProviderInstanceIcon.tsx | 28 ++++- .../components/chat/ProviderPackageIcon.tsx | 47 ++++++++ .../src/components/chat/V2LifecycleRow.tsx | 13 +-- .../components/settings/providerDriverMeta.ts | 8 +- docs/internals/adding-a-provider.md | 34 ++++-- docs/internals/providers.md | 2 +- package.json | 2 +- packages/contracts/src/settings.ts | 39 +------ packages/provider-core/package.json | 16 +++ packages/provider-core/src/client.ts | 17 +++ .../src/server/continuationRequests.ts | 2 +- .../provider-core/src/server/handoffBudget.ts | 0 .../src/server/managedProvider.test.ts | 105 ++++++------------ .../src/server/managedProvider.ts | 9 +- .../src/server/snapshotSettings.ts | 2 +- packages/provider-pi/package.json | 36 ++++++ packages/provider-pi/src/client.ts | 27 +++++ packages/provider-pi/src/server.ts | 8 ++ .../provider-pi/src/server/adapter.test.ts | 8 +- .../provider-pi/src/server/adapter.ts | 12 +- .../provider-pi/src/server/commands.test.ts | 2 +- .../provider-pi/src/server/commands.ts | 0 .../provider-pi/src/server/driver.test.ts | 24 ++-- .../provider-pi/src/server/driver.ts | 18 ++- .../src/server/mcpExtensionSource.test.ts | 2 +- .../src/server/mcpExtensionSource.ts | 0 .../src/server/mcpInjection.test.ts | 4 +- .../provider-pi/src/server/mcpInjection.ts | 2 +- .../provider-pi/src/server/rpc.ts | 0 .../provider-pi/src/server/status.test.ts | 2 +- .../provider-pi/src/server/status.ts | 13 +-- .../src/server/textGeneration.test.ts | 2 +- .../provider-pi/src/server/textGeneration.ts | 10 +- .../src/server/thinkingCapabilities.test.ts | 2 +- .../src/server/thinkingCapabilities.ts | 0 packages/provider-pi/src/settings.ts | 47 ++++++++ packages/provider-pi/tsconfig.json | 7 ++ pnpm-lock.yaml | 43 +++++++ scripts/release-smoke.ts | 1 + 86 files changed, 475 insertions(+), 280 deletions(-) create mode 100644 apps/mobile/src/lib/providerClients.ts create mode 100644 apps/web/src/components/chat/ProviderPackageIcon.tsx rename apps/server/src/orchestration-v2/ProviderContinuationRequests.ts => packages/provider-core/src/server/continuationRequests.ts (97%) rename apps/server/src/orchestration-v2/ContextHandoffBudget.ts => packages/provider-core/src/server/handoffBudget.ts (100%) rename apps/server/src/provider/makeManagedServerProvider.test.ts => packages/provider-core/src/server/managedProvider.test.ts (88%) rename apps/server/src/provider/makeManagedServerProvider.ts => packages/provider-core/src/server/managedProvider.ts (97%) rename apps/server/src/provider/providerUpdateSettings.ts => packages/provider-core/src/server/snapshotSettings.ts (94%) create mode 100644 packages/provider-pi/package.json create mode 100644 packages/provider-pi/src/client.ts create mode 100644 packages/provider-pi/src/server.ts rename apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts => packages/provider-pi/src/server/adapter.test.ts (99%) rename apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts => packages/provider-pi/src/server/adapter.ts (99%) rename apps/server/src/provider/PiCommands.test.ts => packages/provider-pi/src/server/commands.test.ts (99%) rename apps/server/src/provider/PiCommands.ts => packages/provider-pi/src/server/commands.ts (100%) rename apps/server/src/provider/Drivers/PiDriver.test.ts => packages/provider-pi/src/server/driver.test.ts (92%) rename apps/server/src/provider/Drivers/PiDriver.ts => packages/provider-pi/src/server/driver.ts (93%) rename apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.test.ts => packages/provider-pi/src/server/mcpExtensionSource.test.ts (99%) rename apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.ts => packages/provider-pi/src/server/mcpExtensionSource.ts (100%) rename apps/server/src/orchestration-v2/Adapters/piT3McpInjection.test.ts => packages/provider-pi/src/server/mcpInjection.test.ts (98%) rename apps/server/src/orchestration-v2/Adapters/piT3McpInjection.ts => packages/provider-pi/src/server/mcpInjection.ts (99%) rename apps/server/src/orchestration-v2/Adapters/PiRpc.ts => packages/provider-pi/src/server/rpc.ts (100%) rename apps/server/src/provider/PiProvider.test.ts => packages/provider-pi/src/server/status.test.ts (97%) rename apps/server/src/provider/PiProvider.ts => packages/provider-pi/src/server/status.ts (98%) rename apps/server/src/textGeneration/PiTextGeneration.test.ts => packages/provider-pi/src/server/textGeneration.test.ts (98%) rename apps/server/src/textGeneration/PiTextGeneration.ts => packages/provider-pi/src/server/textGeneration.ts (93%) rename apps/server/src/provider/piThinkingCapabilities.test.ts => packages/provider-pi/src/server/thinkingCapabilities.test.ts (95%) rename apps/server/src/provider/piThinkingCapabilities.ts => packages/provider-pi/src/server/thinkingCapabilities.ts (100%) create mode 100644 packages/provider-pi/src/settings.ts create mode 100644 packages/provider-pi/tsconfig.json diff --git a/apps/mobile/package.json b/apps/mobile/package.json index b8d8dea0d058bef0dedf523d450d2b4bc74a4129..35fec0c2769ac7372925b5ec71f63e0ca1873993 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -69,6 +69,8 @@ "@t3tools/mobile-markdown-text": "file:./modules/t3-markdown-text", "@t3tools/mobile-review-diff-native": "file:./modules/t3-review-diff", "@t3tools/mobile-terminal-native": "file:./modules/t3-terminal", + "@t3tools/provider-core": "workspace:*", + "@t3tools/provider-pi": "workspace:*", "@t3tools/shared": "workspace:*", "@tabler/icons-react-native": "^3.44.0", "clsx": "^2.1.1", diff --git a/apps/mobile/src/components/ProviderIcon.tsx b/apps/mobile/src/components/ProviderIcon.tsx index f833baacd7c37d5f9976d1f329497da020ca6886..1675b15461d06033532e81a00fd6bd95e593ee94 100644 --- a/apps/mobile/src/components/ProviderIcon.tsx +++ b/apps/mobile/src/components/ProviderIcon.tsx @@ -6,6 +6,7 @@ import { useState } from "react"; import { resolveOfficialAcpRegistryIconUrl } from "@t3tools/contracts"; import { useAppearancePreferences } from "../features/settings/appearance/AppearancePreferencesProvider"; import { AppText as Text } from "./AppText"; +import { getProviderClient } from "../lib/providerClients"; type ProviderIconProps = { readonly provider: string | null | undefined; @@ -131,16 +132,20 @@ export function ProviderIcon(props: ProviderIconProps) { ); } - if (props.provider === "pi") { - const foreground = isDarkMode ? "#F5F5F5" : "#0F0F0F"; + const packageIcon = getProviderClient(props.provider)?.icon; + if (packageIcon) { + const themeFill = (fill: { readonly light: string; readonly dark: string }) => + isDarkMode ? fill.dark : fill.light; return ( - - - + + {packageIcon.paths.map((path) => ( + + ))} ); } diff --git a/apps/mobile/src/lib/providerClients.ts b/apps/mobile/src/lib/providerClients.ts new file mode 100644 index 0000000000000000000000000000000000000000..c8c1c05c01580e8e9e06b5750a7781458d9ffdee --- /dev/null +++ b/apps/mobile/src/lib/providerClients.ts @@ -0,0 +1,11 @@ +import { isProviderDriverKind } from "@t3tools/contracts"; +import { makeProviderClientRegistry } from "@t3tools/provider-core/client"; +import { piClient } from "@t3tools/provider-pi/client"; + +/** The provider client definitions this mobile build ships. */ +const providerClients = makeProviderClientRegistry([piClient]); + +/** The client definition for a driver kind, or `undefined` for drivers drawn by hand. */ +export function getProviderClient(driver: string | null | undefined) { + return isProviderDriverKind(driver) ? providerClients.get(driver) : undefined; +} diff --git a/apps/server/package.json b/apps/server/package.json index 74bb7cac0e94efad2dc1ab3113a3b9d4cb988190..7672fbf534e3e8fb9765a8acac362e9da04cc52b 100644 --- a/apps/server/package.json +++ b/apps/server/package.json @@ -42,6 +42,7 @@ "@opencode/protocol": "2.0.23", "@opencode/schema": "2.0.23", "@t3tools/provider-core": "workspace:*", + "@t3tools/provider-pi": "workspace:*", "diff": "8.0.3", "effect": "catalog:", "jose": "catalog:", diff --git a/apps/server/scripts/record-grok-acp-replay-fixture.ts b/apps/server/scripts/record-grok-acp-replay-fixture.ts index 5623b45eda8c0781c221c7171420e6323eb2b382..a6b88d3024ff78f140d5d71ac3350a896e6fa10e 100644 --- a/apps/server/scripts/record-grok-acp-replay-fixture.ts +++ b/apps/server/scripts/record-grok-acp-replay-fixture.ts @@ -34,7 +34,7 @@ import { import { ACP_PROTOCOL } from "../src/orchestration-v2/Adapters/AcpAdapterV2.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import type { ProviderAdapterV2SessionRuntime } from "@t3tools/provider-core/server/ProviderAdapter"; -import * as ProviderContinuationRequests from "../src/orchestration-v2/ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderAdapterRegistry from "../src/orchestration-v2/ProviderAdapterRegistry.ts"; import { provideDeterministicTestRuntime } from "../src/orchestration-v2/testkit/DeterministicRuntime.ts"; import { ORCHESTRATOR_REPLAY_FIXTURES } from "../src/orchestration-v2/testkit/fixtures/index.ts"; diff --git a/apps/server/scripts/record-pi-rpc-replay-fixture.ts b/apps/server/scripts/record-pi-rpc-replay-fixture.ts index 8ea04f8ada6229c4d2f4886716d5fce6c866856a..560565666e90ecda17bf699a27eaa8848063b56d 100644 --- a/apps/server/scripts/record-pi-rpc-replay-fixture.ts +++ b/apps/server/scripts/record-pi-rpc-replay-fixture.ts @@ -29,7 +29,7 @@ import { PiOrchestratorReplayHarness, } from "../src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts"; import * as PiAdapterV2Testkit from "../src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts"; -import { PI_PROVIDER } from "../src/orchestration-v2/Adapters/PiAdapterV2.ts"; +import { PI_PROVIDER } from "@t3tools/provider-pi/server"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import { provideDeterministicTestRuntime } from "../src/orchestration-v2/testkit/DeterministicRuntime.ts"; import { ORCHESTRATOR_REPLAY_FIXTURES } from "../src/orchestration-v2/testkit/fixtures/index.ts"; diff --git a/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts b/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts index 496c6260d9b49dea4a70518209023065f364a4e1..f4aa8bafbe6666905f5e63355ad871edd73745fd 100644 --- a/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts +++ b/apps/server/src/mcp/OrchestratorMcpToolkit.integration.test.ts @@ -64,7 +64,7 @@ import { type ProviderAdapterV2TurnInput, } from "@t3tools/provider-core/server/ProviderAdapter"; import * as ProviderAdapterRegistry from "../orchestration-v2/ProviderAdapterRegistry.ts"; -import * as ProviderContinuationRequests from "../orchestration-v2/ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { checkpointWorkspace } from "@t3tools/provider-testing/replayWorkspace"; import * as ProviderReplayHarness from "../orchestration-v2/testkit/ProviderReplayHarness.ts"; import { diff --git a/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts index c6ad1fe57e719b9c48926fd72a855713b64e38ac..c908265271764f7ea0b7d32d7c95c23c5ad05723 100644 --- a/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts @@ -71,7 +71,7 @@ import { type ProviderAdapterV2Event, type ProviderAdapterV2TurnInput, } from "@t3tools/provider-core/server/ProviderAdapter"; -import type { ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; +import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; import { AcpProviderCapabilitiesV2, acpProviderItemNativeId, diff --git a/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts index 0c8332743b1522e5ddd5420ccc2477ea5ef9c0f2..2767e0e1b41d3a7f4617a517f832356d812d0e8b 100644 --- a/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.ts @@ -100,7 +100,7 @@ import { } from "@t3tools/provider-core/server/orchestrationInstructions"; import { buildRuntimeInstructions } from "../../provider/RuntimeInstructions.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import { type ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; +import { type ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; import { type BackgroundWork, type BackgroundWorkReport, diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts index 5273c37d7d68bfb97010c3ace17562c63a6a1362..ebabc11d69ee93737b774c5f55292ef5974e1b11 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.test.ts @@ -67,7 +67,7 @@ import { type ProviderAdapterV2Event, type ProviderAdapterV2TurnInput, } from "@t3tools/provider-core/server/ProviderAdapter"; -import type { ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; +import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; import * as ClaudeAdapterV2 from "./ClaudeAdapterV2.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; diff --git a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts index 17876e430879e23b22e4806d66b4c1fe9ea82d53..0b33327b18509bed426ee269b7660a1a74c8fe62 100644 --- a/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/ClaudeAdapterV2.ts @@ -132,7 +132,7 @@ import { type ProviderAdapterDriverCreateInput, } from "@t3tools/provider-core/server/adapterDriver"; import { type BackgroundWorkReport, backgroundWorkNotification } from "../Notification.ts"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { makeSubagentChildThread, makeSubagentConversationArtifacts, diff --git a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts index cadf666611434a1082035df473f076e04ef10e80..4188c3248a5fdcefd280b5ace74a060939b2f478 100644 --- a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.test.ts @@ -1,6 +1,6 @@ import * as NodeOS from "node:os"; -import { historyResponseItems } from "../ContextHandoffBudget.ts"; +import { historyResponseItems } from "@t3tools/provider-core/server/handoffBudget"; import type { ProviderAdapterV2HistoricalContext } from "@t3tools/provider-core/server/ProviderAdapter"; import { makeProviderTextDeltaCoalescer, @@ -70,7 +70,7 @@ import { type ProviderAdapterV2Event, type ProviderAdapterV2TurnInput, } from "@t3tools/provider-core/server/ProviderAdapter"; -import type { ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; +import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; import * as CodexAdapterV2 from "./CodexAdapterV2.ts"; import { makeReplayServerConfig, withCodexReplayChildMetadata } from "./CodexAdapterV2.testkit.ts"; import * as CodexAdapterV2Testkit from "./CodexAdapterV2.testkit.ts"; diff --git a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts index f87525e9c8f717eb232947da67035ca763c89723..660e690b5887bb0be47b5c122f03995afa300319 100644 --- a/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/CodexAdapterV2.ts @@ -1,5 +1,5 @@ import { revertCodexThread } from "../../provider/CodexThreadRevert.ts"; -import { historyResponseItems } from "../ContextHandoffBudget.ts"; +import { historyResponseItems } from "@t3tools/provider-core/server/handoffBudget"; import { makeProviderTextDeltaCoalescer } from "./ProviderTextDeltaCoalescer.ts"; import { mcpToolPresentation, @@ -125,7 +125,7 @@ import { IdAllocatorV2, type IdAllocatorV2Shape } from "@t3tools/provider-core/s import { type ProviderContinuationRequest, ProviderContinuationRequests, -} from "../ProviderContinuationRequests.ts"; +} from "@t3tools/provider-core/server/continuationRequests"; import { backgroundWorkNotification } from "../Notification.ts"; import { makeProviderFailure, diff --git a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.testkit.ts b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.testkit.ts index 30438a421408612394e249132bab6e3000f73ad4..b770efd77136a53db520f47e731f183ba1e8e46c 100644 --- a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.testkit.ts +++ b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.testkit.ts @@ -17,7 +17,7 @@ import { } from "../../provider/acp/GrokAcpSupport.ts"; import { makeXAiPromptCompletionRuntime } from "../../provider/acp/XAiAcpExtension.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; import type { ProviderReplayGate } from "@t3tools/provider-testing/replayGate"; import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; diff --git a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.ts index 5f28bd1b419f43d22f40cb611db1a6141f68475b..de3c77a696ace12b923ed55e82d481c48c9ae670 100644 --- a/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/GrokAdapterV2.ts @@ -58,7 +58,7 @@ import { acpPermissionDisposition } from "../../provider/acp/AcpClientPolicy.ts" import * as AcpSessionRuntime from "../../provider/acp/AcpSessionRuntime.ts"; import * as ProviderEventLoggers from "../../provider/ProviderEventLoggers.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; import { ProviderAdapterDriverCreateError, diff --git a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.test.ts index a896f876d1ad725abb88e16e56911e87f30d7a73..45a5e00d9bb17e89a8156073c170abb05cfd6523 100644 --- a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.test.ts @@ -41,7 +41,7 @@ import { type ProviderAdapterV2Event, type ProviderAdapterV2TurnInput, } from "@t3tools/provider-core/server/ProviderAdapter"; -import type { ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; +import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; import { makeMuseAdapterV2, type MuseAdapterV2Options } from "./MuseAdapterV2.ts"; const testLayer = Layer.mergeAll( diff --git a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.testkit.ts b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.testkit.ts index 182b67c20aad44c5d940db529ed9b0539a2bb9dd..cce14853f6fd026601a719d98d75d8fa58a096c8 100644 --- a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.testkit.ts +++ b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.testkit.ts @@ -37,7 +37,7 @@ import { } from "../../provider/museSdk.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { makeReplayServerConfig, type OrchestratorV2ProviderReplayHarness, diff --git a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.ts index 7384afad822af160098e4be665686b454c31c6bd..39d332e4e1b0c461ce131a1e5008b90531f3b228 100644 --- a/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/MuseAdapterV2.ts @@ -96,7 +96,7 @@ import { type ProviderAdapterV2TurnMessage, } from "@t3tools/provider-core/server/ProviderAdapter"; import { backgroundWorkNotification, type BackgroundWorkReport } from "../Notification.ts"; -import type * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import type * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; import { turnScopedSelectionTransition } from "@t3tools/provider-core/server/selectionTransition"; import { museItemStatus, museToolPresentation } from "./MuseItemPresentation.ts"; diff --git a/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts b/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts index 1be5940027911252be62b13fca0c56d1b09382c2..96b28d5e082e8ece871184103f64cb3289ecc53c 100644 --- a/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts +++ b/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.test.ts @@ -44,8 +44,8 @@ import type { } from "@t3tools/provider-core/server/ProviderAdapter"; import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import type { ProviderContinuationRequest } from "../ProviderContinuationRequests.ts"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import type { ProviderContinuationRequest } from "@t3tools/provider-core/server/continuationRequests"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { OPENCODE_PROVIDER } from "./OpenCodeAdapterV2.ts"; import { OPENCODE_2_STILL_STOPPING, t3McpServerName } from "./OpenCode2AdapterV2.ts"; import { openCode2ReplayRuntime } from "./OpenCode2AdapterV2.testkit.ts"; diff --git a/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.ts b/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.ts index ef05da600de1adb8303d921d87dcf3f4428d90e0..5806fc5fb68d2951d9d7c8e749035feeb2c43d9b 100644 --- a/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.ts +++ b/apps/server/src/orchestration-v2/Adapters/OpenCode2AdapterV2.ts @@ -88,7 +88,7 @@ import { causeErrorTag } from "@t3tools/shared/observability"; import { providerMessageTextWithAttachmentPaths } from "../AttachmentPrompt.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import { backgroundWorkNotification, type BackgroundWorkReport } from "../Notification.ts"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; import { makeSubagentChildThread, diff --git a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts b/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts index a66a6a2b1a5d35397b85244bf7bf0b28e5852d76..f0538385e8106d491db15b7646c923156326b711 100644 --- a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts +++ b/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.testkit.ts @@ -35,7 +35,7 @@ import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import { ProviderAdapterDriverCreateError } from "@t3tools/provider-core/server/adapterDriver"; import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; import type { OrchestratorV2ProviderReplayHarness } from "../testkit/ProviderReplayHarness.ts"; -import { PI_PROVIDER, PiAdapterV2Driver } from "./PiAdapterV2.ts"; +import { PI_PROVIDER, PiAdapterV2Driver } from "@t3tools/provider-pi/server"; export const PI_RPC_REPLAY_PROTOCOL = "pi.rpc-jsonl"; export const PI_REPLAY_ANY = ""; diff --git a/apps/server/src/orchestration-v2/ContextHandoffBudget.test.ts b/apps/server/src/orchestration-v2/ContextHandoffBudget.test.ts index 6f385a128b39c7eca0868836bb1cbebe3cf6ee0e..0335d921da3e91a8a1e55337a9db939ac8edd5f9 100644 --- a/apps/server/src/orchestration-v2/ContextHandoffBudget.test.ts +++ b/apps/server/src/orchestration-v2/ContextHandoffBudget.test.ts @@ -23,7 +23,7 @@ import { historyResponseItems, selectHistory, historicalMessage, -} from "./ContextHandoffBudget.ts"; +} from "@t3tools/provider-core/server/handoffBudget"; import { projectContextHandoffForWire } from "./WireProjection.ts"; import { deliverContextHandoffs } from "./ContextHandoffDelivery.ts"; diff --git a/apps/server/src/orchestration-v2/ContextHandoffDelivery.ts b/apps/server/src/orchestration-v2/ContextHandoffDelivery.ts index f3c4a846b7e7e9f77bb99974d4e51eb4aa24f5b8..534217a58a202a04f45989147657c224b5cff1d1 100644 --- a/apps/server/src/orchestration-v2/ContextHandoffDelivery.ts +++ b/apps/server/src/orchestration-v2/ContextHandoffDelivery.ts @@ -6,7 +6,11 @@ import type { ProviderAdapterV2HistoricalContext } from "@t3tools/provider-core/ import { ContextHandoffBudgetError } from "@t3tools/provider-core/server/failure"; import * as Effect from "effect/Effect"; import * as Schema from "effect/Schema"; -import { historyCost, renderHistory, selectHistory } from "./ContextHandoffBudget.ts"; +import { + historyCost, + renderHistory, + selectHistory, +} from "@t3tools/provider-core/server/handoffBudget"; /** * Persist before/after injection: an ambiguous pending delivery requires a fresh native thread. diff --git a/apps/server/src/orchestration-v2/ContextHandoffService.ts b/apps/server/src/orchestration-v2/ContextHandoffService.ts index 0d66db6deb3f0f46a679f3bb1057e6e7afb837e5..137f617710c5e41334755965d01ee4dbf2550339 100644 --- a/apps/server/src/orchestration-v2/ContextHandoffService.ts +++ b/apps/server/src/orchestration-v2/ContextHandoffService.ts @@ -20,7 +20,7 @@ import { historicalMessage, renderHistory, selectHistory, -} from "./ContextHandoffBudget.ts"; +} from "@t3tools/provider-core/server/handoffBudget"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; export class ContextHandoffPrepareError extends Schema.TaggedError()( diff --git a/apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.live.test.ts b/apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.live.test.ts index 3e486a14f0de8620116b8d11a5b9ad4bb85ec5c6..9f046abba25f3dde4656c5a962e084e65b356a3c 100644 --- a/apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.live.test.ts +++ b/apps/server/src/orchestration-v2/OpenCode2OrchestratorV2.live.test.ts @@ -67,7 +67,7 @@ import * as ProviderInstanceRegistry from "../provider/ProviderInstanceRegistry. import * as ProviderTurnStartServiceTestkit from "./ProviderTurnStartService.testkit.ts"; import * as RuntimeLayer from "./runtimeLayer.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "./ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderContinuationService from "./ProviderContinuationService.ts"; import * as ThreadManagementService from "./ThreadManagementService.ts"; import * as McpSessionRegistry from "../mcp/McpSessionRegistry.ts"; diff --git a/apps/server/src/orchestration-v2/Orchestrator.ts b/apps/server/src/orchestration-v2/Orchestrator.ts index 226108f6a50384e3a809b5230b8fffaebcb70420..a2e45ed21c5115be7158789917c90cacb68957ab 100644 --- a/apps/server/src/orchestration-v2/Orchestrator.ts +++ b/apps/server/src/orchestration-v2/Orchestrator.ts @@ -109,7 +109,7 @@ import { } from "./ProjectionStore.ts"; import type { ProviderAdapterV2Shape } from "@t3tools/provider-core/server/ProviderAdapter"; import { ProviderAdapterRegistryV2 } from "./ProviderAdapterRegistry.ts"; -import { ProviderContinuationRequests } from "./ProviderContinuationRequests.ts"; +import { ProviderContinuationRequests } from "@t3tools/provider-core/server/continuationRequests"; import { makeProviderFailure } from "@t3tools/provider-core/server/failure"; import * as RunExecutionService from "./RunExecutionService.ts"; import { ProviderSessionManagerV2 } from "./ProviderSessionManager.ts"; diff --git a/apps/server/src/orchestration-v2/ProviderContinuationService.test.ts b/apps/server/src/orchestration-v2/ProviderContinuationService.test.ts index 2ed8b465b2c3fc2d30361007a11cfaba59e94cb1..6e99d80a30e44f23d95c5a49f39e16779a77f819 100644 --- a/apps/server/src/orchestration-v2/ProviderContinuationService.test.ts +++ b/apps/server/src/orchestration-v2/ProviderContinuationService.test.ts @@ -19,7 +19,7 @@ import * as Semaphore from "effect/Semaphore"; import * as TestClock from "effect/testing/TestClock"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "./ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderContinuationService from "./ProviderContinuationService.ts"; import * as ThreadManagementService from "./ThreadManagementService.ts"; diff --git a/apps/server/src/orchestration-v2/ProviderContinuationService.ts b/apps/server/src/orchestration-v2/ProviderContinuationService.ts index ac254a0ae27c6c4b2a4fa8c75363310450cd636a..928a5c9095240d20a27c343ff693b887e21fcd39 100644 --- a/apps/server/src/orchestration-v2/ProviderContinuationService.ts +++ b/apps/server/src/orchestration-v2/ProviderContinuationService.ts @@ -4,7 +4,7 @@ import * as Layer from "effect/Layer"; import * as Ref from "effect/Ref"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "./ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ThreadManagementService from "./ThreadManagementService.ts"; import { isUndeliveredMailboxSteer } from "./NotificationMailbox.ts"; diff --git a/apps/server/src/orchestration-v2/ProviderTurnStartService.ts b/apps/server/src/orchestration-v2/ProviderTurnStartService.ts index 9bf834c0efa4e21ec9e2a84375a4763af6c5359f..a928680b240245ed6ab2c8adaf488d1a52108aa5 100644 --- a/apps/server/src/orchestration-v2/ProviderTurnStartService.ts +++ b/apps/server/src/orchestration-v2/ProviderTurnStartService.ts @@ -35,7 +35,7 @@ import { contextUsageForHandoff, historicalMessage, latestNativeContextUsage, -} from "./ContextHandoffBudget.ts"; +} from "@t3tools/provider-core/server/handoffBudget"; import { deliverContextHandoffs } from "./ContextHandoffDelivery.ts"; import { ProviderAdapterTurnStartError, diff --git a/apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts b/apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts index c9d2b397471375862550ee087c69e2be5029765e..8a6490ef798fc4d4c32028bf854611a56250c290 100644 --- a/apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts +++ b/apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts @@ -18,7 +18,7 @@ import { OpenCodeAdapterV2Driver, type OpenCodeAdapterV2DriverEnv, } from "./Adapters/OpenCodeAdapterV2.ts"; -import { PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "./Adapters/PiAdapterV2.ts"; +import { PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "@t3tools/provider-pi/server"; import type { AnyProviderAdapterDriver } from "@t3tools/provider-core/server/adapterDriver"; export type BuiltInProviderAdapterDriversV2Env = diff --git a/apps/server/src/orchestration-v2/runtimeLayer.ts b/apps/server/src/orchestration-v2/runtimeLayer.ts index d12491cc0eb091f862e6e7bc17cff4116c211343..5d736f1564bebfc166994f17437200b0b86db8db 100644 --- a/apps/server/src/orchestration-v2/runtimeLayer.ts +++ b/apps/server/src/orchestration-v2/runtimeLayer.ts @@ -30,7 +30,7 @@ import * as ProjectionStore from "./ProjectionStore.ts"; import * as ProjectionMaintenance from "./ProjectionMaintenance.ts"; import * as ProjectStore from "./ProjectStore.ts"; import * as ProviderAdapterRegistry from "./ProviderAdapterRegistry.ts"; -import * as ProviderContinuationRequests from "./ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderContinuationService from "./ProviderContinuationService.ts"; import * as ThreadTitleRegenerationService from "./ThreadTitleRegenerationService.ts"; import * as ProviderEventIngestor from "./ProviderEventIngestor.ts"; diff --git a/apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts b/apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts index 1307b2a77df6489fae9b0408a7690421cb8f0ff2..d24ae5b624d90feb53838732b1a2bec19b0336e8 100644 --- a/apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts +++ b/apps/server/src/orchestration-v2/testkit/ProviderReplayHarness.ts @@ -35,7 +35,7 @@ import * as ProjectionStore from "../ProjectionStore.ts"; import * as ProjectStore from "../ProjectStore.ts"; import * as ProviderAdapterRegistry from "../ProviderAdapterRegistry.ts"; import * as ProviderAuthService from "../../provider/ProviderAuthService.ts"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as ProviderContinuationService from "../ProviderContinuationService.ts"; import * as ProviderEventIngestor from "../ProviderEventIngestor.ts"; import * as ProviderRuntimeRecoveryService from "../ProviderRuntimeRecoveryService.ts"; diff --git a/apps/server/src/orchestration-v2/testkit/ProviderSwitch.integration.test.ts b/apps/server/src/orchestration-v2/testkit/ProviderSwitch.integration.test.ts index 732e04408c276f47ded4e61bb6856ad3ddd93ae9..a0de3392631c73a81136167a65d2a5f5045880c7 100644 --- a/apps/server/src/orchestration-v2/testkit/ProviderSwitch.integration.test.ts +++ b/apps/server/src/orchestration-v2/testkit/ProviderSwitch.integration.test.ts @@ -1,5 +1,5 @@ import { vi } from "vite-plus/test"; -import { historyResponseItems } from "../ContextHandoffBudget.ts"; +import { historyResponseItems } from "@t3tools/provider-core/server/handoffBudget"; import { assert, describe, it } from "@effect/vitest"; import { CommandId, diff --git a/apps/server/src/provider/AntigravityProvider.ts b/apps/server/src/provider/AntigravityProvider.ts index ca6c0391491af25894755f637337234c3f44b4ec..143b6522bd469d2f5b4700f5479e8f1d6a505c4f 100644 --- a/apps/server/src/provider/AntigravityProvider.ts +++ b/apps/server/src/provider/AntigravityProvider.ts @@ -19,7 +19,7 @@ import type * as EffectAcpErrors from "effect-acp/errors"; import type * as EffectAcpSchema from "effect-acp/compat"; import type { AcpSessionRuntimeStartResult } from "./acp/AcpSessionRuntime.ts"; -import { makeManagedServerProvider } from "./makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { makeManualOnlyProviderMaintenanceCapabilities, type ProviderMaintenanceCapabilities, diff --git a/apps/server/src/provider/Drivers/AcpRegistryDriver.ts b/apps/server/src/provider/Drivers/AcpRegistryDriver.ts index cc08d2b4a10e729979e1ca8e5e2179a27894e96e..bdd5c0449a2c6961719ebd9b872fbe5a5641a915 100644 --- a/apps/server/src/provider/Drivers/AcpRegistryDriver.ts +++ b/apps/server/src/provider/Drivers/AcpRegistryDriver.ts @@ -29,7 +29,7 @@ import { } from "../../orchestration-v2/Adapters/AcpRegistryAdapterV2.ts"; import type { TextGeneration } from "../../textGeneration/TextGeneration.ts"; import { ProviderDriverError } from "../Errors.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; import { defaultProviderContinuationIdentity, @@ -42,7 +42,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; import { type AcpRegistryAvailableCommands, type AcpRegistryConfigurationProbe, diff --git a/apps/server/src/provider/Drivers/AntigravityDriver.ts b/apps/server/src/provider/Drivers/AntigravityDriver.ts index 817dbff73570d394720e0424d8032c5a48fc0ffc..238834f63a11f8e6428782f9e73c23a4b8f79c60 100644 --- a/apps/server/src/provider/Drivers/AntigravityDriver.ts +++ b/apps/server/src/provider/Drivers/AntigravityDriver.ts @@ -47,7 +47,7 @@ import { removeAntigravitySessionFiles, } from "../acp/AntigravitySessionFiles.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "../../orchestration-v2/ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { makeAntigravityAdapterV2 } from "../../orchestration-v2/Adapters/AntigravityAdapterV2.ts"; import { makeAcpNativeLoggerFactory } from "../acp/AcpNativeLogging.ts"; import { ProviderDriverError } from "../Errors.ts"; diff --git a/apps/server/src/provider/Drivers/ClaudeDriver.ts b/apps/server/src/provider/Drivers/ClaudeDriver.ts index 55dfe036b98ec6aa89a6cf0d792cc9c11b4f5d74..ab9e6d2e8f2f353322f40391f383029c9ef938a3 100644 --- a/apps/server/src/provider/Drivers/ClaudeDriver.ts +++ b/apps/server/src/provider/Drivers/ClaudeDriver.ts @@ -42,7 +42,7 @@ import { probeClaudeCapabilities, probeClaudeWorkspaceSnapshot, } from "../ClaudeProvider.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import * as ModelManifest from "../ModelManifest.ts"; import { resolveClaudeModelCatalog } from "../ClaudeModelCatalog.ts"; import { @@ -63,7 +63,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; import { makeClaudeCapabilitiesCacheKey, makeClaudeContinuationGroupKey, diff --git a/apps/server/src/provider/Drivers/CodexDriver.ts b/apps/server/src/provider/Drivers/CodexDriver.ts index 885a89b65c66eedd7caf2c3dd5e0d1a328f14dbd..0d6da5a5dea66ec2d58b9dd7f827ff3ced14a4cd 100644 --- a/apps/server/src/provider/Drivers/CodexDriver.ts +++ b/apps/server/src/provider/Drivers/CodexDriver.ts @@ -48,7 +48,7 @@ import { withCodexAppServerClient, } from "../CodexProvider.ts"; import { resolveCodexLaunchArgs } from "../codexLaunchArgs.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import * as ModelManifest from "../ModelManifest.ts"; import type { ProviderDriver, ProviderInstance } from "@t3tools/provider-core/server/driver"; import { withInstanceIdentity } from "./instanceIdentity.ts"; @@ -64,7 +64,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; import { codexContinuationIdentity, materializeCodexShadowHome, diff --git a/apps/server/src/provider/Drivers/CodexManagedProvider.ts b/apps/server/src/provider/Drivers/CodexManagedProvider.ts index e702548000dc4303d6091cf1158b20d51a455278..b7c12ff3391d8e0fed0a8c67a1c8f1ca0a77c89c 100644 --- a/apps/server/src/provider/Drivers/CodexManagedProvider.ts +++ b/apps/server/src/provider/Drivers/CodexManagedProvider.ts @@ -14,7 +14,7 @@ import { makePendingCodexProvider, probeCodexSkillsForCwd, } from "../CodexProvider.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; import { type ProviderDriverCreateInput, diff --git a/apps/server/src/provider/Drivers/CursorDriver.ts b/apps/server/src/provider/Drivers/CursorDriver.ts index e8bd2eee22e61ed494d1006145a02361abde87b5..21bc7a0b7af83be866522d3b882f59811aac819d 100644 --- a/apps/server/src/provider/Drivers/CursorDriver.ts +++ b/apps/server/src/provider/Drivers/CursorDriver.ts @@ -29,7 +29,7 @@ import { checkCursorProviderStatus, } from "../CursorProvider.ts"; import * as CursorSdkCatalog from "../CursorSdkCatalog.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { defaultProviderContinuationIdentity, type ProviderDriver, @@ -42,7 +42,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; import { probeCursorSkills } from "./CursorSkills.ts"; import { makeCursorAuth } from "../CursorAuth.ts"; import * as CursorCredentialStore from "../CursorCredentialStore.ts"; diff --git a/apps/server/src/provider/Drivers/GrokDriver.ts b/apps/server/src/provider/Drivers/GrokDriver.ts index c253401b53e65fe5ca462476cc944ba1d897f4c1..5962c72482645686da4efea83f3daa8930383cdd 100644 --- a/apps/server/src/provider/Drivers/GrokDriver.ts +++ b/apps/server/src/provider/Drivers/GrokDriver.ts @@ -22,7 +22,7 @@ import { enrichGrokSnapshot, } from "../GrokProvider.ts"; import { readGrokAccount } from "../grokUsageLimits.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { defaultProviderContinuationIdentity, type ProviderDriver, @@ -42,7 +42,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; const decodeGrokSettings = Schema.decodeSync(GrokSettings); const DRIVER_KIND = ProviderDriverKind.make("grok"); diff --git a/apps/server/src/provider/Drivers/MuseDriver.ts b/apps/server/src/provider/Drivers/MuseDriver.ts index 63e164d9db96095f77a209ebc01dc026b376c911..e22b22ab0dee2b618ebace5aaf038dbfd2ce6cf7 100644 --- a/apps/server/src/provider/Drivers/MuseDriver.ts +++ b/apps/server/src/provider/Drivers/MuseDriver.ts @@ -14,10 +14,10 @@ import { makeMuseTextGeneration } from "../../textGeneration/MuseTextGeneration. import { ProviderDriverError } from "../Errors.ts"; import { makeMuseAdapterV2 } from "../../orchestration-v2/Adapters/MuseAdapterV2.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "../../orchestration-v2/ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { checkMuseProviderStatus, makePendingMuseProvider } from "../MuseProvider.ts"; import * as ProviderEventLoggers from "../ProviderEventLoggers.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { enrichMuseSnapshot, latestMuseVersion, museMaintenance } from "../museMaintenance.ts"; import { makeMuseEnvironment } from "../museSdk.ts"; import { @@ -34,7 +34,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; import { withInstanceIdentity } from "./instanceIdentity.ts"; const DRIVER_KIND = ProviderDriverKind.make("muse"); diff --git a/apps/server/src/provider/Drivers/OpenCodeDriver.ts b/apps/server/src/provider/Drivers/OpenCodeDriver.ts index db4a9caa9e61326516244d8eedd7151382d3a5b8..76a9dcdc7b789f1d5115ed850f321c268fef0b62 100644 --- a/apps/server/src/provider/Drivers/OpenCodeDriver.ts +++ b/apps/server/src/provider/Drivers/OpenCodeDriver.ts @@ -44,7 +44,7 @@ import { openCodeSkillsToServerProviderSkills, openCodeCommandsToServerProviderSlashCommands, } from "../OpenCodeProvider.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import * as OpenCodeRuntime from "../opencodeRuntime.ts"; import { makeOpenCodeRuntimeProbe, @@ -73,7 +73,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; const decodeOpenCodeSettings = Schema.decodeSync(OpenCodeSettings); const DRIVER_KIND = ProviderDriverKind.make("opencode"); diff --git a/apps/server/src/provider/ProviderOrchestrationAdapterInfrastructure.ts b/apps/server/src/provider/ProviderOrchestrationAdapterInfrastructure.ts index 130a63262fc4d29a876173669f2308f581e748a6..6640288c7ff4898dbe5d354c9b1a903efd219390 100644 --- a/apps/server/src/provider/ProviderOrchestrationAdapterInfrastructure.ts +++ b/apps/server/src/provider/ProviderOrchestrationAdapterInfrastructure.ts @@ -4,7 +4,7 @@ import * as ClaudeAdapterV2 from "../orchestration-v2/Adapters/ClaudeAdapterV2.t import * as CodexAdapterV2 from "../orchestration-v2/Adapters/CodexAdapterV2.ts"; import * as CursorAgentSdk from "../orchestration-v2/Adapters/CursorAgentSdk.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ProviderContinuationRequests from "../orchestration-v2/ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; export type ProviderOrchestrationAdapterInfrastructure = | ClaudeAdapterV2.ClaudeAgentSdkQueryRunner diff --git a/apps/server/src/provider/builtInDrivers.ts b/apps/server/src/provider/builtInDrivers.ts index ffaf812e4c840cd039fa403fd380aaede832d4e9..08a403b70e048fba30fcaf00fbbe3940522ce725 100644 --- a/apps/server/src/provider/builtInDrivers.ts +++ b/apps/server/src/provider/builtInDrivers.ts @@ -28,7 +28,7 @@ import { CursorDriver, type CursorDriverEnv } from "./Drivers/CursorDriver.ts"; import { GrokDriver, type GrokDriverEnv } from "./Drivers/GrokDriver.ts"; import { OpenCodeDriver, type OpenCodeDriverEnv } from "./Drivers/OpenCodeDriver.ts"; import { MuseDriver, type MuseDriverEnv } from "./Drivers/MuseDriver.ts"; -import { PiDriver, type PiDriverEnv } from "./Drivers/PiDriver.ts"; +import { PiDriver, type PiDriverEnv } from "@t3tools/provider-pi/server"; import type { AnyProviderDriver } from "@t3tools/provider-core/server/driver"; /** diff --git a/apps/web/package.json b/apps/web/package.json index 53547e6cfc2219e18fa7c0da95561aab5b75afe9..ab2ae7b35ea32e757b08df5adf9fd1506b0b12cd 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -29,6 +29,7 @@ "@t3tools/client-runtime": "workspace:*", "@t3tools/contracts": "workspace:*", "@t3tools/provider-core": "workspace:*", + "@t3tools/provider-pi": "workspace:*", "@t3tools/shared": "workspace:*", "@tanstack/react-pacer": "^0.19.4", "@tanstack/react-router": "^1.160.2", diff --git a/apps/web/src/components/Icons.tsx b/apps/web/src/components/Icons.tsx index cc6e2d10af79a4f508de8027f72b1a640bea3423..66e170dacf61bf3a93f88f2336ed7fdc03f01882 100644 --- a/apps/web/src/components/Icons.tsx +++ b/apps/web/src/components/Icons.tsx @@ -718,21 +718,6 @@ export const ACPRegistryIcon: Icon = ({ className, ...props }) => ( ); -export const PiAgentIcon: Icon = ({ className, ...props }) => ( - - - - -); - // Official two-color mark from https://forgejo.org/favicon.svg. export const ForgejoIcon: Icon = (props) => ( {label} diff --git a/apps/web/src/components/settings/providerDriverMeta.ts b/apps/web/src/components/settings/providerDriverMeta.ts index 60d2d346d13bb4c3519fbc6a8dc6948500984df5..59b42d0f6751bc3c17286d48d83b0024d0e1c42c 100644 --- a/apps/web/src/components/settings/providerDriverMeta.ts +++ b/apps/web/src/components/settings/providerDriverMeta.ts @@ -6,11 +6,11 @@ import { CursorSettings, GrokSettings, OpenCodeSettings, - PiSettings, MuseSettings, ProviderDriverKind, } from "@t3tools/contracts"; import { makeProviderClientRegistry } from "@t3tools/provider-core/client"; +import { piClient } from "@t3tools/provider-pi/client"; /** The provider client definitions this web build ships, in presentation order. */ export const providerClients = makeProviderClientRegistry([ @@ -59,11 +59,7 @@ export const providerClients = makeProviderClientRegistry([ settingsSchema: MuseSettings, badgeLabel: "Beta", }, - { - driverKind: ProviderDriverKind.make("pi"), - label: "Pi", - settingsSchema: PiSettings, - }, + piClient, { driverKind: ProviderDriverKind.make("acpRegistry"), label: "ACP Registry", diff --git a/docs/internals/adding-a-provider.md b/docs/internals/adding-a-provider.md index e0100be873b3cb23d4af0ddf3a4eda3c3c7957de..4227182185ebc46e9b496e858fb59ad87e9b3196 100644 --- a/docs/internals/adding-a-provider.md +++ b/docs/internals/adding-a-provider.md @@ -27,7 +27,7 @@ capabilities, never the driver kind. at runtime is a bug. - **Permission modes.** Offer only modes the provider enforces natively, through `supportedRuntimeModes` in the provider presentation ([Grok](../../apps/server/src/provider/GrokProvider.ts) - and [Pi](../../apps/server/src/provider/PiProvider.ts) are examples). Do not imitate a missing + and [Pi](../../packages/provider-pi/src/server/status.ts) are examples). Do not imitate a missing mode by answering approvals in T3: T3's check is weaker than the agent's own enforcement. The server runs an unoffered stored mode as Supervised ([`RuntimePolicy.ts`](../../apps/server/src/orchestration-v2/RuntimePolicy.ts)). @@ -86,7 +86,7 @@ produce catches them. sending. - **Work the provider starts on its own.** Background commands, subagents, workflows, and goals can finish or start a turn after T3's turn settled. Offer a continuation through - [`ProviderContinuationRequests`](../../apps/server/src/orchestration-v2/ProviderContinuationRequests.ts) + [`ProviderContinuationRequests`](../../packages/provider-core/src/server/continuationRequests.ts) so the parent wakes, and report `hasPendingBackgroundWork` so the session is not released as idle. Dropping it, or killing the session, loses the result. - **Subagents outlive the run that launched them.** A child can report after its parent's turn @@ -103,16 +103,26 @@ produce catches them. ## Where a driver plugs in -- **Contracts:** settings schema, default model, and display name in - [`packages/contracts`](../../packages/contracts/src). Instances store that config in - `providerInstances`. New providers are off by default. -- **Server:** the driver in [`provider/Drivers`](../../apps/server/src/provider/Drivers) and its entry - in [`builtInDrivers.ts`](../../apps/server/src/provider/builtInDrivers.ts). Also its position in - the [status order](../../apps/server/src/provider/providerStatusCache.ts), a compatibility policy - in [`model-manifest.json`](../../apps/server/src/provider/model-manifest.json) (bump `updatedAt`; - see [model manifest](./model-manifest.md)), and text generation for titles and commit messages. -- **Clients:** web settings metadata and badge, provider icons on web and mobile, and settings - search terms. +A provider lives in its own `packages/provider-` package, with +[Pi](../../packages/provider-pi) as the reference. Drivers not moved yet still live in +[`provider/Drivers`](../../apps/server/src/provider/Drivers). + +- **Package exports.** `./settings` holds the instance settings schema, built with + `makeProviderSettingsSchema` from contracts. `./client` exports a `ProviderClientDefinition` + (label, settings schema, plain-data icon, badge) and must stay browser- and React Native-safe. + `./server` exports the `ProviderDriver` and its adapter driver. Settings live in + `providerInstances`; new providers are off by default. +- **Package boundaries.** Server code imports only `@t3tools/provider-core/server/*`, contracts, + and shared. It reaches the server through `ProviderHost` (paths, settings, background demand, + attachments), never through `apps/server`. Tests use `@t3tools/provider-testing`. +- **Server registration:** the driver's entry in + [`builtInDrivers.ts`](../../apps/server/src/provider/builtInDrivers.ts) and the adapter driver's in + [`builtInProviderAdapterDrivers.ts`](../../apps/server/src/orchestration-v2/builtInProviderAdapterDrivers.ts). + Also its position in the [status order](../../apps/server/src/provider/providerStatusCache.ts), a + compatibility policy in [`model-manifest.json`](../../apps/server/src/provider/model-manifest.json) + (bump `updatedAt`; see [model manifest](./model-manifest.md)), and its default model in contracts. +- **Client registration:** the client definition in the web and mobile provider registries, and + settings search terms. Clients draw the package icon; do not add a per-driver icon branch. - **Docs:** a `docs/user/providers-.md` guide in the product's voice, a row in the [install](../user/install.md#providers) table, and any provider difference that changes the [permission modes](../user/permission-modes.md) page. diff --git a/docs/internals/providers.md b/docs/internals/providers.md index 3da603d9ce015e74a8814100c0aa77e7977674b3..b8542cbbef38b07782417e772c361811bc386981 100644 --- a/docs/internals/providers.md +++ b/docs/internals/providers.md @@ -34,7 +34,7 @@ trust discovery. T3 injects only its namespaced MCP bridge, so a Pi session beha the Pi TUI. Pi session files back native resume, rollback, and same-instance thread forks. Forks use Pi's CLI in the destination directory because RPC session switching retains the source session's cwd. Provider switches still use portable handoff summaries. -See the [adapter](../../apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts). +See the [adapter](../../packages/provider-pi/src/server/adapter.ts). Antigravity separates account profiles per instance while sharing installed executables across the environment. It forces file-based credential storage because the native macOS keychain entry would diff --git a/package.json b/package.json index 078da2b294523b092d5d8d488d6fa3d4375066b8..eece70e89ef5e0f61f902356bcd0b83e1f3e526e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "tc": "vp run -r --concurrency-limit 2 typecheck", "lint": "vp lint --report-unused-disable-directives", "knip": "knip --preprocessor ./scripts/knip-schemas.ts", - "knip:check": "knip --include files,dependencies --no-config-hints && knip --workspace apps/server --workspace apps/desktop --workspace apps/web --workspace packages/client-runtime --workspace packages/contracts --workspace packages/effect-acp --workspace packages/effect-codex-app-server --workspace packages/shared --workspace packages/ssh --workspace packages/tailscale --workspace packages/provider-core --workspace packages/provider-testing --exports --preprocessor ./scripts/knip-schemas.ts --no-config-hints", + "knip:check": "knip --include files,dependencies --no-config-hints && knip --workspace apps/server --workspace apps/desktop --workspace apps/web --workspace packages/client-runtime --workspace packages/contracts --workspace packages/effect-acp --workspace packages/effect-codex-app-server --workspace packages/shared --workspace packages/ssh --workspace packages/tailscale --workspace packages/provider-core --workspace packages/provider-testing --workspace packages/provider-pi --exports --preprocessor ./scripts/knip-schemas.ts --no-config-hints", "knip:production": "knip --production --preprocessor ./scripts/knip-schemas.ts", "lint:mobile": "node scripts/mobile-native-static-check.ts", "test": "vp run -r test", diff --git a/packages/contracts/src/settings.ts b/packages/contracts/src/settings.ts index 9cce40c70ce273e12192ec45985bd48345478207..c9b3c00136dc750fa598ece6acd644bec38390f8 100644 --- a/packages/contracts/src/settings.ts +++ b/packages/contracts/src/settings.ts @@ -525,7 +525,8 @@ export const UsageModelPriceOverride = Schema.Struct({ }); export type UsageModelPriceOverride = typeof UsageModelPriceOverride.Type; -const makeBinaryPathSetting = (fallback: string) => +/** A binary path setting that decodes empty input to the provider's default executable. */ +export const makeBinaryPathSetting = (fallback: string) => TrimmedString.pipe( Schema.decodeTo( Schema.String, @@ -571,7 +572,8 @@ export type ProviderSettingsOrder = readonl string >[]; -function makeProviderSettingsSchema( +/** A provider settings struct whose fields the settings form renders in `order`. */ +export function makeProviderSettingsSchema( fields: Fields, options?: { readonly order?: ProviderSettingsOrder | undefined; @@ -861,39 +863,6 @@ export const MuseSettings = makeProviderSettingsSchema( ); export type MuseSettings = typeof MuseSettings.Type; -export const PiSettings = makeProviderSettingsSchema( - { - // Off by default like Cursor and Grok. Users opt in from Settings. - enabled: Schema.Boolean.pipe( - Schema.withDecodingDefault(Effect.succeed(false)), - Schema.annotateKey({ providerSettingsForm: { hidden: true } }), - ), - binaryPath: makeBinaryPathSetting("pi").pipe( - Schema.annotateKey({ - title: "Binary path", - description: "Path to the Pi coding agent binary.", - providerSettingsForm: { placeholder: "pi", clearWhenEmpty: "omit" }, - }), - ), - launchArgs: TrimmedString.pipe( - Schema.withDecodingDefault(Effect.succeed("")), - Schema.annotateKey({ - title: "Launch arguments", - description: "Additional CLI arguments passed to pi --mode rpc on session start.", - providerSettingsForm: { clearWhenEmpty: "omit" }, - }), - ), - customModels: Schema.Array(CustomModelSetting).pipe( - Schema.withDecodingDefault(Effect.succeed([])), - Schema.annotateKey({ providerSettingsForm: { hidden: true } }), - ), - }, - { - order: ["binaryPath", "launchArgs"], - }, -); -export type PiSettings = typeof PiSettings.Type; - export const AcpRegistryDistributionPreference = Schema.Literals(["auto", "binary", "npx", "uvx"]); export type AcpRegistryDistributionPreference = typeof AcpRegistryDistributionPreference.Type; diff --git a/packages/provider-core/package.json b/packages/provider-core/package.json index 23ac2a66e8467dc091dddbfa945c364a8c29ce2d..073faf381440156c27ee3811cb92a0730897e6ff 100644 --- a/packages/provider-core/package.json +++ b/packages/provider-core/package.json @@ -19,6 +19,10 @@ "types": "./src/server/collectStreamText.ts", "import": "./src/server/collectStreamText.ts" }, + "./server/continuationRequests": { + "types": "./src/server/continuationRequests.ts", + "import": "./src/server/continuationRequests.ts" + }, "./server/driver": { "types": "./src/server/driver.ts", "import": "./src/server/driver.ts" @@ -31,6 +35,10 @@ "types": "./src/server/failure.ts", "import": "./src/server/failure.ts" }, + "./server/handoffBudget": { + "types": "./src/server/handoffBudget.ts", + "import": "./src/server/handoffBudget.ts" + }, "./server/IdAllocator": { "types": "./src/server/IdAllocator.ts", "import": "./src/server/IdAllocator.ts" @@ -47,6 +55,10 @@ "types": "./src/server/maintenanceResolver.ts", "import": "./src/server/maintenanceResolver.ts" }, + "./server/managedProvider": { + "types": "./src/server/managedProvider.ts", + "import": "./src/server/managedProvider.ts" + }, "./server/mcpSession": { "types": "./src/server/mcpSession.ts", "import": "./src/server/mcpSession.ts" @@ -91,6 +103,10 @@ "types": "./src/server/snapshotProbe.ts", "import": "./src/server/snapshotProbe.ts" }, + "./server/snapshotSettings": { + "types": "./src/server/snapshotSettings.ts", + "import": "./src/server/snapshotSettings.ts" + }, "./server/textGeneration": { "types": "./src/server/textGeneration.ts", "import": "./src/server/textGeneration.ts" diff --git a/packages/provider-core/src/client.ts b/packages/provider-core/src/client.ts index 18c64cede5956df11d5cca39e5210ad94fe66d93..74a6e5ac8a7af6a3c1037e1abef05595d00c1e65 100644 --- a/packages/provider-core/src/client.ts +++ b/packages/provider-core/src/client.ts @@ -31,9 +31,26 @@ export interface ProviderEnvironmentField { readonly sensitive?: boolean; } +/** + * A provider glyph as plain data, so web and mobile can each draw it with + * their own SVG renderer. Colors are per theme; a path without a fill uses + * the icon's `fill`. + */ +export interface ProviderIcon { + readonly viewBox: string; + readonly fill: { readonly light: string; readonly dark: string }; + readonly paths: ReadonlyArray<{ + readonly d: string; + readonly fillRule?: "evenodd" | "nonzero"; + readonly fill?: { readonly light: string; readonly dark: string }; + }>; +} + export interface ProviderClientDefinition { readonly driverKind: ProviderDriverKind; readonly label: string; + /** Omitted for drivers whose glyph a client still draws itself. */ + readonly icon?: ProviderIcon; readonly settingsSchema: ProviderSettingsSchema; readonly environmentFields?: ReadonlyArray; /** Whether the driver has a default instance backed by legacy `providers.` settings. */ diff --git a/apps/server/src/orchestration-v2/ProviderContinuationRequests.ts b/packages/provider-core/src/server/continuationRequests.ts similarity index 97% rename from apps/server/src/orchestration-v2/ProviderContinuationRequests.ts rename to packages/provider-core/src/server/continuationRequests.ts index e6af7fa791b5f697f84d52f180cecdafb73b175e..f7c8606ace14e925d827b466a8c639e9a98d5eea 100644 --- a/apps/server/src/orchestration-v2/ProviderContinuationRequests.ts +++ b/packages/provider-core/src/server/continuationRequests.ts @@ -59,7 +59,7 @@ export interface ProviderContinuationRequest { export class ProviderContinuationRequests extends Context.Reference<{ readonly offer: (request: ProviderContinuationRequest) => Effect.Effect; readonly take: Effect.Effect; -}>("t3/orchestration-v2/ProviderContinuationRequests", { +}>("@t3tools/provider-core/server/continuationRequests/ProviderContinuationRequests", { defaultValue: () => ({ offer: () => Effect.void, take: Effect.never }), }) {} diff --git a/apps/server/src/orchestration-v2/ContextHandoffBudget.ts b/packages/provider-core/src/server/handoffBudget.ts similarity index 100% rename from apps/server/src/orchestration-v2/ContextHandoffBudget.ts rename to packages/provider-core/src/server/handoffBudget.ts diff --git a/apps/server/src/provider/makeManagedServerProvider.test.ts b/packages/provider-core/src/server/managedProvider.test.ts similarity index 88% rename from apps/server/src/provider/makeManagedServerProvider.test.ts rename to packages/provider-core/src/server/managedProvider.test.ts index 767ed192b25d98bd04d54adcceb6d7726c37e372..f46eb897bbb6a9384c3e127f701e623d03af116c 100644 --- a/apps/server/src/provider/makeManagedServerProvider.test.ts +++ b/packages/provider-core/src/server/managedProvider.test.ts @@ -1,4 +1,3 @@ -import * as NodeServices from "@effect/platform-node/NodeServices"; import { describe, it, assert } from "@effect/vitest"; import { DEFAULT_SERVER_SETTINGS, @@ -7,7 +6,6 @@ import { type ServerProvider, } from "@t3tools/contracts"; import { createModelCapabilities } from "@t3tools/shared/model"; -import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; import * as Duration from "effect/Duration"; import * as Effect from "effect/Effect"; @@ -18,14 +16,10 @@ import * as Ref from "effect/Ref"; import * as Stream from "effect/Stream"; import { TestClock } from "effect/testing"; -import * as BackgroundPolicy from "../background/BackgroundPolicy.ts"; -import * as ServerConfig from "../config.ts"; -import * as ServerSettings from "../serverSettings.ts"; -import { makeManagedServerProvider } from "./makeManagedServerProvider.ts"; -import * as ProviderHostLive from "./ProviderHostLive.ts"; +import { ProviderHost, type ProviderHostShape } from "./ProviderHost.ts"; +import { makeManagedServerProvider } from "./managedProvider.ts"; const emptyCapabilities = createModelCapabilities({ optionDescriptors: [] }); -const TEST_EPOCH = DateTime.makeUnsafe("1970-01-01T00:00:00.000Z"); const fastModeCapabilities = createModelCapabilities({ optionDescriptors: [ { @@ -102,60 +96,33 @@ const refreshedSnapshotSecond: ServerProvider = { message: "Refreshed provider availability again.", }; -function layerBackgroundPolicy(shouldRunScopeWork: boolean) { - return Layer.mock(BackgroundPolicy.BackgroundPolicy)({ - reportClientActivity: () => Effect.void, - removeRpcClient: () => Effect.void, - reportHostPowerState: () => Effect.void, - snapshot: Effect.succeed({ - hostPower: { - source: "unknown", - idle: "unknown", - idleSeconds: null, - locked: "unknown", - suspended: false, - onBattery: "unknown", - lowPowerMode: "unknown", - thermalState: "unknown", - stale: true, - updatedAt: TEST_EPOCH, +/** A host whose settings never change and whose background demand is fixed. */ +function layerProviderHost(input: { + readonly runBackgroundWork: boolean; + readonly settings?: Pick["settings"]; +}) { + return Layer.succeed( + ProviderHost, + ProviderHost.of({ + paths: { + cwd: process.cwd(), + baseDir: "/t3", + stateDir: "/t3/userdata", + providerStatusCacheDir: "/t3/caches", }, - leases: [], - activeForegroundLeaseCount: 0, - activeScopeKeys: [], - shouldRunOpportunisticWork: true, - updatedAt: TEST_EPOCH, + settings: input.settings ?? { + get: Effect.succeed(DEFAULT_SERVER_SETTINGS), + changes: Stream.empty, + subscribe: Effect.succeed(Stream.empty), + }, + shouldRunBackgroundWork: () => Effect.succeed(input.runBackgroundWork), + resolveAttachmentPath: () => null, }), - streamChanges: Stream.empty, - hasDemand: () => Effect.succeed(shouldRunScopeWork), - shouldRunScopeWork: () => Effect.succeed(shouldRunScopeWork), - shouldRunOpportunisticWork: Effect.succeed(shouldRunScopeWork), - }); -} - -const layerBackgroundPolicyAlwaysRun = layerBackgroundPolicy(true); -const layerBackgroundPolicyNeverRun = layerBackgroundPolicy(false); -const layerServerSettingsTest = ServerSettings.layerTest(); -const layerServerConfigTest = ServerConfig.layerTest(process.cwd(), { - prefix: "t3-managed-provider-test-", -}).pipe(Layer.provide(NodeServices.layer)); - -function layerProviderHost( - layerBackground: Layer.Layer, - layerSettings: Layer.Layer, -) { - return ProviderHostLive.layer.pipe( - Layer.provideMerge(layerBackground), - Layer.provideMerge(layerSettings), - Layer.provide(layerServerConfigTest), ); } -const layerAlwaysRunTest = layerProviderHost( - layerBackgroundPolicyAlwaysRun, - layerServerSettingsTest, -); -const layerNeverRunTest = layerProviderHost(layerBackgroundPolicyNeverRun, layerServerSettingsTest); +const layerAlwaysRunTest = layerProviderHost({ runBackgroundWork: true }); +const layerNeverRunTest = layerProviderHost({ runBackgroundWork: false }); const enrichedSnapshotSecond: ServerProvider = { ...refreshedSnapshotSecond, @@ -314,21 +281,13 @@ describe("makeManagedServerProvider", () => { }; const serverSettingsRef = yield* Ref.make(initialServerSettings); const serverSettingsChanges = yield* PubSub.unbounded(); - const layerServerSettings = Layer.succeed( - ServerSettings.ServerSettingsService, - ServerSettings.ServerSettingsService.of({ - start: Effect.void, - ready: Effect.void, - getSettings: Ref.get(serverSettingsRef), - updateSettings: () => Effect.die(new Error("unused in this test")), - updateProviderInstance: () => Effect.die(new Error("unused in this test")), - withSettingsSnapshot: (use) => Ref.get(serverSettingsRef).pipe(Effect.flatMap(use)), - streamChanges: Stream.empty, - subscribeChanges: PubSub.subscribe(serverSettingsChanges).pipe( - Effect.map((subscription) => Stream.fromSubscription(subscription)), - ), - }), - ); + const hostSettings: ProviderHostShape["settings"] = { + get: Ref.get(serverSettingsRef), + changes: Stream.empty, + subscribe: PubSub.subscribe(serverSettingsChanges).pipe( + Effect.map((subscription) => Stream.fromSubscription(subscription)), + ), + }; const checkCalls = yield* Ref.make(0); const initialCheckDone = yield* Deferred.make(); const periodicCheckDone = yield* Deferred.make(); @@ -348,7 +307,7 @@ describe("makeManagedServerProvider", () => { Effect.as(refreshedSnapshot), ), }).pipe( - Effect.provide(layerProviderHost(layerBackgroundPolicyAlwaysRun, layerServerSettings)), + Effect.provide(layerProviderHost({ runBackgroundWork: true, settings: hostSettings })), ); yield* Deferred.await(initialCheckDone); diff --git a/apps/server/src/provider/makeManagedServerProvider.ts b/packages/provider-core/src/server/managedProvider.ts similarity index 97% rename from apps/server/src/provider/makeManagedServerProvider.ts rename to packages/provider-core/src/server/managedProvider.ts index e2637cc1a146d8ab45efa916d42e57deb27731f6..a04873f0e6087c057ca6b42aa14814c0b854f2cb 100644 --- a/apps/server/src/provider/makeManagedServerProvider.ts +++ b/packages/provider-core/src/server/managedProvider.ts @@ -15,12 +15,9 @@ import * as Scope from "effect/Scope"; import * as Stream from "effect/Stream"; import * as Semaphore from "effect/Semaphore"; -import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; -import { - applyUsageLimitsUpdate, - resolveUsageLimitsAfterProbe, -} from "@t3tools/provider-core/server/usageLimits"; -import type { ServerProviderShape } from "@t3tools/provider-core/server/snapshot"; +import { ProviderHost } from "./ProviderHost.ts"; +import { applyUsageLimitsUpdate, resolveUsageLimitsAfterProbe } from "./usageLimits.ts"; +import type { ServerProviderShape } from "./snapshot.ts"; interface ProviderSnapshotState { readonly snapshot: ServerProvider; diff --git a/apps/server/src/provider/providerUpdateSettings.ts b/packages/provider-core/src/server/snapshotSettings.ts similarity index 94% rename from apps/server/src/provider/providerUpdateSettings.ts rename to packages/provider-core/src/server/snapshotSettings.ts index f61061439730634c798cdfa07fb33d9c28c6484d..87286728fe60c1dfba11b6d2dd84999bcc6bd9b2 100644 --- a/apps/server/src/provider/providerUpdateSettings.ts +++ b/packages/provider-core/src/server/snapshotSettings.ts @@ -3,7 +3,7 @@ import * as Effect from "effect/Effect"; import * as Equal from "effect/Equal"; import * as Stream from "effect/Stream"; -import type { ProviderHostShape } from "@t3tools/provider-core/server/ProviderHost"; +import type { ProviderHostShape } from "./ProviderHost.ts"; export interface ProviderSnapshotSettings { readonly provider: Settings; diff --git a/packages/provider-pi/package.json b/packages/provider-pi/package.json new file mode 100644 index 0000000000000000000000000000000000000000..7387a33303f687d5482c5af5d7811963e46dea99 --- /dev/null +++ b/packages/provider-pi/package.json @@ -0,0 +1,36 @@ +{ + "name": "@t3tools/provider-pi", + "private": true, + "type": "module", + "exports": { + "./client": { + "types": "./src/client.ts", + "import": "./src/client.ts" + }, + "./settings": { + "types": "./src/settings.ts", + "import": "./src/settings.ts" + }, + "./server": { + "types": "./src/server.ts", + "import": "./src/server.ts" + } + }, + "scripts": { + "typecheck": "tsc --noEmit", + "test": "vp test run --config ../../vite.config.ts --dir ." + }, + "dependencies": { + "@t3tools/contracts": "workspace:*", + "@t3tools/provider-core": "workspace:*", + "@t3tools/shared": "workspace:*", + "effect": "catalog:" + }, + "devDependencies": { + "@effect/platform-node": "catalog:", + "@effect/vitest": "catalog:", + "@t3tools/provider-testing": "workspace:*", + "@types/node": "catalog:", + "vite-plus": "catalog:" + } +} diff --git a/packages/provider-pi/src/client.ts b/packages/provider-pi/src/client.ts new file mode 100644 index 0000000000000000000000000000000000000000..2b1acd8f2f88b200999d91a8a8bd811d71d70e86 --- /dev/null +++ b/packages/provider-pi/src/client.ts @@ -0,0 +1,27 @@ +/** + * Pi's client definition: settings form, label, and glyph. Browser- and + * React Native-safe. + * + * @module provider-pi/client + */ +import { ProviderDriverKind } from "@t3tools/contracts"; +import { defineProviderClient } from "@t3tools/provider-core/client"; + +import { PiSettings } from "./settings.ts"; + +export const piClient = defineProviderClient({ + driverKind: ProviderDriverKind.make("pi"), + label: "Pi", + settingsSchema: PiSettings, + icon: { + viewBox: "165.29 165.29 469.43 469.43", + fill: { light: "#0F0F0F", dark: "#F5F5F5" }, + paths: [ + { + d: "M165.29 165.29H517.36V400H400V517.36H282.65V634.72H165.29ZM282.65 282.65V400H400V282.65Z", + fillRule: "evenodd", + }, + { d: "M517.36 400H634.72V634.72H517.36Z" }, + ], + }, +}); diff --git a/packages/provider-pi/src/server.ts b/packages/provider-pi/src/server.ts new file mode 100644 index 0000000000000000000000000000000000000000..8205371dbbe2159260eb9b4553fcff25d036dca1 --- /dev/null +++ b/packages/provider-pi/src/server.ts @@ -0,0 +1,8 @@ +/** + * Pi's server entry: the driver the server registers, plus the adapter + * driver used by replay tests and the fixture recorder. + * + * @module provider-pi/server + */ +export { PiDriver, type PiDriverEnv } from "./server/driver.ts"; +export { PI_PROVIDER, PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "./server/adapter.ts"; diff --git a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts b/packages/provider-pi/src/server/adapter.test.ts similarity index 99% rename from apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts rename to packages/provider-pi/src/server/adapter.test.ts index 8789b5268498d8da10f07a722954178964a1f1c7..65a01a4030952c3af63b12ba5865179e74439223 100644 --- a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.test.ts +++ b/packages/provider-pi/src/server/adapter.test.ts @@ -35,7 +35,7 @@ import { HostProcessEnvironment } from "@t3tools/shared/hostProcess"; import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; import { layerTestProviderHost } from "@t3tools/provider-testing/host"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import * as McpProviderSession from "@t3tools/provider-core/server/mcpSession"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import { @@ -43,14 +43,14 @@ import { type ProviderAdapterV2Event, type ProviderAdapterV2SessionRuntime, } from "@t3tools/provider-core/server/ProviderAdapter"; -import { handoffBudget } from "../ContextHandoffBudget.ts"; +import { handoffBudget } from "@t3tools/provider-core/server/handoffBudget"; import { makePiAdapterV2, PiAdapterV2Driver, PI_PROVIDER, type PiAdapterV2Options, -} from "./PiAdapterV2.ts"; -import { makePiRpcConnection, type PiRpcRecord } from "./PiRpc.ts"; +} from "./adapter.ts"; +import { makePiRpcConnection, type PiRpcRecord } from "./rpc.ts"; const layerTest = Layer.mergeAll( NodeServices.layer, diff --git a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts b/packages/provider-pi/src/server/adapter.ts similarity index 99% rename from apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts rename to packages/provider-pi/src/server/adapter.ts index 520992dbc4e40a65f39e215d4a79f20c8f2f77b8..73e1f64953c5c997bdba1775c8975adf4adaba77 100644 --- a/apps/server/src/orchestration-v2/Adapters/PiAdapterV2.ts +++ b/packages/provider-pi/src/server/adapter.ts @@ -27,7 +27,6 @@ import { HostProcessEnvironment } from "@t3tools/shared/hostProcess"; import { getModelSelectionStringOptionValue } from "@t3tools/shared/model"; import { defaultInstanceIdForDriver, - PiSettings, ProviderDriverKind, type ChatAttachment, type ModelSelection, @@ -46,6 +45,7 @@ import { type ProviderInstanceId, type OrchestrationV2ProviderTurnTokenUsage, } from "@t3tools/contracts"; +import { PiSettings } from "../settings.ts"; import * as Cause from "effect/Cause"; import * as DateTime from "effect/DateTime"; import * as Deferred from "effect/Deferred"; @@ -68,11 +68,11 @@ import { parsePiCompactCommand, parsePiDiscoveredCommands, type PiCompactCommand, -} from "../../provider/PiCommands.ts"; +} from "./commands.ts"; import { mergeProviderInstanceEnvironment } from "@t3tools/provider-core/server/instanceEnvironment"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; import * as ProviderAdapter from "@t3tools/provider-core/server/ProviderAdapter"; -import * as ProviderContinuationRequests from "../ProviderContinuationRequests.ts"; +import * as ProviderContinuationRequests from "@t3tools/provider-core/server/continuationRequests"; import { ProviderAdapterDriverCreateError, type ProviderAdapterDriver, @@ -91,13 +91,13 @@ import { piRecordString as recordString, type PiRpcConnection, type PiRpcRecord, -} from "./PiRpc.ts"; +} from "./rpc.ts"; import { buildPiRpcLaunch, materializePiT3McpExtension, resolvePiLaunchArgs, -} from "./piT3McpInjection.ts"; -import { PI_FILE_CHANGE_TOOLS } from "./piT3McpExtensionSource.ts"; +} from "./mcpInjection.ts"; +import { PI_FILE_CHANGE_TOOLS } from "./mcpExtensionSource.ts"; export const PI_PROVIDER = ProviderDriverKind.make("pi"); const PI_DRIVER_KIND = PI_PROVIDER; diff --git a/apps/server/src/provider/PiCommands.test.ts b/packages/provider-pi/src/server/commands.test.ts similarity index 99% rename from apps/server/src/provider/PiCommands.test.ts rename to packages/provider-pi/src/server/commands.test.ts index b84c181e9fc5755cc23e10697c78671242b359e7..09f39130dd06029bd015d9700acb7d3f1033e2da 100644 --- a/apps/server/src/provider/PiCommands.test.ts +++ b/packages/provider-pi/src/server/commands.test.ts @@ -6,7 +6,7 @@ import { parsePiDiscoveredCommands, PI_COMPACT_SLASH_COMMAND, withPiBuiltinSlashCommands, -} from "./PiCommands.ts"; +} from "./commands.ts"; it("maps current Pi skill metadata to T3's user and project skill scopes", () => { expect( diff --git a/apps/server/src/provider/PiCommands.ts b/packages/provider-pi/src/server/commands.ts similarity index 100% rename from apps/server/src/provider/PiCommands.ts rename to packages/provider-pi/src/server/commands.ts diff --git a/apps/server/src/provider/Drivers/PiDriver.test.ts b/packages/provider-pi/src/server/driver.test.ts similarity index 92% rename from apps/server/src/provider/Drivers/PiDriver.test.ts rename to packages/provider-pi/src/server/driver.test.ts index 2c4751ddf812997fe272f07587ddd8694a2dd79f..83a6f33eb57c5fec18c3b51aeda1b2800867a1f2 100644 --- a/apps/server/src/provider/Drivers/PiDriver.test.ts +++ b/packages/provider-pi/src/server/driver.test.ts @@ -1,6 +1,6 @@ import * as NodeServices from "@effect/platform-node/NodeServices"; import { assert, it } from "@effect/vitest"; -import { ProviderInstanceId, type PiSettings } from "@t3tools/contracts"; +import { DEFAULT_SERVER_SETTINGS, ProviderInstanceId } from "@t3tools/contracts"; import * as Deferred from "effect/Deferred"; import * as Effect from "effect/Effect"; import * as Fiber from "effect/Fiber"; @@ -13,28 +13,24 @@ import * as TestClock from "effect/testing/TestClock"; import { HttpClient } from "effect/http"; import { ChildProcess, ChildProcessSpawner } from "effect/process"; -import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts"; -import * as ServerConfig from "../../config.ts"; import * as IdAllocator from "@t3tools/provider-core/server/IdAllocator"; -import * as ServerSettings from "../../serverSettings.ts"; -import * as ProviderHostLive from "../ProviderHostLive.ts"; -import { PiDriver } from "./PiDriver.ts"; +import { layerTestProviderHost } from "@t3tools/provider-testing/host"; +import type { PiSettings } from "../settings.ts"; +import { PiDriver } from "./driver.ts"; -const layerDeps = Layer.mergeAll( - ServerConfig.layerTest("/machine", { prefix: "t3-pi-driver-" }), - IdAllocator.layer, - ServerSettings.layerTest({ enableProviderUpdateChecks: false }), - Layer.mock(BackgroundPolicy.BackgroundPolicy)({ - shouldRunScopeWork: () => Effect.succeed(false), +const layerTest = Layer.mergeAll( + layerTestProviderHost({ + cwd: "/machine", + settings: { ...DEFAULT_SERVER_SETTINGS, enableProviderUpdateChecks: false }, + runBackgroundWork: false, }), + IdAllocator.layer, Layer.succeed( HttpClient.HttpClient, HttpClient.make(() => Effect.die("Unexpected HTTP")), ), ).pipe(Layer.provideMerge(NodeServices.layer)); -const layerTest = ProviderHostLive.layer.pipe(Layer.provideMerge(layerDeps)); - const decodeRequest = Schema.decodeSync( Schema.fromJsonString(Schema.Record(Schema.String, Schema.Unknown)), ); diff --git a/apps/server/src/provider/Drivers/PiDriver.ts b/packages/provider-pi/src/server/driver.ts similarity index 93% rename from apps/server/src/provider/Drivers/PiDriver.ts rename to packages/provider-pi/src/server/driver.ts index 6bfc0ac15421d852444f23dbc3c013cdeca75f4a..eb58a6dcc61451301b4f433cf18ca80c3074848d 100644 --- a/apps/server/src/provider/Drivers/PiDriver.ts +++ b/packages/provider-pi/src/server/driver.ts @@ -6,7 +6,8 @@ * Pi state (sessions, settings, extensions, auth) lives in the user's own * `~/.pi/agent`, so continuation identity uses the default instance grouping. */ -import { PiSettings, ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { ProviderDriverKind, type ServerProvider } from "@t3tools/contracts"; +import { PiSettings } from "../settings.ts"; import * as Effect from "effect/Effect"; import * as FileSystem from "effect/FileSystem"; import * as Path from "effect/Path"; @@ -15,19 +16,16 @@ import { HttpClient } from "effect/http"; import { ChildProcessSpawner } from "effect/process"; import { ProviderHost } from "@t3tools/provider-core/server/ProviderHost"; -import { makePiTextGeneration } from "../../textGeneration/PiTextGeneration.ts"; -import { - PiAdapterV2Driver, - type PiAdapterV2DriverEnv, -} from "../../orchestration-v2/Adapters/PiAdapterV2.ts"; -import { ProviderDriverError } from "../Errors.ts"; +import { makePiTextGeneration } from "./textGeneration.ts"; +import { PiAdapterV2Driver, type PiAdapterV2DriverEnv } from "./adapter.ts"; +import { ProviderDriverError } from "@t3tools/provider-core/server/errors"; import { buildInitialPiProviderSnapshot, checkPiProviderStatus, discoverPiCommandsForCwd, enrichPiSnapshot, -} from "../PiProvider.ts"; -import { makeManagedServerProvider } from "../makeManagedServerProvider.ts"; +} from "./status.ts"; +import { makeManagedServerProvider } from "@t3tools/provider-core/server/managedProvider"; import { defaultProviderContinuationIdentity, type ProviderDriver, @@ -44,7 +42,7 @@ import { haveProviderSnapshotSettingsChanged, makeProviderSnapshotSettingsSource, type ProviderSnapshotSettings, -} from "../providerUpdateSettings.ts"; +} from "@t3tools/provider-core/server/snapshotSettings"; const decodePiSettings = Schema.decodeSync(PiSettings); diff --git a/apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.test.ts b/packages/provider-pi/src/server/mcpExtensionSource.test.ts similarity index 99% rename from apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.test.ts rename to packages/provider-pi/src/server/mcpExtensionSource.test.ts index 5498d2afec83a251b62190ea69868c5215fd57d6..4d4aef33d8fd4def08276c5dee682f1218fe687f 100644 --- a/apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.test.ts +++ b/packages/provider-pi/src/server/mcpExtensionSource.test.ts @@ -2,7 +2,7 @@ import * as NodeModule from "node:module"; import * as NodeVM from "node:vm"; import { assert, describe, it } from "@effect/vitest"; -import { PI_T3_MCP_EXTENSION_SOURCE } from "./piT3McpExtensionSource.ts"; +import { PI_T3_MCP_EXTENSION_SOURCE } from "./mcpExtensionSource.ts"; type RequestHook = ( event: { payload: unknown }, diff --git a/apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.ts b/packages/provider-pi/src/server/mcpExtensionSource.ts similarity index 100% rename from apps/server/src/orchestration-v2/Adapters/piT3McpExtensionSource.ts rename to packages/provider-pi/src/server/mcpExtensionSource.ts diff --git a/apps/server/src/orchestration-v2/Adapters/piT3McpInjection.test.ts b/packages/provider-pi/src/server/mcpInjection.test.ts similarity index 98% rename from apps/server/src/orchestration-v2/Adapters/piT3McpInjection.test.ts rename to packages/provider-pi/src/server/mcpInjection.test.ts index b462b98a612a537de685d3ed4a47eab327b09abd..45f8781a563554510ea0a89e627770c303d1d3d1 100644 --- a/apps/server/src/orchestration-v2/Adapters/piT3McpInjection.test.ts +++ b/packages/provider-pi/src/server/mcpInjection.test.ts @@ -9,12 +9,12 @@ import { T3_MCP_BEARER_ENV, T3_MCP_URL_ENV, T3_PI_RUNTIME_MODE_ENV, -} from "./piT3McpExtensionSource.ts"; +} from "./mcpExtensionSource.ts"; import { buildPiRpcLaunch, materializePiT3McpExtension, resolvePiLaunchArgs, -} from "./piT3McpInjection.ts"; +} from "./mcpInjection.ts"; const threadId = ThreadId.make("thread-pi-t3-mcp"); diff --git a/apps/server/src/orchestration-v2/Adapters/piT3McpInjection.ts b/packages/provider-pi/src/server/mcpInjection.ts similarity index 99% rename from apps/server/src/orchestration-v2/Adapters/piT3McpInjection.ts rename to packages/provider-pi/src/server/mcpInjection.ts index 5f377782178007f54bf56992c026bef0fd5ab5cb..25e1d3ddbb98cc5168e7400413162e0b59cbb7f3 100644 --- a/apps/server/src/orchestration-v2/Adapters/piT3McpInjection.ts +++ b/packages/provider-pi/src/server/mcpInjection.ts @@ -9,7 +9,7 @@ import { T3_MCP_BEARER_ENV, T3_MCP_URL_ENV, T3_PI_RUNTIME_MODE_ENV, -} from "./piT3McpExtensionSource.ts"; +} from "./mcpExtensionSource.ts"; const RESERVED_PI_LAUNCH_ARGUMENTS = new Set([ "--continue", diff --git a/apps/server/src/orchestration-v2/Adapters/PiRpc.ts b/packages/provider-pi/src/server/rpc.ts similarity index 100% rename from apps/server/src/orchestration-v2/Adapters/PiRpc.ts rename to packages/provider-pi/src/server/rpc.ts diff --git a/apps/server/src/provider/PiProvider.test.ts b/packages/provider-pi/src/server/status.test.ts similarity index 97% rename from apps/server/src/provider/PiProvider.test.ts rename to packages/provider-pi/src/server/status.test.ts index 7ca54dbf3cb0a279003558792f8d6e570ababc4d..133a505612b1090f9d04f382ff3d9502bd36bed7 100644 --- a/apps/server/src/provider/PiProvider.test.ts +++ b/packages/provider-pi/src/server/status.test.ts @@ -5,7 +5,7 @@ import * as Sink from "effect/Sink"; import * as Stream from "effect/Stream"; import { ChildProcess, ChildProcessSpawner } from "effect/process"; -import { checkPiProviderStatus, MINIMUM_PI_VERSION } from "./PiProvider.ts"; +import { checkPiProviderStatus, MINIMUM_PI_VERSION } from "./status.ts"; const encoder = new TextEncoder(); diff --git a/apps/server/src/provider/PiProvider.ts b/packages/provider-pi/src/server/status.ts similarity index 98% rename from apps/server/src/provider/PiProvider.ts rename to packages/provider-pi/src/server/status.ts index 4ea63f02ea494959a159be0dc9cbe4c2993a6a54..54be47d3dfd9c498b178b8d55e931e88b5bbda14 100644 --- a/apps/server/src/provider/PiProvider.ts +++ b/packages/provider-pi/src/server/status.ts @@ -10,10 +10,10 @@ */ import { type CustomModelSetting, - type PiSettings, type ServerProvider, type ServerProviderModel, } from "@t3tools/contracts"; +import type { PiSettings } from "../settings.ts"; import { causeErrorTag } from "@t3tools/shared/observability"; import { resolveSpawnCommand } from "@t3tools/shared/shell"; import { compareSemverVersions } from "@t3tools/shared/semver"; @@ -26,17 +26,14 @@ import * as Result from "effect/Result"; import { HttpClient } from "effect/http"; import { ChildProcess, ChildProcessSpawner } from "effect/process"; -import { - buildPiRpcLaunch, - resolvePiLaunchArgs, -} from "../orchestration-v2/Adapters/piT3McpInjection.ts"; +import { buildPiRpcLaunch, resolvePiLaunchArgs } from "./mcpInjection.ts"; import { makePiRpcConnection, PiRpcError, PiRpcTimeoutError, piRecordField as recordField, piRecordString as recordString, -} from "../orchestration-v2/Adapters/PiRpc.ts"; +} from "./rpc.ts"; import { buildServerProvider, isCommandMissingCause, @@ -52,12 +49,12 @@ import { import { EMPTY_PI_MODEL_CAPABILITIES, thinkingCapabilitiesForPiModel, -} from "./piThinkingCapabilities.ts"; +} from "./thinkingCapabilities.ts"; import { parsePiDiscoveredCommands, withPiBuiltinSlashCommands, type PiDiscoveredCommands, -} from "./PiCommands.ts"; +} from "./commands.ts"; const PI_PRESENTATION = { displayName: "Pi", diff --git a/apps/server/src/textGeneration/PiTextGeneration.test.ts b/packages/provider-pi/src/server/textGeneration.test.ts similarity index 98% rename from apps/server/src/textGeneration/PiTextGeneration.test.ts rename to packages/provider-pi/src/server/textGeneration.test.ts index 336e110a9ffc81c416fa0c6d2a1296b1477969fd..fb56753785a8093bf31a3743f71a74b479c417de 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.test.ts +++ b/packages/provider-pi/src/server/textGeneration.test.ts @@ -9,7 +9,7 @@ import * as Sink from "effect/Sink"; import * as Stream from "effect/Stream"; import { ChildProcessSpawner } from "effect/process"; -import { makePiTextGeneration } from "./PiTextGeneration.ts"; +import { makePiTextGeneration } from "./textGeneration.ts"; const decodeJsonLine = Schema.decodeUnknownSync(Schema.fromJsonString(Schema.Unknown)); const encodeJsonLine = Schema.encodeSync(Schema.fromJsonString(Schema.Unknown)); diff --git a/apps/server/src/textGeneration/PiTextGeneration.ts b/packages/provider-pi/src/server/textGeneration.ts similarity index 93% rename from apps/server/src/textGeneration/PiTextGeneration.ts rename to packages/provider-pi/src/server/textGeneration.ts index 7d52e4e08e6597ce1645f83897e766d04a1a36e8..cf334556fdf92a9d7c981d3ed775ba51d8350de2 100644 --- a/apps/server/src/textGeneration/PiTextGeneration.ts +++ b/packages/provider-pi/src/server/textGeneration.ts @@ -10,13 +10,11 @@ import * as Queue from "effect/Queue"; import * as Schema from "effect/Schema"; import { ChildProcessSpawner } from "effect/process"; -import { TextGenerationError, type PiSettings } from "@t3tools/contracts"; +import { TextGenerationError } from "@t3tools/contracts"; +import type { PiSettings } from "../settings.ts"; -import { makePiRpcConnection, parsePiModelSlug } from "../orchestration-v2/Adapters/PiRpc.ts"; -import { - buildPiRpcLaunch, - resolvePiLaunchArgs, -} from "../orchestration-v2/Adapters/piT3McpInjection.ts"; +import { makePiRpcConnection, parsePiModelSlug } from "./rpc.ts"; +import { buildPiRpcLaunch, resolvePiLaunchArgs } from "./mcpInjection.ts"; import * as TextGenerationOperations from "@t3tools/provider-core/server/textGenerationOperations"; const PI_TIMEOUT_MS = 180_000; diff --git a/apps/server/src/provider/piThinkingCapabilities.test.ts b/packages/provider-pi/src/server/thinkingCapabilities.test.ts similarity index 95% rename from apps/server/src/provider/piThinkingCapabilities.test.ts rename to packages/provider-pi/src/server/thinkingCapabilities.test.ts index b6474bf2d9ec400ae07f3020c3f0cdcf521189d9..5617c01b3943323949902c6c4f8a5dba4d26c913 100644 --- a/apps/server/src/provider/piThinkingCapabilities.test.ts +++ b/packages/provider-pi/src/server/thinkingCapabilities.test.ts @@ -1,6 +1,6 @@ import { assert, describe, it } from "@effect/vitest"; -import { thinkingCapabilitiesForPiModel } from "./piThinkingCapabilities.ts"; +import { thinkingCapabilitiesForPiModel } from "./thinkingCapabilities.ts"; describe("thinkingCapabilitiesForPiModel", () => { it("gives every choice its real level id and tags Pi's default", () => { diff --git a/apps/server/src/provider/piThinkingCapabilities.ts b/packages/provider-pi/src/server/thinkingCapabilities.ts similarity index 100% rename from apps/server/src/provider/piThinkingCapabilities.ts rename to packages/provider-pi/src/server/thinkingCapabilities.ts diff --git a/packages/provider-pi/src/settings.ts b/packages/provider-pi/src/settings.ts new file mode 100644 index 0000000000000000000000000000000000000000..8d19e29ac6a2e643849ff7567ed54b6fcce1cfe1 --- /dev/null +++ b/packages/provider-pi/src/settings.ts @@ -0,0 +1,47 @@ +/** + * Pi instance settings. Shared by the server driver and the client settings + * form, so it holds only browser-safe schema code. + * + * @module provider-pi/settings + */ +import { + CustomModelSetting, + makeBinaryPathSetting, + makeProviderSettingsSchema, + TrimmedString, +} from "@t3tools/contracts"; +import * as Effect from "effect/Effect"; +import * as Schema from "effect/Schema"; + +export const PiSettings = makeProviderSettingsSchema( + { + // Off by default like Cursor and Grok. Users opt in from Settings. + enabled: Schema.Boolean.pipe( + Schema.withDecodingDefault(Effect.succeed(false)), + Schema.annotateKey({ providerSettingsForm: { hidden: true } }), + ), + binaryPath: makeBinaryPathSetting("pi").pipe( + Schema.annotateKey({ + title: "Binary path", + description: "Path to the Pi coding agent binary.", + providerSettingsForm: { placeholder: "pi", clearWhenEmpty: "omit" }, + }), + ), + launchArgs: TrimmedString.pipe( + Schema.withDecodingDefault(Effect.succeed("")), + Schema.annotateKey({ + title: "Launch arguments", + description: "Additional CLI arguments passed to pi --mode rpc on session start.", + providerSettingsForm: { clearWhenEmpty: "omit" }, + }), + ), + customModels: Schema.Array(CustomModelSetting).pipe( + Schema.withDecodingDefault(Effect.succeed([])), + Schema.annotateKey({ providerSettingsForm: { hidden: true } }), + ), + }, + { + order: ["binaryPath", "launchArgs"], + }, +); +export type PiSettings = typeof PiSettings.Type; diff --git a/packages/provider-pi/tsconfig.json b/packages/provider-pi/tsconfig.json new file mode 100644 index 0000000000000000000000000000000000000000..374bac55202ddcad695ede1c567ec219a61e9c48 --- /dev/null +++ b/packages/provider-pi/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "types": ["node"] + }, + "include": ["src"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a3da3784edd8443670dbb24d7a2126a5fd59c689..b948baba7c65c30129e92c6c3cdd31884ad2cc09 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -353,6 +353,12 @@ importers: '@t3tools/mobile-terminal-native': specifier: file:./modules/t3-terminal version: file:apps/mobile/modules/t3-terminal + '@t3tools/provider-core': + specifier: workspace:* + version: link:../../packages/provider-core + '@t3tools/provider-pi': + specifier: workspace:* + version: link:../../packages/provider-pi '@t3tools/shared': specifier: workspace:* version: link:../../packages/shared @@ -597,6 +603,9 @@ importers: '@t3tools/provider-core': specifier: workspace:* version: link:../../packages/provider-core + '@t3tools/provider-pi': + specifier: workspace:* + version: link:../../packages/provider-pi diff: specifier: 8.0.3 version: 8.0.3 @@ -724,6 +733,9 @@ importers: '@t3tools/provider-core': specifier: workspace:* version: link:../../packages/provider-core + '@t3tools/provider-pi': + specifier: workspace:* + version: link:../../packages/provider-pi '@t3tools/shared': specifier: workspace:* version: link:../../packages/shared @@ -1087,6 +1099,37 @@ importers: specifier: 1.0.0 version: 1.0.0(@types/node@24.12.4)(@vitest/ui@5.0.1(vitest@5.0.1))(bufferutil@4.1.0)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + packages/provider-pi: + dependencies: + '@t3tools/contracts': + specifier: workspace:* + version: link:../contracts + '@t3tools/provider-core': + specifier: workspace:* + version: link:../provider-core + '@t3tools/shared': + specifier: workspace:* + version: link:../shared + effect: + specifier: 4.0.1 + version: 4.0.1(patch_hash=a33cba07c41f32374c2aaa86ea4a84d3ab9a872a78c94b65e929b19f8361856f) + devDependencies: + '@effect/platform-node': + specifier: 4.0.1 + version: 4.0.1(bufferutil@4.1.0)(effect@4.0.1(patch_hash=a33cba07c41f32374c2aaa86ea4a84d3ab9a872a78c94b65e929b19f8361856f))(redis@6.2.1)(utf-8-validate@6.0.6) + '@effect/vitest': + specifier: 4.0.1 + version: 4.0.1(patch_hash=359f6fb2f7b3ec145bb72208edb9034f02489791aa2491a55cdbd69bd56ee0d2)(@types/node@24.12.4)(@vitest/ui@5.0.1)(bufferutil@4.1.0)(effect@4.0.1(patch_hash=a33cba07c41f32374c2aaa86ea4a84d3ab9a872a78c94b65e929b19f8361856f))(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + '@t3tools/provider-testing': + specifier: workspace:* + version: link:../provider-testing + '@types/node': + specifier: 24.12.4 + version: 24.12.4 + vite-plus: + specifier: 1.0.0 + version: 1.0.0(@types/node@24.12.4)(@vitest/ui@5.0.1(vitest@5.0.1))(bufferutil@4.1.0)(esbuild@0.28.2)(jiti@2.7.0)(jsdom@30.1.0(@noble/hashes@1.8.0))(msw@2.12.11(@types/node@24.12.4)(typescript@7.0.2))(terser@5.48.0)(typescript@7.0.2)(unrun@0.2.39)(utf-8-validate@6.0.6)(yaml@2.9.0) + packages/provider-testing: dependencies: '@effect/platform-node': diff --git a/scripts/release-smoke.ts b/scripts/release-smoke.ts index 296b3ac1441ff12623743d598581f08807a68de5..8fb9ab883995e474cc7f8fe404a2da8114ca8dac 100644 --- a/scripts/release-smoke.ts +++ b/scripts/release-smoke.ts @@ -30,6 +30,7 @@ const workspaceFiles = [ "packages/tailscale/package.json", "packages/provider-core/package.json", "packages/provider-testing/package.json", + "packages/provider-pi/package.json", "packages/effect-acp/package.json", "packages/effect-codex-app-server/package.json", "scripts/package.json", -- 2.54.0