@ponythewhite/base-context 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/NOTICE +0 -5
- package/README.md +44 -27
- package/dist/NOTICE +0 -5
- package/dist/base-context-runtime/pyproject.toml +1 -1
- package/dist/base-context-runtime/src/rlm/__init__.py +7 -5
- package/dist/base-context-runtime/test/test_subagent_registry.py +28 -1
- package/dist/base-context-runtime/uv.lock +1 -1
- package/dist/build-info.json +1 -1
- package/dist/bundle/amazon-bedrock.js +21 -0
- package/dist/bundle/{anthropic-YY4S534V.js → anthropic-UV5GZDGU.js} +5 -5
- package/dist/bundle/{azure-openai-responses-JRP6MIM3.js → azure-openai-responses-WSNPXLYC.js} +6 -6
- package/dist/bundle/{bundled-modules-P5HARVZA.js → bundled-modules-PWOGKUQQ.js} +71 -16
- package/dist/bundle/chunk-27QCJ2AZ.js +2578 -0
- package/dist/bundle/{chunk-BYVP7LWV.js → chunk-44PEHPOG.js} +1916 -4689
- package/dist/bundle/{chunk-MZHTNNVA.js → chunk-4GXPNXOJ.js} +8 -0
- package/dist/bundle/{chunk-SC5KG5R4.js → chunk-DGNX7HQ3.js} +1 -7
- package/dist/bundle/{chunk-A53O363M.js → chunk-GRJFXLBM.js} +0 -1
- package/dist/bundle/chunk-HKINIBP4.js +29 -0
- package/dist/bundle/{chunk-73DCPU3D.js → chunk-IADCPVEI.js} +1019 -3427
- package/dist/bundle/{chunk-UDSW6FNG.js → chunk-KTNETTHI.js} +1 -1
- package/dist/bundle/{chunk-U7AUVG3B.js → chunk-VSIYFWYI.js} +24 -6
- package/dist/bundle/{chunk-IW77OXFS.js → chunk-W46VZFI6.js} +0 -2099
- package/dist/bundle/{cli-main-O4X7GFGY.js → cli-main-4DS7Y3PI.js} +8 -6
- package/dist/bundle/cli.js +2 -2
- package/dist/bundle/{google-AUTVGDGZ.js → google-T32FMD4G.js} +6 -6
- package/dist/bundle/{google-vertex-Q75D7RKS.js → google-vertex-56KP6I3B.js} +3 -3
- package/dist/bundle/{main-XKOW2BV6.js → main-SV7JLVEB.js} +7 -5
- package/dist/bundle/{mistral-7ESB7QUD.js → mistral-WGBMYIVU.js} +5 -5
- package/dist/bundle/{openai-codex-responses-LV3QRPN4.js → openai-codex-responses-PIV2RQ3G.js} +6 -6
- package/dist/bundle/{openai-completions-OJECLPXJ.js → openai-completions-64C3JPR4.js} +11 -22
- package/dist/bundle/{openai-responses-FN6HZMBC.js → openai-responses-UI7RSTDV.js} +6 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +108 -59
- package/dist/cli/args.js.map +1 -1
- package/dist/cli/daemon-ps.d.ts +4 -3
- package/dist/cli/daemon-ps.d.ts.map +1 -1
- package/dist/cli/daemon-ps.js +6 -1
- package/dist/cli/daemon-ps.js.map +1 -1
- package/dist/cli/product-doctor.d.ts +0 -1
- package/dist/cli/product-doctor.d.ts.map +1 -1
- package/dist/cli/product-doctor.js +6 -3
- package/dist/cli/product-doctor.js.map +1 -1
- package/dist/config.d.ts +0 -3
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +0 -8
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-config.d.ts +1 -2
- package/dist/core/agent-session-config.d.ts.map +1 -1
- package/dist/core/agent-session-config.js +0 -3
- package/dist/core/agent-session-config.js.map +1 -1
- package/dist/core/agent-session-runtime.d.ts.map +1 -1
- package/dist/core/agent-session-runtime.js +5 -4
- package/dist/core/agent-session-runtime.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +5 -3
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +2 -27
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +10 -6
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +107 -107
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-storage.d.ts +8 -35
- package/dist/core/auth-storage.d.ts.map +1 -1
- package/dist/core/auth-storage.js +33 -243
- package/dist/core/auth-storage.js.map +1 -1
- package/dist/core/cron-jobs.d.ts.map +1 -1
- package/dist/core/cron-jobs.js +7 -1
- package/dist/core/cron-jobs.js.map +1 -1
- package/dist/core/inference-coordinator.d.ts +6 -1
- package/dist/core/inference-coordinator.d.ts.map +1 -1
- package/dist/core/inference-coordinator.js +18 -2
- package/dist/core/inference-coordinator.js.map +1 -1
- package/dist/core/kernel/bootstrap.d.ts.map +1 -1
- package/dist/core/kernel/bootstrap.js +2 -2
- package/dist/core/kernel/bootstrap.js.map +1 -1
- package/dist/core/kernel/repl-manager.d.ts +2 -0
- package/dist/core/kernel/repl-manager.d.ts.map +1 -1
- package/dist/core/kernel/repl-manager.js +44 -1
- package/dist/core/kernel/repl-manager.js.map +1 -1
- package/dist/core/logging.d.ts +4 -3
- package/dist/core/logging.d.ts.map +1 -1
- package/dist/core/logging.js +6 -6
- package/dist/core/logging.js.map +1 -1
- package/dist/core/mcp/mcp-manager.d.ts.map +1 -1
- package/dist/core/mcp/mcp-manager.js +3 -3
- package/dist/core/mcp/mcp-manager.js.map +1 -1
- package/dist/core/model-registry.d.ts +1 -16
- package/dist/core/model-registry.d.ts.map +1 -1
- package/dist/core/model-registry.js +88 -196
- package/dist/core/model-registry.js.map +1 -1
- package/dist/core/model-resolver.d.ts +2 -19
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +36 -266
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/provider-contracts.d.ts +5 -6
- package/dist/core/provider-contracts.d.ts.map +1 -1
- package/dist/core/provider-contracts.js +25 -36
- package/dist/core/provider-contracts.js.map +1 -1
- package/dist/core/provider-display-names.d.ts.map +1 -1
- package/dist/core/provider-display-names.js +0 -2
- package/dist/core/provider-display-names.js.map +1 -1
- package/dist/core/rlm-max-subagents.d.ts +32 -0
- package/dist/core/rlm-max-subagents.d.ts.map +1 -0
- package/dist/core/rlm-max-subagents.js +50 -0
- package/dist/core/rlm-max-subagents.js.map +1 -0
- package/dist/core/rlm-runtime.d.ts +3 -3
- package/dist/core/rlm-runtime.d.ts.map +1 -1
- package/dist/core/rlm-runtime.js.map +1 -1
- package/dist/core/sdk.d.ts +4 -3
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +27 -14
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager.d.ts +3 -16
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +12 -44
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +6 -6
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/installer.mjs +2 -3
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +39 -34
- package/dist/main.js.map +1 -1
- package/dist/modes/acp/acp-mode.d.ts.map +1 -1
- package/dist/modes/acp/acp-mode.js +1 -1
- package/dist/modes/acp/acp-mode.js.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.d.ts +6 -2
- package/dist/modes/agent-connection/daemon-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/daemon-agent-connection.js +13 -2
- package/dist/modes/agent-connection/daemon-agent-connection.js.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.d.ts +2 -0
- package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
- package/dist/modes/agent-connection/in-process-agent-connection.js +6 -0
- package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
- package/dist/modes/agent-connection/types.d.ts +3 -0
- package/dist/modes/agent-connection/types.d.ts.map +1 -1
- package/dist/modes/agent-connection/types.js.map +1 -1
- package/dist/modes/agents-view/agents-view-mode.d.ts.map +1 -1
- package/dist/modes/agents-view/agents-view-mode.js +2 -19
- package/dist/modes/agents-view/agents-view-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-mode.d.ts +5 -0
- package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-mode.js +107 -12
- package/dist/modes/daemon/daemon-mode.js.map +1 -1
- package/dist/modes/daemon/daemon-protocol.d.ts +194 -165
- package/dist/modes/daemon/daemon-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-protocol.js +16 -11
- package/dist/modes/daemon/daemon-protocol.js.map +1 -1
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts +19 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js +74 -0
- package/dist/modes/daemon/daemon-rlm-capacity-coordinator.js.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity.d.ts +19 -0
- package/dist/modes/daemon/daemon-rlm-capacity.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-rlm-capacity.js +85 -0
- package/dist/modes/daemon/daemon-rlm-capacity.js.map +1 -0
- package/dist/modes/daemon/daemon-session-summarizer.d.ts +2 -3
- package/dist/modes/daemon/daemon-session-summarizer.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-session-summarizer.js +32 -23
- package/dist/modes/daemon/daemon-session-summarizer.js.map +1 -1
- package/dist/modes/daemon/daemon-state-root.d.ts +15 -0
- package/dist/modes/daemon/daemon-state-root.d.ts.map +1 -0
- package/dist/modes/daemon/daemon-state-root.js +40 -0
- package/dist/modes/daemon/daemon-state-root.js.map +1 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.d.ts +2 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-supervisor-ownership.js +27 -0
- package/dist/modes/daemon/daemon-supervisor-ownership.js.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.d.ts +10 -1
- package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-supervisor.js +213 -20
- package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.d.ts +28 -1
- package/dist/modes/daemon/daemon-worker-protocol.d.ts.map +1 -1
- package/dist/modes/daemon/daemon-worker-protocol.js +16 -2
- package/dist/modes/daemon/daemon-worker-protocol.js.map +1 -1
- package/dist/modes/daemon/saved-session-catalog.d.ts.map +1 -1
- package/dist/modes/daemon/saved-session-catalog.js +2 -0
- package/dist/modes/daemon/saved-session-catalog.js.map +1 -1
- package/dist/modes/interactive/auth-flows.d.ts +0 -6
- package/dist/modes/interactive/auth-flows.d.ts.map +1 -1
- package/dist/modes/interactive/auth-flows.js +6 -126
- package/dist/modes/interactive/auth-flows.js.map +1 -1
- package/dist/modes/interactive/components/configuration-menu.d.ts +3 -0
- package/dist/modes/interactive/components/configuration-menu.d.ts.map +1 -1
- package/dist/modes/interactive/components/configuration-menu.js +13 -2
- package/dist/modes/interactive/components/configuration-menu.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +1 -1
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +2 -2
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -1
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -1
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/login-dialog.d.ts +0 -1
- package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
- package/dist/modes/interactive/components/login-dialog.js +3 -40
- package/dist/modes/interactive/components/login-dialog.js.map +1 -1
- package/dist/modes/interactive/components/model-selector.d.ts +2 -0
- package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/model-selector.js +13 -2
- package/dist/modes/interactive/components/model-selector.js.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/oauth-selector.js +2 -11
- package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
- package/dist/modes/interactive/feature-hints.d.ts.map +1 -1
- package/dist/modes/interactive/feature-hints.js +0 -4
- package/dist/modes/interactive/feature-hints.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +3 -12
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +81 -507
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/onboarding.d.ts +0 -3
- package/dist/modes/interactive/onboarding.d.ts.map +1 -1
- package/dist/modes/interactive/onboarding.js +0 -17
- package/dist/modes/interactive/onboarding.js.map +1 -1
- package/dist/modes/rpc/rpc-client.d.ts +4 -1
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js +82 -42
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/node/amazon-bedrock.d.ts +2 -0
- package/dist/node/amazon-bedrock.d.ts.map +1 -0
- package/dist/node/amazon-bedrock.js +6 -0
- package/dist/node/amazon-bedrock.js.map +1 -0
- package/dist/product-identity.d.ts +0 -1
- package/dist/product-identity.d.ts.map +1 -1
- package/dist/product-identity.js +0 -1
- package/dist/product-identity.js.map +1 -1
- package/docs/development.md +1 -1
- package/docs/fork-philosophy.md +4 -8
- package/docs/installation.md +83 -62
- package/docs/providers.md +23 -25
- package/docs/quickstart.md +19 -10
- package/docs/rlm-runtime.md +13 -5
- package/docs/rpc.md +4 -4
- package/docs/sdk.md +20 -11
- package/docs/sessions.md +0 -1
- package/docs/settings.md +9 -42
- package/docs/skills.md +0 -1
- package/docs/upstream-0.9.5.md +171 -0
- package/docs/usage.md +14 -10
- package/package.json +4 -4
- package/dist/core/agent-traces.d.ts +0 -149
- package/dist/core/agent-traces.d.ts.map +0 -1
- package/dist/core/agent-traces.js +0 -904
- package/dist/core/agent-traces.js.map +0 -1
- package/dist/core/prime-inference-auth.d.ts +0 -70
- package/dist/core/prime-inference-auth.d.ts.map +0 -1
- package/dist/core/prime-inference-auth.js +0 -352
- package/dist/core/prime-inference-auth.js.map +0 -1
- package/dist/core/prime-inference-model-selection.d.ts +0 -16
- package/dist/core/prime-inference-model-selection.d.ts.map +0 -1
- package/dist/core/prime-inference-model-selection.js +0 -16
- package/dist/core/prime-inference-model-selection.js.map +0 -1
- package/dist/core/prime-inference-models.d.ts +0 -6
- package/dist/core/prime-inference-models.d.ts.map +0 -1
- package/dist/core/prime-inference-models.js +0 -62
- package/dist/core/prime-inference-models.js.map +0 -1
- package/dist/core/telemetry.d.ts +0 -95
- package/dist/core/telemetry.d.ts.map +0 -1
- package/dist/core/telemetry.js +0 -637
- package/dist/core/telemetry.js.map +0 -1
- package/dist/modes/interactive/components/prime-onboarding-splash.d.ts +0 -39
- package/dist/modes/interactive/components/prime-onboarding-splash.d.ts.map +0 -1
- package/dist/modes/interactive/components/prime-onboarding-splash.js +0 -286
- package/dist/modes/interactive/components/prime-onboarding-splash.js.map +0 -1
- package/dist/modes/interactive/components/prime-team-selector.d.ts +0 -30
- package/dist/modes/interactive/components/prime-team-selector.d.ts.map +0 -1
- package/dist/modes/interactive/components/prime-team-selector.js +0 -166
- package/dist/modes/interactive/components/prime-team-selector.js.map +0 -1
- package/dist/skills/prime-intellect/SKILL.md +0 -87
- package/dist/skills/prime-intellect/references/compute.md +0 -45
- package/dist/skills/prime-intellect/references/environments.md +0 -73
- package/dist/skills/prime-intellect/references/inference.md +0 -47
- package/dist/skills/prime-intellect/references/sandboxes.md +0 -75
- package/skills/prime-intellect/SKILL.md +0 -87
- package/skills/prime-intellect/references/compute.md +0 -45
- package/skills/prime-intellect/references/environments.md +0 -73
- package/skills/prime-intellect/references/inference.md +0 -47
- package/skills/prime-intellect/references/sandboxes.md +0 -75
|
@@ -6,12 +6,10 @@ import { createHash } from "node:crypto";
|
|
|
6
6
|
import { getModels, getProviders, registerApiProvider, resetApiProviders, } from "@ponythewhite/base-context-ai";
|
|
7
7
|
import { registerBuiltinMcpOAuthProviders } from "@ponythewhite/base-context-ai/mcp";
|
|
8
8
|
import { getOAuthProvider, registerOAuthProvider, resetOAuthProviders } from "@ponythewhite/base-context-ai/oauth";
|
|
9
|
-
import { existsSync, readFileSync
|
|
10
|
-
import {
|
|
9
|
+
import { existsSync, readFileSync } from "fs";
|
|
10
|
+
import { join } from "path";
|
|
11
11
|
import { Type } from "typebox";
|
|
12
12
|
import { getAgentDir } from "../config.js";
|
|
13
|
-
import { PRIME_INFERENCE_PROVIDER_ID } from "./prime-inference-auth.js";
|
|
14
|
-
import { fetchAuthorizedPrivatePrimeInferenceModelIds, getPrivatePrimeInferenceModels, isPrivatePrimeInferenceModel, } from "./prime-inference-models.js";
|
|
15
13
|
import { getProviderAuthContract, isProviderApiKeyAllowed } from "./provider-contracts.js";
|
|
16
14
|
import { BUILT_IN_PROVIDER_DISPLAY_NAMES } from "./provider-display-names.js";
|
|
17
15
|
import { resolveConfigValueOrThrow, resolveConfigValueUncached, resolveHeadersOrThrow, } from "./resolve-config-value.js";
|
|
@@ -235,6 +233,55 @@ function applyModelOverride(model, override) {
|
|
|
235
233
|
result.compat = mergeCompat(model.compat, override.compat);
|
|
236
234
|
return result;
|
|
237
235
|
}
|
|
236
|
+
function isApiKeyOverriddenByHeaders(model, apiKey, headers) {
|
|
237
|
+
if (!headers)
|
|
238
|
+
return false;
|
|
239
|
+
let headerName;
|
|
240
|
+
let expectedValue = apiKey;
|
|
241
|
+
switch (model.api) {
|
|
242
|
+
case "openai-completions":
|
|
243
|
+
case "openai-responses":
|
|
244
|
+
expectedValue = `Bearer ${apiKey}`;
|
|
245
|
+
headerName = model.provider === "cloudflare-ai-gateway" ? "cf-aig-authorization" : "authorization";
|
|
246
|
+
if (model.provider === "cloudflare-ai-gateway") {
|
|
247
|
+
// These adapters set the gateway key after merging custom headers.
|
|
248
|
+
headers = { ...headers, "cf-aig-authorization": expectedValue };
|
|
249
|
+
}
|
|
250
|
+
break;
|
|
251
|
+
case "anthropic-messages":
|
|
252
|
+
headerName = model.provider === "cloudflare-ai-gateway" ? "cf-aig-authorization" : "x-api-key";
|
|
253
|
+
if (model.provider === "cloudflare-ai-gateway")
|
|
254
|
+
expectedValue = `Bearer ${apiKey}`;
|
|
255
|
+
else if (model.provider === "github-copilot" || apiKey.includes("sk-ant-oat")) {
|
|
256
|
+
headerName = "authorization";
|
|
257
|
+
expectedValue = `Bearer ${apiKey}`;
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
case "azure-openai-responses":
|
|
261
|
+
headerName = "api-key";
|
|
262
|
+
break;
|
|
263
|
+
case "google-generative-ai":
|
|
264
|
+
case "google-vertex":
|
|
265
|
+
headerName = "x-goog-api-key";
|
|
266
|
+
break;
|
|
267
|
+
case "mistral-conversations":
|
|
268
|
+
headerName = "authorization";
|
|
269
|
+
expectedValue = /^bearer /i.test(apiKey) ? apiKey : `Bearer ${apiKey}`;
|
|
270
|
+
break;
|
|
271
|
+
default:
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
// Google and Mistral append differently cased duplicates; Stainless SDKs use the last entry.
|
|
275
|
+
const values = Object.entries(headers)
|
|
276
|
+
.filter(([name]) => name.toLowerCase() === headerName)
|
|
277
|
+
.map(([, value]) => value.trim());
|
|
278
|
+
if (values.length === 0)
|
|
279
|
+
return false;
|
|
280
|
+
const actualValue = model.api === "google-generative-ai" || model.api === "google-vertex" || model.api === "mistral-conversations"
|
|
281
|
+
? values.join(", ")
|
|
282
|
+
: values.at(-1);
|
|
283
|
+
return actualValue !== expectedValue.trim();
|
|
284
|
+
}
|
|
238
285
|
function readOpenAICodexAccountId(token) {
|
|
239
286
|
try {
|
|
240
287
|
const payload = JSON.parse(Buffer.from(token.split(".")[1] ?? "", "base64url").toString("utf8"));
|
|
@@ -292,18 +339,6 @@ function readOpenAICodexModelIds(value) {
|
|
|
292
339
|
return [model.slug];
|
|
293
340
|
}));
|
|
294
341
|
}
|
|
295
|
-
const PRIVATE_PRIME_AUTHORIZATION_CACHE_FILE = "prime-inference-private-models.json";
|
|
296
|
-
const PRIVATE_PRIME_AUTHORIZATION_CACHE_TTL_MS = 5 * 60_000;
|
|
297
|
-
const PRIVATE_PRIME_BACKGROUND_REFRESH_TIMEOUT_MS = 3_000;
|
|
298
|
-
function privatePrimeAuthorizationFingerprint(apiKey, teamId) {
|
|
299
|
-
return createHash("sha256").update(apiKey).update("\0").update(teamId).digest("hex");
|
|
300
|
-
}
|
|
301
|
-
function isOfflineModeEnabled() {
|
|
302
|
-
const value = process.env.BASE_CONTEXT_OFFLINE;
|
|
303
|
-
if (!value)
|
|
304
|
-
return false;
|
|
305
|
-
return value === "1" || value.toLowerCase() === "true" || value.toLowerCase() === "yes";
|
|
306
|
-
}
|
|
307
342
|
/**
|
|
308
343
|
* Model registry - loads and manages models, resolves API keys via AuthStorage.
|
|
309
344
|
*/
|
|
@@ -316,11 +351,7 @@ export class ModelRegistry {
|
|
|
316
351
|
lastProviderAuthSourceTokens = new Map();
|
|
317
352
|
modelRequestHeaders = new Map();
|
|
318
353
|
registeredProviders = new Map();
|
|
319
|
-
authorizedPrivatePrimeInferenceModelIds = new Set();
|
|
320
|
-
authorizedPrivatePrimeInferenceTeamId;
|
|
321
|
-
explicitPrivatePrimeInferenceModelIds = new Set();
|
|
322
354
|
openAICodexModelsCache;
|
|
323
|
-
backgroundPrivatePrimeAuthorization;
|
|
324
355
|
loadError = undefined;
|
|
325
356
|
/** Re-register dynamic OAuth providers (e.g. user MCP servers) after refresh() resets the registry. */
|
|
326
357
|
onOAuthProvidersReset;
|
|
@@ -345,9 +376,6 @@ export class ModelRegistry {
|
|
|
345
376
|
this.providerRequestConfigs.clear();
|
|
346
377
|
this.modelRequestHeaders.clear();
|
|
347
378
|
this.lastProviderAuthSourceTokens.clear();
|
|
348
|
-
this.authorizedPrivatePrimeInferenceModelIds.clear();
|
|
349
|
-
this.authorizedPrivatePrimeInferenceTeamId = undefined;
|
|
350
|
-
this.explicitPrivatePrimeInferenceModelIds.clear();
|
|
351
379
|
this.loadError = undefined;
|
|
352
380
|
// Credentials may have been written by another process (e.g. the UI
|
|
353
381
|
// process saving a login while the session lives in the daemon).
|
|
@@ -379,9 +407,7 @@ export class ModelRegistry {
|
|
|
379
407
|
if (error) {
|
|
380
408
|
this.loadError = error;
|
|
381
409
|
}
|
|
382
|
-
|
|
383
|
-
const builtInModels = [...this.loadBuiltInModels(overrides, modelOverrides), ...getPrivatePrimeInferenceModels()];
|
|
384
|
-
let combined = this.mergeCustomModels(builtInModels, customModels);
|
|
410
|
+
let combined = this.mergeCustomModels(this.loadBuiltInModels(overrides, modelOverrides), customModels);
|
|
385
411
|
for (const oauthProvider of this.authStorage.getOAuthProviders()) {
|
|
386
412
|
const cred = this.authStorage.get(oauthProvider.id);
|
|
387
413
|
if (cred?.type === "oauth" && oauthProvider.modifyModels) {
|
|
@@ -580,176 +606,23 @@ export class ModelRegistry {
|
|
|
580
606
|
* This is a fast check that doesn't refresh OAuth tokens.
|
|
581
607
|
*/
|
|
582
608
|
getAvailable() {
|
|
583
|
-
return this.models.filter((model) =>
|
|
584
|
-
if (isPrivatePrimeInferenceModel(model) &&
|
|
585
|
-
!this.explicitPrivatePrimeInferenceModelIds.has(model.id) &&
|
|
586
|
-
!this.authorizedPrivatePrimeInferenceModelIds.has(model.id)) {
|
|
587
|
-
return false;
|
|
588
|
-
}
|
|
589
|
-
return this.hasConfiguredAuth(model);
|
|
590
|
-
});
|
|
609
|
+
return this.models.filter((model) => this.hasConfiguredAuth(model));
|
|
591
610
|
}
|
|
592
611
|
async refreshAvailableModels() {
|
|
593
|
-
const previousPrivateModelIds = new Set(this.authorizedPrivatePrimeInferenceModelIds);
|
|
594
|
-
const previousTeamId = this.authorizedPrivatePrimeInferenceTeamId;
|
|
595
612
|
this.refresh();
|
|
596
|
-
await this.refreshPrivatePrimeInferenceAuthorization(previousPrivateModelIds, previousTeamId);
|
|
597
613
|
return this.getAvailable();
|
|
598
614
|
}
|
|
599
|
-
async refreshPrivatePrimeInferenceAuthorization(previousPrivateModelIds = new Set(this.authorizedPrivatePrimeInferenceModelIds), previousTeamId = this.authorizedPrivatePrimeInferenceTeamId) {
|
|
600
|
-
const apiKey = await this.authStorage.getApiKey(PRIME_INFERENCE_PROVIDER_ID);
|
|
601
|
-
const teamHeaders = this.authStorage.getProviderHeaders(PRIME_INFERENCE_PROVIDER_ID);
|
|
602
|
-
const teamId = teamHeaders?.["X-Prime-Team-ID"];
|
|
603
|
-
if (!apiKey || !teamHeaders || !teamId) {
|
|
604
|
-
this.authorizedPrivatePrimeInferenceModelIds.clear();
|
|
605
|
-
this.authorizedPrivatePrimeInferenceTeamId = undefined;
|
|
606
|
-
return;
|
|
607
|
-
}
|
|
608
|
-
const fingerprint = privatePrimeAuthorizationFingerprint(apiKey, teamId);
|
|
609
|
-
const cached = this.readPrivatePrimeAuthorizationCache();
|
|
610
|
-
if (cached?.fingerprint === fingerprint) {
|
|
611
|
-
// Serve the persisted authorization decision so startup and model lists
|
|
612
|
-
// don't block on the network. A stale cache refreshes in the background
|
|
613
|
-
// and the updated ids apply to subsequent lookups in this process.
|
|
614
|
-
this.authorizedPrivatePrimeInferenceModelIds = new Set(cached.modelIds);
|
|
615
|
-
this.authorizedPrivatePrimeInferenceTeamId = teamId;
|
|
616
|
-
const cacheIsFresh = Date.now() - cached.refreshedAt < PRIVATE_PRIME_AUTHORIZATION_CACHE_TTL_MS;
|
|
617
|
-
if (cacheIsFresh || isOfflineModeEnabled()) {
|
|
618
|
-
return;
|
|
619
|
-
}
|
|
620
|
-
this.startBackgroundPrivatePrimeAuthorizationRefresh(apiKey, teamHeaders, teamId, fingerprint);
|
|
621
|
-
return;
|
|
622
|
-
}
|
|
623
|
-
if (isOfflineModeEnabled()) {
|
|
624
|
-
this.authorizedPrivatePrimeInferenceModelIds.clear();
|
|
625
|
-
this.authorizedPrivatePrimeInferenceTeamId = undefined;
|
|
626
|
-
return;
|
|
627
|
-
}
|
|
628
|
-
let authorizedIds;
|
|
629
|
-
try {
|
|
630
|
-
authorizedIds = await fetchAuthorizedPrivatePrimeInferenceModelIds(apiKey, teamHeaders);
|
|
631
|
-
}
|
|
632
|
-
catch {
|
|
633
|
-
// Fall back to the previous authorization below.
|
|
634
|
-
}
|
|
635
|
-
// Leave newer state untouched if the credentials changed while fetching.
|
|
636
|
-
if ((await this.currentPrivatePrimeAuthorizationFingerprint()) !== fingerprint) {
|
|
637
|
-
return;
|
|
638
|
-
}
|
|
639
|
-
if (authorizedIds) {
|
|
640
|
-
this.authorizedPrivatePrimeInferenceModelIds = authorizedIds;
|
|
641
|
-
this.authorizedPrivatePrimeInferenceTeamId = teamId;
|
|
642
|
-
this.writePrivatePrimeAuthorizationCache({ fingerprint, modelIds: authorizedIds, refreshedAt: Date.now() });
|
|
643
|
-
}
|
|
644
|
-
else if (teamId === previousTeamId) {
|
|
645
|
-
this.authorizedPrivatePrimeInferenceModelIds = previousPrivateModelIds;
|
|
646
|
-
this.authorizedPrivatePrimeInferenceTeamId = teamId;
|
|
647
|
-
}
|
|
648
|
-
else {
|
|
649
|
-
this.authorizedPrivatePrimeInferenceModelIds.clear();
|
|
650
|
-
this.authorizedPrivatePrimeInferenceTeamId = undefined;
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
/**
|
|
654
|
-
* Stale cache hits refresh in the background; failures keep the cached ids.
|
|
655
|
-
* Refreshes for the same credentials are deduped, a changed-credentials
|
|
656
|
-
* refresh is queued after the in-flight one, and a result is only applied
|
|
657
|
-
* if the credentials it was fetched with are still current.
|
|
658
|
-
*/
|
|
659
|
-
startBackgroundPrivatePrimeAuthorizationRefresh(apiKey, teamHeaders, teamId, fingerprint) {
|
|
660
|
-
if (this.backgroundPrivatePrimeAuthorization?.fingerprint === fingerprint) {
|
|
661
|
-
return;
|
|
662
|
-
}
|
|
663
|
-
const run = async () => {
|
|
664
|
-
try {
|
|
665
|
-
const authorizedIds = await fetchAuthorizedPrivatePrimeInferenceModelIds(apiKey, teamHeaders, undefined, PRIVATE_PRIME_BACKGROUND_REFRESH_TIMEOUT_MS);
|
|
666
|
-
if ((await this.currentPrivatePrimeAuthorizationFingerprint()) !== fingerprint) {
|
|
667
|
-
return;
|
|
668
|
-
}
|
|
669
|
-
this.authorizedPrivatePrimeInferenceModelIds = authorizedIds;
|
|
670
|
-
this.authorizedPrivatePrimeInferenceTeamId = teamId;
|
|
671
|
-
this.writePrivatePrimeAuthorizationCache({ fingerprint, modelIds: authorizedIds, refreshedAt: Date.now() });
|
|
672
|
-
}
|
|
673
|
-
catch {
|
|
674
|
-
// Keep the cached authorization.
|
|
675
|
-
}
|
|
676
|
-
};
|
|
677
|
-
const pending = this.backgroundPrivatePrimeAuthorization?.promise;
|
|
678
|
-
const promise = (pending ?? Promise.resolve()).then(run);
|
|
679
|
-
this.backgroundPrivatePrimeAuthorization = { fingerprint, promise };
|
|
680
|
-
void promise.finally(() => {
|
|
681
|
-
if (this.backgroundPrivatePrimeAuthorization?.promise === promise) {
|
|
682
|
-
this.backgroundPrivatePrimeAuthorization = undefined;
|
|
683
|
-
}
|
|
684
|
-
});
|
|
685
|
-
}
|
|
686
|
-
async currentPrivatePrimeAuthorizationFingerprint() {
|
|
687
|
-
const apiKey = await this.authStorage.getApiKey(PRIME_INFERENCE_PROVIDER_ID);
|
|
688
|
-
const teamId = this.authStorage.getProviderHeaders(PRIME_INFERENCE_PROVIDER_ID)?.["X-Prime-Team-ID"];
|
|
689
|
-
return apiKey && teamId ? privatePrimeAuthorizationFingerprint(apiKey, teamId) : undefined;
|
|
690
|
-
}
|
|
691
|
-
privatePrimeAuthorizationCachePath() {
|
|
692
|
-
if (!this.modelsJsonPath) {
|
|
693
|
-
return undefined;
|
|
694
|
-
}
|
|
695
|
-
return join(dirname(this.modelsJsonPath), PRIVATE_PRIME_AUTHORIZATION_CACHE_FILE);
|
|
696
|
-
}
|
|
697
|
-
readPrivatePrimeAuthorizationCache() {
|
|
698
|
-
const cachePath = this.privatePrimeAuthorizationCachePath();
|
|
699
|
-
if (!cachePath) {
|
|
700
|
-
return undefined;
|
|
701
|
-
}
|
|
702
|
-
try {
|
|
703
|
-
const parsed = JSON.parse(readFileSync(cachePath, "utf8"));
|
|
704
|
-
if (typeof parsed.fingerprint !== "string" ||
|
|
705
|
-
!Array.isArray(parsed.modelIds) ||
|
|
706
|
-
typeof parsed.refreshedAt !== "number") {
|
|
707
|
-
return undefined;
|
|
708
|
-
}
|
|
709
|
-
return {
|
|
710
|
-
fingerprint: parsed.fingerprint,
|
|
711
|
-
modelIds: new Set(parsed.modelIds),
|
|
712
|
-
refreshedAt: parsed.refreshedAt,
|
|
713
|
-
};
|
|
714
|
-
}
|
|
715
|
-
catch {
|
|
716
|
-
return undefined;
|
|
717
|
-
}
|
|
718
|
-
}
|
|
719
|
-
writePrivatePrimeAuthorizationCache(cache) {
|
|
720
|
-
const cachePath = this.privatePrimeAuthorizationCachePath();
|
|
721
|
-
if (!cachePath) {
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
try {
|
|
725
|
-
const tmpPath = `${cachePath}.${process.pid}.tmp`;
|
|
726
|
-
writeFileSync(tmpPath, JSON.stringify({ ...cache, modelIds: [...cache.modelIds] }), { mode: 0o600 });
|
|
727
|
-
renameSync(tmpPath, cachePath);
|
|
728
|
-
}
|
|
729
|
-
catch {
|
|
730
|
-
// A failed cache write only requires a later refetch.
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
615
|
async refreshModelCatalog() {
|
|
734
616
|
const availableModels = await this.refreshAvailableModels();
|
|
735
|
-
const availablePrivateModels = new Set(availableModels.filter(isPrivatePrimeInferenceModel).map((model) => `${model.provider}/${model.id}`));
|
|
736
617
|
return {
|
|
737
|
-
models: this.models
|
|
618
|
+
models: this.models,
|
|
738
619
|
configuredProviders: [...new Set(availableModels.map((model) => model.provider))],
|
|
739
620
|
};
|
|
740
621
|
}
|
|
741
622
|
async canUseModel(model) {
|
|
742
|
-
|
|
743
|
-
return false;
|
|
744
|
-
}
|
|
745
|
-
if (!isPrivatePrimeInferenceModel(model)) {
|
|
746
|
-
return true;
|
|
747
|
-
}
|
|
748
|
-
const availableModels = await this.refreshAvailableModels();
|
|
749
|
-
return availableModels.some((candidate) => candidate.provider === model.provider && candidate.id === model.id);
|
|
623
|
+
return this.hasConfiguredAuth(model);
|
|
750
624
|
}
|
|
751
625
|
async getExecutableModels() {
|
|
752
|
-
await this.refreshPrivatePrimeInferenceAuthorization();
|
|
753
626
|
const availableModels = this.getAvailable();
|
|
754
627
|
const codexModels = availableModels.filter((model) => model.provider === "openai-codex");
|
|
755
628
|
if (codexModels.length === 0) {
|
|
@@ -811,10 +684,13 @@ export class ModelRegistry {
|
|
|
811
684
|
].includes(model.baseUrl.replace(/\/+$/, "")));
|
|
812
685
|
}
|
|
813
686
|
hasConfiguredAuth(model) {
|
|
814
|
-
if (this.isExistingOpenAICodexSubscription(model))
|
|
815
|
-
return this.authStorage.hasAuth(model.provider);
|
|
816
|
-
|
|
817
|
-
|
|
687
|
+
if (this.authStorage.isExistingOpenAICodexSubscription(model.provider)) {
|
|
688
|
+
return this.isExistingOpenAICodexSubscription(model) && this.authStorage.hasAuth(model.provider);
|
|
689
|
+
}
|
|
690
|
+
if (!isProviderApiKeyAllowed(model.provider, "", model.api)) {
|
|
691
|
+
return this.isUsingOAuth(model) && this.authStorage.hasAuth(model.provider);
|
|
692
|
+
}
|
|
693
|
+
return this.authStorage.hasAuth(model.provider) || this.hasConfiguredProviderRequestAuth(model.provider);
|
|
818
694
|
}
|
|
819
695
|
fingerprintProviderRequestAuthSource(source, material) {
|
|
820
696
|
const digest = createHash("sha256").update(source).update("\0").update(material).digest("hex");
|
|
@@ -1020,6 +896,10 @@ export class ModelRegistry {
|
|
|
1020
896
|
*/
|
|
1021
897
|
async getApiKeyAndHeaders(model) {
|
|
1022
898
|
try {
|
|
899
|
+
if (this.authStorage.isExistingOpenAICodexSubscription(model.provider) &&
|
|
900
|
+
!this.isExistingOpenAICodexSubscription(model)) {
|
|
901
|
+
return { ok: false, error: "Existing OpenAI subscription requires the native Codex endpoint and API" };
|
|
902
|
+
}
|
|
1023
903
|
if (this.isExistingOpenAICodexSubscription(model)) {
|
|
1024
904
|
const config = this.providerRequestConfigs.get(model.provider);
|
|
1025
905
|
const modelHeaders = this.modelRequestHeaders.get(this.getModelRequestKey(model.provider, model.id));
|
|
@@ -1037,10 +917,16 @@ export class ModelRegistry {
|
|
|
1037
917
|
...resolveHeadersOrThrow(modelHeaders, `model "${model.provider}/${model.id}"`),
|
|
1038
918
|
};
|
|
1039
919
|
this.setLastProviderAuthSourceToken(model.provider, auth.sourceToken);
|
|
1040
|
-
return {
|
|
920
|
+
return {
|
|
921
|
+
ok: true,
|
|
922
|
+
apiKey: auth.apiKey,
|
|
923
|
+
sourceToken: auth.sourceToken,
|
|
924
|
+
headers: Object.keys(headers).length ? headers : undefined,
|
|
925
|
+
};
|
|
1041
926
|
}
|
|
1042
927
|
const contract = getProviderAuthContract(model.api === "openai-codex-responses" ? "openai-codex" : model.provider);
|
|
1043
|
-
|
|
928
|
+
const usingOAuth = this.isUsingOAuth(model);
|
|
929
|
+
if (!usingOAuth && !isProviderApiKeyAllowed(model.provider, "", model.api)) {
|
|
1044
930
|
return { ok: false, error: contract.guidance };
|
|
1045
931
|
}
|
|
1046
932
|
const providerConfig = this.providerRequestConfigs.get(model.provider);
|
|
@@ -1062,12 +948,10 @@ export class ModelRegistry {
|
|
|
1062
948
|
authSourceToken = this.getProviderRequestAuthSourceToken(model.provider, providerRequestAuthSource);
|
|
1063
949
|
}
|
|
1064
950
|
}
|
|
1065
|
-
this.setLastProviderAuthSourceToken(model.provider, apiKey === undefined ? undefined : authSourceToken);
|
|
1066
951
|
const providerHeaders = resolveHeadersOrThrow(providerConfig?.headers, `provider "${model.provider}"`);
|
|
1067
|
-
const authStorageHeaders = this.authStorage.getProviderHeaders(model.provider);
|
|
1068
952
|
const modelHeaders = resolveHeadersOrThrow(this.modelRequestHeaders.get(this.getModelRequestKey(model.provider, model.id)), `model "${model.provider}/${model.id}"`);
|
|
1069
|
-
let headers = model.headers ||
|
|
1070
|
-
? { ...model.headers, ...
|
|
953
|
+
let headers = model.headers || providerHeaders || modelHeaders
|
|
954
|
+
? { ...model.headers, ...providerHeaders, ...modelHeaders }
|
|
1071
955
|
: undefined;
|
|
1072
956
|
if (providerConfig?.authHeader) {
|
|
1073
957
|
if (!apiKey) {
|
|
@@ -1075,13 +959,17 @@ export class ModelRegistry {
|
|
|
1075
959
|
}
|
|
1076
960
|
headers = { ...headers, Authorization: `Bearer ${apiKey}` };
|
|
1077
961
|
}
|
|
1078
|
-
if (!isProviderApiKeyAllowed(model.provider, apiKey ?? "", model.api)
|
|
1079
|
-
Object.values(headers ?? {}).some((value) => !isProviderApiKeyAllowed(model.provider, value, model.api))) {
|
|
962
|
+
if (!usingOAuth && !isProviderApiKeyAllowed(model.provider, apiKey ?? "", model.api)) {
|
|
1080
963
|
return { ok: false, error: contract.guidance };
|
|
1081
964
|
}
|
|
965
|
+
if (apiKey === undefined || isApiKeyOverriddenByHeaders(model, apiKey, headers)) {
|
|
966
|
+
authSourceToken = undefined;
|
|
967
|
+
}
|
|
968
|
+
this.setLastProviderAuthSourceToken(model.provider, authSourceToken);
|
|
1082
969
|
return {
|
|
1083
970
|
ok: true,
|
|
1084
971
|
apiKey,
|
|
972
|
+
sourceToken: authSourceToken,
|
|
1085
973
|
headers: headers && Object.keys(headers).length > 0 ? headers : undefined,
|
|
1086
974
|
};
|
|
1087
975
|
}
|
|
@@ -1159,10 +1047,14 @@ export class ModelRegistry {
|
|
|
1159
1047
|
* Check if a model is using OAuth credentials (subscription).
|
|
1160
1048
|
*/
|
|
1161
1049
|
isUsingOAuth(model) {
|
|
1050
|
+
if (this.authStorage.isExistingOpenAICodexSubscription(model.provider) &&
|
|
1051
|
+
!this.isExistingOpenAICodexSubscription(model)) {
|
|
1052
|
+
return false;
|
|
1053
|
+
}
|
|
1162
1054
|
const cred = this.authStorage.get(model.provider);
|
|
1163
1055
|
return (cred?.type === "oauth" &&
|
|
1164
1056
|
(this.isExistingOpenAICodexSubscription(model) ||
|
|
1165
|
-
getProviderAuthContract(model.provider).oauth === "
|
|
1057
|
+
getProviderAuthContract(model.provider).oauth === "supported"));
|
|
1166
1058
|
}
|
|
1167
1059
|
/**
|
|
1168
1060
|
* Register a provider dynamically (from extensions).
|
|
@@ -1267,7 +1159,7 @@ export class ModelRegistry {
|
|
|
1267
1159
|
compat: modelDef.compat,
|
|
1268
1160
|
});
|
|
1269
1161
|
}
|
|
1270
|
-
if (config.oauth?.modifyModels && getProviderAuthContract(providerName).oauth === "
|
|
1162
|
+
if (config.oauth?.modifyModels && getProviderAuthContract(providerName).oauth === "supported") {
|
|
1271
1163
|
const cred = this.authStorage.get(providerName);
|
|
1272
1164
|
if (cred?.type === "oauth") {
|
|
1273
1165
|
this.models = config.oauth.modifyModels(this.models, cred);
|