Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 26 additions & 10 deletions apps/server/src/provider/Layers/ProviderRegistry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { checkClaudeProviderStatus } from "./ClaudeProvider.ts";
import * as BackgroundPolicy from "../../background/BackgroundPolicy.ts";
import { AntigravityInstallation } from "../AntigravityInstallation.ts";
import * as ModelManifest from "../ModelManifest.ts";
import { applyProviderCompatibility } from "../providerCompatibility.ts";
import * as CodexResetCredit from "./codexResetCredit.ts";
import * as OpenCodeRuntime from "../opencodeRuntime.ts";
import * as ProviderEventLoggers from "./ProviderEventLoggers.ts";
Expand Down Expand Up @@ -76,6 +77,12 @@ process.env.T3CODE_CURSOR_ENABLED = "1";

const encoder = new TextEncoder();
const TEST_EPOCH = DateTime.makeUnsafe("1970-01-01T00:00:00.000Z");
const withBundledCompatibility = (snapshot: ServerProvider) =>
applyProviderCompatibility(
snapshot,
undefined,
ModelManifest.BUNDLED_MODEL_MANIFEST.compatibility,
);

// Provider metadata checks use a bundled manifest and stubbed HTTP.
const TestHttpClientLive = Layer.succeed(
Expand Down Expand Up @@ -1754,7 +1761,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te
);
assert.deepStrictEqual(
recoveredProviders.find((provider) => provider.instanceId === codexInstanceId),
codexProvider,
withBundledCompatibility(codexProvider),
);

yield* Ref.set(catalogSnapshot, changedCatalogProvider);
Expand All @@ -1766,7 +1773,7 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te
);
assert.deepStrictEqual(
changedProviders.find((provider) => provider.instanceId === codexInstanceId),
codexProvider,
withBundledCompatibility(codexProvider),
);
}).pipe(Effect.provide(runtimeServices));

Expand Down Expand Up @@ -1880,10 +1887,13 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te
yield* Fiber.join(persisted);
const cachedProvider = yield* readProviderStatusCache(filePath);

assert.deepStrictEqual(cachedProvider, {
...refreshedProvider,
models: [...initialProvider.models],
});
assert.deepStrictEqual(
cachedProvider,
withBundledCompatibility({
...refreshedProvider,
models: [...initialProvider.models],
}),
);
}).pipe(Effect.provide(runtimeServices));
}),
);
Expand Down Expand Up @@ -2095,10 +2105,14 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te
yield* Effect.gen(function* () {
const registry = yield* ProviderRegistry.ProviderRegistry;

assert.deepStrictEqual(yield* registry.getProviders, [cachedProvider]);
assert.deepStrictEqual(yield* registry.refresh(codexDriver), [cachedProvider]);
assert.deepStrictEqual(yield* registry.getProviders, [
withBundledCompatibility(cachedProvider),
]);
assert.deepStrictEqual(yield* registry.refresh(codexDriver), [
withBundledCompatibility(cachedProvider),
]);
assert.deepStrictEqual(yield* registry.refreshInstance(codexInstanceId), [
cachedProvider,
withBundledCompatibility(cachedProvider),
]);
}).pipe(Effect.provide(runtimeServices));
}),
Expand Down Expand Up @@ -2206,7 +2220,9 @@ it.layer(Layer.mergeAll(NodeServices.layer, ServerSettingsModule.layerTest(), Te

yield* Effect.gen(function* () {
const registry = yield* ProviderRegistry.ProviderRegistry;
assert.deepStrictEqual(yield* registry.getProviders, [codexProvider]);
assert.deepStrictEqual(yield* registry.getProviders, [
withBundledCompatibility(codexProvider),
]);

yield* Ref.set(failNextList, true);
yield* PubSub.publish(changes, undefined);
Expand Down
50 changes: 48 additions & 2 deletions apps/server/src/provider/model-manifest.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,58 @@
{
"version": 1,
"updatedAt": "2026-09-22T21:40:00Z",
"updatedAt": "2026-09-24T00:11:29Z",
"compatibility": [
{
"driver": "codex",
"t3CodeRange": ">=0.0.42",
"recommendedRange": ">=0.129.0",
"ranges": [
{ "range": ">=0.129.0", "status": "supported" },
{ "range": "<0.129.0", "status": "broken" }
]
},
{
"driver": "claudeAgent",
"t3CodeRange": ">=0.0.42",
"recommendedRange": ">=2.1.280",
"ranges": [
{ "range": ">=2.1.280", "status": "supported" },
{ "range": ">=2.1.111 <2.1.280", "status": "graceful" },
{ "range": "<2.1.111", "status": "unsupported" }
]
},
{
"driver": "cursor",
"t3CodeRange": ">=0.0.42",
"recommendedRange": ">=2026.05.09",
"ranges": [
{ "range": ">=2026.05.09", "status": "supported" },
{ "range": "<2026.05.09", "status": "unknown" }
]
},
{
"driver": "grok",
"t3CodeRange": ">=0.0.42",
"recommendedRange": ">=1.0.13",
"ranges": [
{ "range": ">=1.0.13", "status": "supported" },
{ "range": "<1.0.13", "status": "unknown" }
]
},
{
"driver": "opencode",
"t3CodeRange": ">=0.0.42",
"recommendedRange": ">=1.14.19",
"ranges": [{ "range": "<1.14.19", "status": "broken" }]
"ranges": [
{ "range": ">=1.14.19", "status": "supported" },
{ "range": "<1.14.19", "status": "broken" }
]
},
{
"driver": "antigravity",
"t3CodeRange": ">=0.0.42",
"recommendedRange": "=1.1.1",
"ranges": [{ "range": "=1.1.1", "status": "supported" }]
}
],
"currentModels": {
Expand Down
63 changes: 63 additions & 0 deletions apps/server/src/provider/providerCompatibility.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ProviderRegistry } from "./Services/ProviderRegistry.ts";
import { ProviderInstanceRegistry } from "./Services/ProviderInstanceRegistry.ts";
import type { ProviderInstance } from "./ProviderDriver.ts";
import { makeManualOnlyProviderMaintenanceCapabilities } from "./providerMaintenance.ts";
import { BUILT_IN_DRIVERS } from "./builtInDrivers.ts";
import * as Schema from "effect/Schema";
import {
applyProviderCompatibility,
Expand Down Expand Up @@ -51,6 +52,68 @@ const provider: ServerProvider = {
};

describe("provider compatibility", () => {
it("bundles a compatibility policy for every built-in harness", () => {
for (const builtIn of BUILT_IN_DRIVERS) {
assert.isDefined(
resolveProviderCompatibility(
ModelManifest.BUNDLED_MODEL_MANIFEST.compatibility,
builtIn.driverKind,
null,
),
`Missing bundled compatibility policy for ${builtIn.driverKind}`,
);
}
});

it("compares Cursor build dates without treating semver prereleases as stable", () => {
const cursor = ProviderDriverKind.make("cursor");
const cursorPolicy: ProviderCompatibilityPolicy = {
driver: cursor,
t3CodeRange: policy.t3CodeRange,
ranges: [
{ range: "<2026.05.09", status: "unsupported" },
{ range: ">=2026.05.09", status: "supported" },
],
};
for (const [version, expected] of [
["2026.05.08-a1b2c3d", "unsupported"],
["2026.05.09-a1b2c3d", "supported"],
["2026.09.22-f2b0fcd", "supported"],
["2026.05.09", "supported"],
["2026.05.09-beta.1", "unknown"],
] as const) {
assert.strictEqual(
resolveProviderCompatibility([cursorPolicy], cursor, version)?.status,
expected,
);
}
assert.strictEqual(
resolveProviderCompatibility([policy], driver, "2.0.0-a1b2c3d")?.status,
"unknown",
);
});

it("recognizes Antigravity semver release tags while keeping dated candidates unknown", () => {
const antigravity = ProviderDriverKind.make("antigravity");
const taggedPolicy = {
...policy,
driver: antigravity,
ranges: [{ range: "=2.0.0", status: "supported" as const }],
};
for (const [version, expected] of [
["agy_acp_server_2.0.0", "supported"],
["2.0.0", "supported"],
["agy_acp_server_2.0.1", "unknown"],
["agy_acp_server_2.0.0-beta.1", "unknown"],
["agy_acp_server_20260818_01_RC01", "unknown"],
] as const) {
assert.strictEqual(
resolveProviderCompatibility([taggedPolicy], antigravity, version)?.status,
expected,
);
}
});

it("classifies boundaries and treats unlisted versions and release tags as unknown", () => {
for (const [version, expected] of [
["0.9.9", "broken"],
Expand Down
12 changes: 10 additions & 2 deletions apps/server/src/provider/providerCompatibility.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import * as Schema from "effect/Schema";
import packageJson from "../../package.json" with { type: "json" };

// Deliberately uses the shared CLI gate syntax: comparator groups joined by ||.
// Release tags and prereleases remain unknown instead of matching stable ranges.
// Prereleases and unrecognized release tags remain unknown.
const StableVersion = TrimmedNonEmptyString.pipe(
Schema.check(Schema.makeFilter((value) => /^\d+\.\d+\.\d+$/.test(value))),
);
Expand Down Expand Up @@ -66,7 +66,15 @@ export function resolveProviderCompatibility(
(entry) => entry.driver === driver && satisfiesSemverRange(t3CodeVersion, entry.t3CodeRange),
);
if (!policy) return undefined;
const stable = version?.replace(/^v/, "");
const unprefixed = version?.replace(/^v/, "");
// Cursor appends a build hash to its date; Google's ACP runtime uses a release prefix.
// Strip only these driver-specific forms, keeping semver prereleases unknown.
const stable =
driver === "cursor"
? unprefixed?.replace(/^(\d{4}\.\d{2}\.\d{2})-[a-f0-9]+$/, "$1")
: driver === "antigravity"
? unprefixed?.replace(/^agy_acp_server_(\d+\.\d+\.\d+)$/, "$1")
: unprefixed;
const status =
stable && /^\d+\.\d+\.\d+$/.test(stable)
? (policy.ranges.find((entry) => satisfiesSemverRange(stable, entry.range))?.status ??
Expand Down
8 changes: 7 additions & 1 deletion apps/server/src/provider/providerMaintenanceRunner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,13 @@ function makeRegistry(

const makeTestRunner = (
registry: ProviderRegistryShape,
manifest = ModelManifest.BUNDLED_MODEL_MANIFEST,
// Generic updater fixtures use synthetic versions. Keep their compatibility
// unknown so real harness minimums do not bypass the command under test.
manifest: ModelManifest.ModelManifestData = {
version: 1,
currentModels: {},
compatibility: [{ driver: CODEX_DRIVER, t3CodeRange: ">=0.0.42", ranges: [] }],
},
) =>
Effect.service(ProviderMaintenanceRunner.ProviderMaintenanceRunner).pipe(
Effect.provide(
Expand Down
Loading