From 6f45258b2149dbc54640c02e88459fe57e9b0be3 Mon Sep 17 00:00:00 2001 From: xieqian0816 <260077733+xieqian0816@users.noreply.github.com> Date: Mon, 10 Aug 2026 17:29:46 +0800 Subject: [PATCH] fix: make custom providers usable in web UI --- .../custom-provider-onboarding-ready.png | Bin 0 -> 135790 bytes docs/pr-evidence/custom-provider-web-flow.md | 34 ++++++++++++++++ docs/pr-evidence/custom-provider-web-turn.png | Bin 0 -> 42975 bytes plugins/admin/public/index.html | 28 ++++++++++--- plugins/admin/test/onboarding-view.test.ts | 29 +++++++++++++ plugins/web-ui/src/core-bridge.ts | 5 ++- plugins/web-ui/src/model-options.ts | 16 ++++++-- plugins/web-ui/src/pi-models.ts | 21 +++++++++- plugins/web-ui/test/model-options.test.ts | 22 ++++++++++ plugins/web-ui/test/pi-models.test.ts | 16 ++++++++ src/api/app-turn.ts | 14 +++---- src/api/routes/admin/model-providers.ts | 10 ++++- src/api/routes/surface.ts | 38 +++++++++++++----- src/index.ts | 2 + src/model/custom-providers.ts | 18 ++++++++- src/model/model-catalog.ts | 3 ++ test/custom-provider-route.test.ts | 37 ++++++++++++++++- test/custom-providers.test.ts | 11 ++++- test/model-credential-route.test.ts | 33 +++++++++++++++ 19 files changed, 303 insertions(+), 34 deletions(-) create mode 100644 docs/pr-evidence/custom-provider-onboarding-ready.png create mode 100644 docs/pr-evidence/custom-provider-web-flow.md create mode 100644 docs/pr-evidence/custom-provider-web-turn.png diff --git a/docs/pr-evidence/custom-provider-onboarding-ready.png b/docs/pr-evidence/custom-provider-onboarding-ready.png new file mode 100644 index 0000000000000000000000000000000000000000..9700bedb7ee93af029c840fe75ceacbf3ec54e8e GIT binary patch literal 135790 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 BFtPvu literal 0 HcmV?d00001 diff --git a/docs/pr-evidence/custom-provider-web-flow.md b/docs/pr-evidence/custom-provider-web-flow.md new file mode 100644 index 00000000..d97adf2b --- /dev/null +++ b/docs/pr-evidence/custom-provider-web-flow.md @@ -0,0 +1,34 @@ +# Custom Provider Web Flow + +## Reproduced failures + +A production-style local instance exposed four separate breaks in the same flow: + +1. `PUT /v1/admin/custom-providers/:id` returned `404` because the production entrypoint did not pass the custom-provider dependencies to the server. +2. A configured custom-provider key did not satisfy Portal or Admin readiness checks. +3. A custom model was rejected on Web turns unless the administrator explicitly saved a Web UI model allowlist. +4. The runtime config advertised the custom model, but the Web picker silently discarded it because the browser lacked its protocol metadata. + +## Automated verification + +- The production entrypoint is covered by a regression assertion for both required dependencies. +- Core route tests cover custom-provider readiness, status hygiene, runtime catalog metadata, and a Web turn without an explicit picker allowlist. +- Web UI tests cover generic OpenAI-compatible custom-model construction and selection. +- Admin tests cover custom-provider readiness, initial table loading, and readiness refresh after save/remove mutations. +- The full root suite passed once at 3,818 tests with 0 failures and 135 skipped. A later post-review run hit one unrelated OpenCode startup-output timing failure; that test passed immediately on an isolated rerun (10/10 OpenCode harness tests). +- Prettier, TypeScript, ESLint, and Oxlint checks pass. + +## Live DeepSeek verification + +The current branch was loaded through the repository's production-style dev supervisor and tested through Chrome against the saved `deepseek` provider. No credential is present in these artifacts. + +- Portal `/` returned the Web application instead of redirecting to onboarding. +- Admin reported `Ready`, identified `deepseek-v4-flash · custom provider key`, and listed the provider with a write-only key status. +- The Web picker displayed `DeepSeek V4 Flash` under the Pi harness without requiring an explicit model allowlist. +- Text turn: `DS_PR_TEXT_OK_20260810`. +- Tool turn: the model called `execute` with `pwd`; Admin recorded exit code `0`, the next model request contained the tool result `/root/workspace`, and the model returned `DS_PR_TOOL_OK`. +- Session: `4de03b0b-6ec4-426d-aa72-8fd066cf9246`. + +![Admin reports the custom provider as ready](custom-provider-onboarding-ready.png) + +![DeepSeek completes text and tool turns in the Web UI](custom-provider-web-turn.png) diff --git a/docs/pr-evidence/custom-provider-web-turn.png b/docs/pr-evidence/custom-provider-web-turn.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c18ba1378ecf66f4c847965bc3ba26bed0cfa5 GIT binary patch literal 42975 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 governance change let onboardingModels = {}; let onboardingModelStatuses = []; + let onboardingCustomProviderStatuses = []; function onboardingBadge(id, text, ready, optional = false) { const el = $(id); el.textContent = text; @@ -6998,6 +6999,15 @@

Confirm governance change

"" ); } + function onboardingModelStatus(modelId) { + const provider = onboardingProviderForModel(modelId); + const managed = onboardingModelStatuses.find((item) => item.provider === provider); + if (managed?.configured) return managed; + const custom = onboardingCustomProviderStatuses.find( + (item) => item.id === provider && !item.disabled && item.hasKey, + ); + return custom ? { provider, configured: true, source: "custom" } : managed; + } function renderOnboardingProviderOptions(preferred) { const select = $("onboarding-model-provider"); select.textContent = ""; @@ -7043,13 +7053,14 @@

Confirm governance change

return; } onboardingModelStatuses = models.data.providers || []; + onboardingCustomProviderStatuses = models.data.customProviders || []; onboardingModels = {}; (models.data.models || []).forEach((model) => { (onboardingModels[model.provider] ||= []).push(model); }); const baseModel = config.data.baseModel || config.data.baseModelDefault || ""; const baseProvider = onboardingProviderForModel(baseModel); - const baseStatus = onboardingModelStatuses.find((item) => item.provider === baseProvider); + const baseStatus = onboardingModelStatus(baseModel); onboardingBadge( "onboarding-model-badge", baseStatus?.configured ? "Ready" : "Needs a key", @@ -7058,7 +7069,13 @@

Confirm governance change

$("onboarding-model-summary").textContent = !baseModel ? "No base model is configured yet — pick a provider and model below." : baseStatus?.configured - ? baseModel + " · " + (baseStatus.source === "admin" ? "admin-managed key" : "deployment key") + ? baseModel + + " · " + + (baseStatus.source === "admin" + ? "admin-managed key" + : baseStatus.source === "custom" + ? "custom provider key" + : "deployment key") : baseModel + " cannot run until its " + (MODEL_PROVIDER_LABELS[baseProvider] || connectorName(baseProvider)) + @@ -7087,6 +7104,7 @@

Confirm governance change

$("onboarding-oauth-summary").textContent = configured.length ? configured.map((item) => connectorName(item.provider)).join(", ") + " available in the web UI." : "Add Google, GitHub, Notion, or other OAuth clients to make those connectors available."; + await loadCustomProviders(); viewLoadedAt.onboarding = Date.now(); } $("onboarding-model-provider").onchange = () => renderOnboardingModelOptions(); @@ -7110,7 +7128,6 @@

Confirm governance change

$("onboarding-model-save").disabled = false; $("onboarding-model-key").value = ""; await loadOnboarding(); - await loadCustomProviders(); setStatus( "st-onboarding-model", selected.ok ? "Key and base model saved." : "Key saved, but the base model could not be changed.", @@ -7132,7 +7149,6 @@

Confirm governance change

return; } await loadOnboarding(); - await loadCustomProviders(); setStatus("st-onboarding-model", "Provider disabled.", "ok"); }; let customProvidersLoaded = []; @@ -7196,7 +7212,7 @@

Confirm governance change

setStatus("st-custom-provider", removed.data?.message || "Could not remove this provider.", "err"); return; } - await loadCustomProviders(); + await loadOnboarding(); setStatus("st-custom-provider", "Provider removed.", "ok"); }; actions.appendChild(edit); @@ -7232,7 +7248,7 @@

Confirm governance change

return; } $("custom-provider-key").value = ""; - await loadCustomProviders(); + await loadOnboarding(); setStatus("st-custom-provider", "Provider saved. Its models are now in the picker.", "ok"); }; function openOnboardingTarget(target) { diff --git a/plugins/admin/test/onboarding-view.test.ts b/plugins/admin/test/onboarding-view.test.ts index c7fe9b4f..5dc77b6b 100644 --- a/plugins/admin/test/onboarding-view.test.ts +++ b/plugins/admin/test/onboarding-view.test.ts @@ -43,3 +43,32 @@ test("?view=onboarding resolves to the onboarding view", () => { test("unknown views still fall back to the default view", () => { assert.equal(resolveView("/admin/no-such-view", ""), "history"); }); + +test("a keyed custom provider makes its base model ready", () => { + const src = [ + slice("function onboardingProviderForModel(modelId) {", "function renderOnboardingProviderOptions"), + "onboardingModelStatus('acme-large');", + ].join("\n"); + const context = vm.createContext({ + onboardingModels: { "acme-gateway": [{ id: "acme-large", name: "Acme Large" }] }, + onboardingModelStatuses: [], + onboardingCustomProviderStatuses: [{ id: "acme-gateway", disabled: false, hasKey: true }], + }); + assert.deepEqual(JSON.parse(JSON.stringify(vm.runInContext(src, context))), { + provider: "acme-gateway", + configured: true, + source: "custom", + }); +}); + +test("onboarding loads the custom provider table on entry", () => { + assert.match( + slice("async function loadOnboarding() {", '$("onboarding-model-provider").onchange'), + /await loadCustomProviders\(\)/, + ); +}); + +test("custom provider mutations refresh onboarding readiness", () => { + const handlers = slice("async function loadCustomProviders() {", "function openOnboardingTarget"); + assert.equal(handlers.match(/await loadOnboarding\(\)/g)?.length, 2); +}); diff --git a/plugins/web-ui/src/core-bridge.ts b/plugins/web-ui/src/core-bridge.ts index a7cef34d..ec149677 100644 --- a/plugins/web-ui/src/core-bridge.ts +++ b/plugins/web-ui/src/core-bridge.ts @@ -473,7 +473,10 @@ export interface RuntimeConfig { scopeId: string; approvedHarnesses: string[]; modelsByHarness: Record; - modelCatalog: Record; + modelCatalog: Record< + string, + { name: string; provider: string; api?: Api; contextWindow?: number; maxTokens?: number } + >; orgDefault: { harnessId: string; modelId: string; effortLevel?: string; fastMode?: boolean; revision: number }; scopeOverride: { harnessId: string; diff --git a/plugins/web-ui/src/model-options.ts b/plugins/web-ui/src/model-options.ts index 5ee2c799..60d28de4 100644 --- a/plugins/web-ui/src/model-options.ts +++ b/plugins/web-ui/src/model-options.ts @@ -16,6 +16,14 @@ interface ModelMeta { buttonLabel: string; } +interface CatalogModel { + name: string; + provider: string; + api?: Api; + contextWindow?: number; + maxTokens?: number; +} + const MODEL_CATALOG: Record = { "claude-opus-5": { label: "Opus 5", @@ -78,7 +86,7 @@ function buildOption( id: string, harnessId = "pi", qualified = false, - catalog: Readonly> = {}, + catalog: Readonly> = {}, ): ModelOption | null { try { const dynamic = catalog[id]; @@ -101,7 +109,7 @@ function buildOptions( ids: readonly string[], harnessId = "pi", qualified = false, - catalog: Readonly> = {}, + catalog: Readonly> = {}, ): ModelOption[] { const seen = new Set(); const out: ModelOption[] = []; @@ -154,7 +162,7 @@ export function applyPickerModelIds(ids: readonly string[] | null | undefined, b export function runtimeModelOptions( approvedHarnesses: readonly string[], modelsByHarness: Readonly>, - catalog: Readonly> = {}, + catalog: Readonly> = {}, ): ModelOption[] { const options = approvedHarnesses.flatMap((harnessId) => { const configured = buildOptions(modelsByHarness[harnessId] ?? [], harnessId, true, catalog); @@ -170,7 +178,7 @@ export function applyRuntimeOptions( approvedHarnesses: readonly string[], modelsByHarness: Readonly>, effective: { harnessId: string; modelId: string }, - catalog: Readonly> = {}, + catalog: Readonly> = {}, ): void { const options = runtimeModelOptions(approvedHarnesses, modelsByHarness, catalog); const applied = { options, defaultValue: `${effective.harnessId}:${effective.modelId}` }; diff --git a/plugins/web-ui/src/pi-models.ts b/plugins/web-ui/src/pi-models.ts index ca2128a3..8328206e 100644 --- a/plugins/web-ui/src/pi-models.ts +++ b/plugins/web-ui/src/pi-models.ts @@ -13,6 +13,13 @@ const CLONE_TEMPLATES: Readonly; +type DynamicModel = { + name: string; + provider: string; + api?: Api; + contextWindow?: number; + maxTokens?: number; +}; function builtinModel(id: string): PiModel | undefined { for (const provider of KNOWN_PROVIDERS) { @@ -22,7 +29,7 @@ function builtinModel(id: string): PiModel | undefined { return undefined; } -export function getBaseModel(id: string, fallback?: { name: string; provider: string }): PiModel { +export function getBaseModel(id: string, fallback?: DynamicModel): PiModel { const builtin = builtinModel(id); if (builtin) return builtin; const clone = CLONE_TEMPLATES[id]; @@ -34,6 +41,18 @@ export function getBaseModel(id: string, fallback?: { name: string; provider: st const template = getModel("openrouter", "openrouter/auto" as Parameters[1]) as PiModel | undefined; if (template) return cloneModel(template, id, fallback.name); } + if (fallback?.api) { + const templateId = fallback.api === "anthropic-messages" ? "claude-opus-4-8" : "gpt-5.5"; + const template = builtinModel(templateId); + if (template) + return { + ...cloneModel(template, id, fallback.name), + provider: fallback.provider, + api: fallback.api, + ...(fallback.contextWindow ? { contextWindow: fallback.contextWindow } : {}), + ...(fallback.maxTokens ? { maxTokens: fallback.maxTokens } : {}), + }; + } throw new Error(`Unsupported model: ${id}`); } diff --git a/plugins/web-ui/test/model-options.test.ts b/plugins/web-ui/test/model-options.test.ts index 329b6453..02fa2580 100644 --- a/plugins/web-ui/test/model-options.test.ts +++ b/plugins/web-ui/test/model-options.test.ts @@ -96,6 +96,28 @@ test("runtime options preserve a fetched OpenRouter model as the selected web tu assert.equal(defaultModelValue(), "pi:anthropic/claude-sonnet-4.5"); }); +test("runtime options render and select a custom provider model", () => { + applyRuntimeOptions( + null, + ["pi"], + { pi: ["acme-large"] }, + { harnessId: "pi", modelId: "acme-large" }, + { + "acme-large": { + name: "Acme Large", + provider: "acme-gateway", + api: "openai-completions", + contextWindow: 128000, + maxTokens: 8192, + }, + }, + ); + const option = getModelOptions()[0]!; + assert.equal(option.value, "pi:acme-large"); + assert.equal(option.model.provider, "acme-gateway"); + assert.equal(defaultModelValue(), "pi:acme-large"); +}); + test("runtime options hide retired persisted model ids", () => { applyRuntimeOptions( null, diff --git a/plugins/web-ui/test/pi-models.test.ts b/plugins/web-ui/test/pi-models.test.ts index 8f586d46..b66891f5 100644 --- a/plugins/web-ui/test/pi-models.test.ts +++ b/plugins/web-ui/test/pi-models.test.ts @@ -30,6 +30,22 @@ test("models this pi-ai build lacks are cloned from a template of their own prov assert.equal(sol.provider, "openai", "an OpenAI model never resolves through an Anthropic template"); }); +test("custom provider models are materialized from protocol metadata", () => { + const model = getBaseModel("acme-large", { + name: "Acme Large", + provider: "acme-gateway", + api: "openai-completions", + contextWindow: 128000, + maxTokens: 8192, + }); + assert.equal(model.id, "acme-large"); + assert.equal(model.name, "Acme Large"); + assert.equal(model.provider, "acme-gateway"); + assert.equal(model.api, "openai-completions"); + assert.equal(model.contextWindow, 128000); + assert.equal(model.maxTokens, 8192); +}); + test("fast-mode support is fed from core's runtime config, not a hardcoded client copy", () => { setFastModeModelIds(null, []); assert.equal(modelSupportsFastMode(null, "claude-opus-4-8"), false); diff --git a/src/api/app-turn.ts b/src/api/app-turn.ts index 17d835f0..093a3ad6 100644 --- a/src/api/app-turn.ts +++ b/src/api/app-turn.ts @@ -13,7 +13,7 @@ import { modelProviderAvailabilityFor, modelServiceable, } from "../model/pi-models.ts"; -import { selectableCatalogForHarness, selectableModelCatalog } from "../model/model-catalog.ts"; +import { builtInModelCatalog, selectableCatalogForHarness, selectableModelCatalog } from "../model/model-catalog.ts"; import { resolveRuntimeChoiceDurable } from "../harness/harness-router.ts"; import { errMessage } from "../util/errors.ts"; @@ -170,16 +170,16 @@ export function createTurnMethods( }; } const configuredWebuiModels = await deps.config.getWebuiModelsDurable(org); - let enabledWebuiModels: string[] | null = null; + let enabledWebuiModels: string[]; if (configuredWebuiModels?.length) { enabledWebuiModels = [...new Set([...configuredWebuiModels, orgRuntime.modelId])]; - } else if (providers?.openrouter) { + } else { + const catalog = providers?.openrouter + ? await selectableModelCatalog(deps.modelCredentialFetch) + : builtInModelCatalog(); enabledWebuiModels = [ ...new Set([ - ...selectableCatalogForHarness( - await selectableModelCatalog(deps.modelCredentialFetch), - runtime.harnessId, - ).map((model) => model.id), + ...selectableCatalogForHarness(catalog, runtime.harnessId).map((model) => model.id), ...(orgRuntime.harnessId === runtime.harnessId ? [orgRuntime.modelId] : []), ]), ]; diff --git a/src/api/routes/admin/model-providers.ts b/src/api/routes/admin/model-providers.ts index a4380655..414597b7 100644 --- a/src/api/routes/admin/model-providers.ts +++ b/src/api/routes/admin/model-providers.ts @@ -58,9 +58,15 @@ export async function getModelProviders(ctx: ApiCtx): Promise { resource: "model-providers", scopeLabel: orgScope(ctx.deps), }); + const [providers, models, customProviders] = await Promise.all([ + ctx.deps.modelCredentials.statuses(), + selectableModelCatalog(ctx.deps.modelCredentialFetch), + ctx.deps.customProviders?.statuses() ?? [], + ]); return sendJson(ctx.res, 200, { - providers: await ctx.deps.modelCredentials.statuses(), - models: await selectableModelCatalog(ctx.deps.modelCredentialFetch), + providers, + models, + ...(ctx.deps.customProviders ? { customProviders } : {}), }); } diff --git a/src/api/routes/surface.ts b/src/api/routes/surface.ts index 3fbe270a..e88a9b1d 100644 --- a/src/api/routes/surface.ts +++ b/src/api/routes/surface.ts @@ -997,14 +997,16 @@ export async function shareArtifact(ctx: ApiCtx): Promise { async function getSurfaceConfig(ctx: ApiCtx): Promise { const { res, deps } = ctx; if (!deps.config) return sendJson(res, 404, { error: "not_found" }); - const [webuiModels, baseModel, externalSlackParticipants, branding] = await Promise.all([ - deps.config.getWebuiModelsDurable(orgScope(deps)), - deps.config.getBaseModelDurable(orgScope(deps)), - deps.config.getExternalSlackParticipantsDurable(orgScope(deps)), - deps.config.getBrandingDurable(orgScope(deps)), - ]); + const [webuiModels, baseModel, externalSlackParticipants, branding, managedKeys, customProviderStatuses] = + await Promise.all([ + deps.config.getWebuiModelsDurable(orgScope(deps)), + deps.config.getBaseModelDurable(orgScope(deps)), + deps.config.getExternalSlackParticipantsDurable(orgScope(deps)), + deps.config.getBrandingDurable(orgScope(deps)), + deps.modelCredentials?.availability() ?? null, + deps.customProviders?.statuses() ?? [], + ]); const harnessId = deps.harnessId ?? "pi"; - const managedKeys = deps.modelCredentials ? await deps.modelCredentials.availability() : null; const catalog = managedKeys?.openrouter ? await selectableModelCatalog(deps.modelCredentialFetch) : builtInModelCatalog(); @@ -1038,7 +1040,13 @@ async function getSurfaceConfig(ctx: ApiCtx): Promise { webuiModels: configuredPicker.length ? configuredPicker : allowed, baseModel: resolvedBase, harnessId, - ...(managedKeys ? { modelProviderConfigured: Object.values(managedKeys).some(Boolean) } : {}), + ...(managedKeys + ? { + modelProviderConfigured: + Object.values(managedKeys).some(Boolean) || + customProviderStatuses.some((provider) => !provider.disabled && provider.hasKey), + } + : {}), externalSlackParticipants, ...(Object.keys(resolvedBranding).length ? { branding: resolvedBranding } : {}), }); @@ -1165,7 +1173,19 @@ async function runtimeConfigBody(ctx: ApiCtx, scope: ScopeId): Promise { const model = catalog.find((candidate) => candidate.id === id); - if (model) return [[id, { name: model.name, provider: model.provider }]]; + if (model) + return [ + [ + id, + { + name: model.name, + provider: model.provider, + ...(model.api ? { api: model.api } : {}), + ...(model.contextWindow ? { contextWindow: model.contextWindow } : {}), + ...(model.maxTokens ? { maxTokens: model.maxTokens } : {}), + }, + ], + ]; const resolved = resolveModel(id); return resolved ? [[id, { name: resolved.name, provider: resolved.provider }]] : []; }), diff --git a/src/index.ts b/src/index.ts index fbd390c3..c3188894 100644 --- a/src/index.ts +++ b/src/index.ts @@ -33,6 +33,8 @@ const server = createServer(built.app, { modelProviders: modelProviderAvailabilityFor(config.harness, providerKeysPresent(config)), providerKeys: providerKeysPresent(config), modelCredentials: built.modelCredentials, + customProviders: built.customProviders, + refreshCustomProviders: built.refreshCustomProviders, ...(config.brandingDefault ? { brandingDefault: config.brandingDefault } : {}), harnessId: config.harness, connectorTokens: built.connectorTokens, diff --git a/src/model/custom-providers.ts b/src/model/custom-providers.ts index cb2a92c2..f98682fe 100644 --- a/src/model/custom-providers.ts +++ b/src/model/custom-providers.ts @@ -147,8 +147,22 @@ export function isCustomModelId(id: string): boolean { return registry.has(id); } -export function customModelCatalog(): Array<{ id: string; name: string; provider: string }> { - return [...registry.values()].map((m) => ({ id: m.id, name: m.name, provider: m.provider })); +export function customModelCatalog(): Array<{ + id: string; + name: string; + provider: string; + api: CustomRuntimeModel["api"]; + contextWindow: number; + maxTokens: number; +}> { + return [...registry.values()].map((m) => ({ + id: m.id, + name: m.name, + provider: m.provider, + api: m.api, + contextWindow: m.contextWindow, + maxTokens: m.maxTokens, + })); } /** diff --git a/src/model/model-catalog.ts b/src/model/model-catalog.ts index 77a26440..9927c069 100644 --- a/src/model/model-catalog.ts +++ b/src/model/model-catalog.ts @@ -6,6 +6,9 @@ export interface ModelCatalogEntry { name: string; /** A built-in provider or the slug of an admin-registered custom provider. */ provider: string; + api?: string; + contextWindow?: number; + maxTokens?: number; } const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models?supported_parameters=tools&sort=most-popular"; diff --git a/test/custom-provider-route.test.ts b/test/custom-provider-route.test.ts index 910bdd9e..0971b903 100644 --- a/test/custom-provider-route.test.ts +++ b/test/custom-provider-route.test.ts @@ -2,7 +2,7 @@ import "./support/auto-fake-sprites.ts"; import assert from "node:assert/strict"; import type { AddressInfo } from "node:net"; -import { mkdtempSync } from "node:fs"; +import { mkdtempSync, readFileSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { test, afterEach } from "node:test"; @@ -71,6 +71,35 @@ test("custom provider lifecycle: register, list, resolve, delete — admin only, assert.equal(putBody.status.hasKey, true); assert.equal(JSON.stringify(putBody).includes("sk-acme-secret"), false); + const surface = await fetch(`${srv.base}/v1/surface-config`); + assert.equal(surface.status, 200); + assert.equal(((await surface.json()) as { modelProviderConfigured?: boolean }).modelProviderConfigured, true); + + const providers = await fetch(`${srv.base}/v1/admin/model-providers`, { headers: ADMIN }); + assert.equal(providers.status, 200); + const providersBody = (await providers.json()) as { + customProviders: Array<{ id: string; disabled: boolean; hasKey: boolean }>; + }; + assert.deepEqual( + providersBody.customProviders.map(({ id, disabled, hasKey }) => ({ id, disabled, hasKey })), + [{ id: "acme-gateway", disabled: false, hasKey: true }], + ); + + const runtime = await fetch(`${srv.base}/v1/runtime-config?principalId=alice&scopeId=personal%3Aalice`); + assert.equal(runtime.status, 200); + const runtimeBody = (await runtime.json()) as { + modelsByHarness: Record; + modelCatalog: Record; + }; + assert.ok(runtimeBody.modelsByHarness.pi?.includes("acme-large")); + assert.deepEqual(runtimeBody.modelCatalog["acme-large"], { + name: "Acme Large", + provider: "acme-gateway", + api: "openai-completions", + contextWindow: 128000, + maxTokens: 8192, + }); + // The runtime registry serves the model immediately. assert.equal(String(resolveModel("acme-large")?.provider), "acme-gateway"); @@ -97,6 +126,12 @@ test("custom provider lifecycle: register, list, resolve, delete — admin only, } }); +test("production entrypoint wires custom provider routes into the core server", () => { + const entrypoint = readFileSync(new URL("../src/index.ts", import.meta.url), "utf8"); + assert.match(entrypoint, /customProviders:\s*built\.customProviders/); + assert.match(entrypoint, /refreshCustomProviders:\s*built\.refreshCustomProviders/); +}); + test("a rejected key blocks registration unless validate:false", async () => { const srv = start(async () => new Response(null, { status: 401 })); try { diff --git a/test/custom-providers.test.ts b/test/custom-providers.test.ts index 6621b64d..0dc1c415 100644 --- a/test/custom-providers.test.ts +++ b/test/custom-providers.test.ts @@ -74,7 +74,16 @@ test("a registered custom model is serviceable regardless of built-in key availa test("catalog lists custom models; clearing the registry removes them", () => { setCustomProviders([GATEWAY]); - assert.deepEqual(customModelCatalog(), [{ id: "acme-large", name: "Acme Large", provider: "acme-gateway" }]); + assert.deepEqual(customModelCatalog(), [ + { + id: "acme-large", + name: "Acme Large", + provider: "acme-gateway", + api: "openai-completions", + contextWindow: 200_000, + maxTokens: 16_000, + }, + ]); setCustomProviders([]); assert.equal(isCustomModelId("acme-large"), false); assert.equal(resolveModel("acme-large"), undefined); diff --git a/test/model-credential-route.test.ts b/test/model-credential-route.test.ts index e127025a..d05f3122 100644 --- a/test/model-credential-route.test.ts +++ b/test/model-credential-route.test.ts @@ -401,6 +401,39 @@ test("surface-config reports whether any model provider is configured", async () } }); +test("web turns allow a configured custom model without an explicit picker allowlist", async () => { + const srv = start({ harness: "pi" }); + try { + await srv.built.customProviders.upsert( + { + id: "acme-gateway", + name: "Acme Gateway", + protocol: "openai", + baseUrl: "https://llm.acme.internal/v1", + models: [{ id: "acme-large", name: "Acme Large" }], + }, + "sk-acme-secret", + "admin-alice@default-org", + ); + await srv.built.refreshCustomProviders(); + srv.built.config.setRuntimeSelection("org:default-org", { harnessId: "pi", modelId: "acme-large" }); + await srv.built.config.flushScope("org:default-org"); + + const result = await srv.built.app.turn({ + surface: "web", + actor: { externalId: "alice" }, + conversation: { kind: "dm", threadRef: "web:alice:custom-provider" }, + text: "hello", + harness: "pi", + model: "acme-large", + async: true, + }); + assert.equal(result.status, "queued"); + } finally { + await srv.close(); + } +}); + test("admin model credentials survive a second app instance on the same durable store", async () => { const backing = createMemoryMap(); const first = createModelCredentialStore({ backing, keyMaterial: "shared-model-key" });