fix(connectors): guard pi provider resolution
This commit is contained in:
1 parent
0d9f4f15eb
commit
7793f2da35
6 files changed
+107
-17
No files matched your search
@@ -23,6 +23,7 @@
|
||||
* - `connector-definitions/cloud.ts` — 3 Cloud providers
|
||||
*/
|
||||
|
||||
import type { KnownProvider } from "@mariozechner/pi-ai";
|
||||
import type { ConnectorId } from "@shared/types";
|
||||
import { OAUTH_CONNECTORS, API_KEY_CONNECTORS, CLOUD_CONNECTORS } from "./connector-definitions/index";
|
||||
|
||||
@@ -67,11 +68,14 @@ export type ConnectorAuth =
|
||||
| ConnectorAuthAzure
|
||||
| ConnectorAuthGcpAdc;
|
||||
|
||||
export type LocalModelResolverProvider = "fireworks" | "fireworks-firepass";
|
||||
export type ConnectorProvider = KnownProvider | LocalModelResolverProvider;
|
||||
|
||||
export interface ConnectorDefinition {
|
||||
/** Stable AgentCompany id; the `connectors` table primary key. */
|
||||
id: ConnectorId;
|
||||
/** pi-ai `KnownProvider` id (or a locally-resolved provider for Fireworks). */
|
||||
provider: string;
|
||||
provider: ConnectorProvider;
|
||||
/** Human-readable label for the Settings panel and onboarding rail. */
|
||||
label: string;
|
||||
/** One-line explanation shown under the label. */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getEnvApiKey } from "@mariozechner/pi-ai";
|
||||
import type { AppDatabase } from "./database";
|
||||
import { getConnectorDefinition, parseEnvBindingText } from "./connectors";
|
||||
import { getConnectorDefinition, isPiKnownProvider, parseEnvBindingText } from "./connectors";
|
||||
import type { ConnectorId } from "@shared/types";
|
||||
import type { CredentialStore } from "./credentials";
|
||||
|
||||
@@ -51,7 +51,7 @@ export function createConnectorHealthService({
|
||||
if (stored?.kind === "api_key") {
|
||||
return { status: "ready", authState: "ok", lastError: null };
|
||||
}
|
||||
if (definition.provider && getEnvApiKey(definition.provider as never)) {
|
||||
if (isPiKnownProvider(definition.provider) && getEnvApiKey(definition.provider)) {
|
||||
return { status: "ready", authState: "ok", lastError: null };
|
||||
}
|
||||
// Re-parse envBindingText on every probe: it is user-editable and must
|
||||
|
||||
+27
-3
@@ -1,8 +1,9 @@
|
||||
import type { CapabilityMatrix, ConnectorRecord } from "@shared/types";
|
||||
import { CONNECTORS, type ConnectorDefinition } from "./connector-definitions";
|
||||
import { getProviders, type KnownProvider } from "@mariozechner/pi-ai";
|
||||
import type { CapabilityMatrix, ConnectorId, ConnectorRecord } from "@shared/types";
|
||||
import { CONNECTORS, type ConnectorDefinition, type ConnectorProvider, type LocalModelResolverProvider } from "./connector-definitions";
|
||||
import { buildApiKeyDoc, buildCloudDoc, buildOAuthDoc } from "./connector-definitions-docs";
|
||||
export { CONNECTORS } from "./connector-definitions";
|
||||
export type { ConnectorDefinition } from "./connector-definitions";
|
||||
export type { ConnectorDefinition, ConnectorProvider, LocalModelResolverProvider } from "./connector-definitions";
|
||||
export { findConnectorDefinition, listFeaturedOnboardingConnectors } from "./connector-definitions-lookup";
|
||||
|
||||
const RESERVED_ENV_BINDING_KEYS = new Set([
|
||||
@@ -17,6 +18,12 @@ const RESERVED_ENV_BINDING_KEYS = new Set([
|
||||
"PWD",
|
||||
]);
|
||||
|
||||
const LOCAL_MODEL_RESOLVER_PROVIDERS: ReadonlySet<LocalModelResolverProvider> = new Set([
|
||||
"fireworks",
|
||||
"fireworks-firepass",
|
||||
]);
|
||||
const PI_KNOWN_PROVIDER_IDS: ReadonlySet<string> = new Set(getProviders());
|
||||
|
||||
/**
|
||||
* Pi-mono drives all provider dispatch through pi-ai, so the adapter-era
|
||||
* capability matrix now collapses to a uniform baseline. These values are
|
||||
@@ -39,6 +46,23 @@ export function getConnectorDefinition(id: string) {
|
||||
return definition;
|
||||
}
|
||||
|
||||
export function isPiKnownProvider(provider: string): provider is KnownProvider {
|
||||
return PI_KNOWN_PROVIDER_IDS.has(provider);
|
||||
}
|
||||
|
||||
export function isLocalModelResolverProvider(provider: string): provider is LocalModelResolverProvider {
|
||||
return LOCAL_MODEL_RESOLVER_PROVIDERS.has(provider as LocalModelResolverProvider);
|
||||
}
|
||||
|
||||
export function getConnectorProvider(id: ConnectorId): ConnectorProvider {
|
||||
return getConnectorDefinition(id).provider;
|
||||
}
|
||||
|
||||
export function getConnectorKnownProvider(id: ConnectorId): KnownProvider | null {
|
||||
const provider = getConnectorProvider(id);
|
||||
return isPiKnownProvider(provider) ? provider : null;
|
||||
}
|
||||
|
||||
export function parseEnvBindingText(text: string): Record<string, string> {
|
||||
const bindings: Record<string, string> = {};
|
||||
for (const rawLine of text.split(/\r?\n/)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { getOAuthProvider } from "@mariozechner/pi-ai/oauth";
|
||||
import { getEnvApiKey } from "@mariozechner/pi-ai";
|
||||
import { getConnectorDefinition } from "@main/connectors";
|
||||
import { getConnectorDefinition, isPiKnownProvider } from "@main/connectors";
|
||||
import { CredentialStore } from "./credential-store";
|
||||
import type { OAuthCredentialPayload, StoredCredentialPayload } from "./types";
|
||||
|
||||
@@ -72,14 +72,11 @@ export class CredentialResolver {
|
||||
if (!fromEnv) throw new CredentialError("CREDENTIAL_MISSING", connectorId, `Env var ${stored.value.value} is not set.`);
|
||||
return { apiKey: fromEnv };
|
||||
}
|
||||
if (!definition.provider) {
|
||||
throw new CredentialError("CREDENTIAL_MISSING", connectorId, `No credential or env API key for ${connectorId}.`);
|
||||
if (isPiKnownProvider(definition.provider)) {
|
||||
const envKey = getEnvApiKey(definition.provider);
|
||||
if (envKey) return { apiKey: envKey };
|
||||
}
|
||||
const envKey = getEnvApiKey(definition.provider as never);
|
||||
if (!envKey) {
|
||||
throw new CredentialError("CREDENTIAL_MISSING", connectorId, `No credential or env API key for ${connectorId}.`);
|
||||
}
|
||||
return { apiKey: envKey };
|
||||
throw new CredentialError("CREDENTIAL_MISSING", connectorId, `No credential or env API key for ${connectorId}.`);
|
||||
}
|
||||
case "azure": {
|
||||
if (stored?.kind !== "azure") {
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
*/
|
||||
|
||||
import log from "electron-log/main.js";
|
||||
import { getModel, getModels, type Api, type Model } from "@mariozechner/pi-ai";
|
||||
import { getModels, type Api, type Model } from "@mariozechner/pi-ai";
|
||||
import { isPiKnownProvider } from "./connectors";
|
||||
|
||||
// Fireworks' OpenAI-compatible root. The OpenAI SDK appends
|
||||
// `/chat/completions`, `/models`, etc. to this baseURL.
|
||||
@@ -67,8 +68,12 @@ export function resolveModel(provider: string, modelId: string): Model<Api> | nu
|
||||
const curated = FIREWORKS_CURATED_MODELS.find((entry) => entry.id === modelId);
|
||||
return buildFireworksModel(modelId, curated?.name, curated?.contextWindow);
|
||||
}
|
||||
if (!isPiKnownProvider(provider)) {
|
||||
log.warn(`[model-resolver] Unknown pi provider: ${provider}`);
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
return getModel(provider as never, modelId as never) ?? null;
|
||||
return getModels(provider).find((model) => model.id === modelId) ?? null;
|
||||
} catch (err) {
|
||||
log.warn(`[model-resolver] getModel failed for ${provider}/${modelId}:`, err instanceof Error ? err.message : String(err));
|
||||
return null;
|
||||
@@ -82,8 +87,12 @@ export function resolveModels(provider: string): Array<{ id: string; name: strin
|
||||
if (provider === "fireworks") {
|
||||
return FIREWORKS_CURATED_MODELS.map(({ id, name }) => ({ id, name }));
|
||||
}
|
||||
if (!isPiKnownProvider(provider)) {
|
||||
log.warn(`[model-resolver] Unknown pi provider: ${provider}`);
|
||||
return [];
|
||||
}
|
||||
try {
|
||||
const models = getModels(provider as never) ?? [];
|
||||
const models = getModels(provider);
|
||||
return models.map((model: { id: string; name?: string }) => ({ id: model.id, name: model.name ?? model.id }));
|
||||
} catch (err) {
|
||||
log.warn(`[model-resolver] getModels failed for ${provider}:`, err instanceof Error ? err.message : String(err));
|
||||
|
||||
Reference in new issue
Block a user