@polpo-ai/llm 0.5.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OpenPolpo Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,28 @@
1
+ /**
2
+ * API key resolution for LLM providers.
3
+ *
4
+ * Resolves API keys from environment variables using the canonical
5
+ * PROVIDER_ENV_MAP from @polpo-ai/core.
6
+ */
7
+ export { PROVIDER_ENV_MAP } from "@polpo-ai/core";
8
+ /**
9
+ * Resolve API key for a provider (synchronous).
10
+ * Reads from process.env using the PROVIDER_ENV_MAP.
11
+ */
12
+ export declare function resolveApiKey(provider: string): string | undefined;
13
+ /**
14
+ * Resolve API key for a provider (async, full resolution chain).
15
+ * Priority: 1) polpo.json overrides (if they had apiKey), 2) env var lookup, 3) stored OAuth profiles.
16
+ *
17
+ * Returns the API key from env vars or provider config.
18
+ */
19
+ export declare function resolveApiKeyAsync(provider: string): Promise<string | undefined>;
20
+ /**
21
+ * Check if there are any stored OAuth profiles for a provider (synchronous).
22
+ * Used by the sync validation path so OAuth-based providers (openai-codex,
23
+ * github-copilot, anthropic, etc.) aren't rejected before spawn.
24
+ *
25
+ * Reads auth-profiles.json directly to stay synchronous in ESM context.
26
+ */
27
+ export declare function hasOAuthProfiles(provider: string): boolean;
28
+ //# sourceMappingURL=api-keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.d.ts","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGlD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAIlE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAEtF;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAa1D"}
@@ -0,0 +1,54 @@
1
+ /**
2
+ * API key resolution for LLM providers.
3
+ *
4
+ * Resolves API keys from environment variables using the canonical
5
+ * PROVIDER_ENV_MAP from @polpo-ai/core.
6
+ */
7
+ import { existsSync, readFileSync } from "node:fs";
8
+ import { join } from "node:path";
9
+ import { homedir } from "node:os";
10
+ // Re-export the canonical env map from @polpo-ai/core.
11
+ export { PROVIDER_ENV_MAP } from "@polpo-ai/core";
12
+ import { PROVIDER_ENV_MAP } from "@polpo-ai/core";
13
+ /**
14
+ * Resolve API key for a provider (synchronous).
15
+ * Reads from process.env using the PROVIDER_ENV_MAP.
16
+ */
17
+ export function resolveApiKey(provider) {
18
+ const envVar = PROVIDER_ENV_MAP[provider];
19
+ if (!envVar)
20
+ return undefined;
21
+ return process.env[envVar] || undefined;
22
+ }
23
+ /**
24
+ * Resolve API key for a provider (async, full resolution chain).
25
+ * Priority: 1) polpo.json overrides (if they had apiKey), 2) env var lookup, 3) stored OAuth profiles.
26
+ *
27
+ * Returns the API key from env vars or provider config.
28
+ */
29
+ export async function resolveApiKeyAsync(provider) {
30
+ return resolveApiKey(provider);
31
+ }
32
+ /**
33
+ * Check if there are any stored OAuth profiles for a provider (synchronous).
34
+ * Used by the sync validation path so OAuth-based providers (openai-codex,
35
+ * github-copilot, anthropic, etc.) aren't rejected before spawn.
36
+ *
37
+ * Reads auth-profiles.json directly to stay synchronous in ESM context.
38
+ */
39
+ export function hasOAuthProfiles(provider) {
40
+ try {
41
+ const globalPolpoDir = join(homedir(), ".polpo");
42
+ const profilePath = join(globalPolpoDir, "auth-profiles.json");
43
+ if (!existsSync(profilePath))
44
+ return false;
45
+ const data = JSON.parse(readFileSync(profilePath, "utf-8"));
46
+ if (!data?.profiles)
47
+ return false;
48
+ return Object.values(data.profiles).some((p) => p.provider === provider);
49
+ }
50
+ catch {
51
+ return false;
52
+ }
53
+ }
54
+ //# sourceMappingURL=api-keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-keys.js","sourceRoot":"","sources":["../src/api-keys.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,uDAAuD;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,MAAM,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;AAC1C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,QAAgB;IACvD,OAAO,aAAa,CAAC,QAAQ,CAAC,CAAC;AACjC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;QAC/D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,IAAI,EAAE,QAAQ;YAAE,OAAO,KAAK,CAAC;QAClC,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CACtC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CACpC,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Provider cooldown / failback logic.
3
+ *
4
+ * Tracks provider-level errors and applies exponential backoff cooldowns
5
+ * to avoid hammering failing providers.
6
+ */
7
+ /**
8
+ * Check if a provider is currently in cooldown.
9
+ */
10
+ export declare function isProviderInCooldown(provider: string): boolean;
11
+ /**
12
+ * Mark a provider as temporarily unavailable (cooldown).
13
+ */
14
+ export declare function markProviderCooldown(provider: string, reason?: string): void;
15
+ /**
16
+ * Clear cooldown for a provider (e.g. after successful call).
17
+ */
18
+ export declare function clearProviderCooldown(provider: string): void;
19
+ /**
20
+ * Get current cooldown state for all providers.
21
+ */
22
+ export declare function getProviderCooldowns(): Record<string, {
23
+ until: number;
24
+ errorCount: number;
25
+ reason?: string;
26
+ }>;
27
+ /**
28
+ * Classify an error to determine if it should trigger cooldown or failover.
29
+ */
30
+ export declare function classifyProviderError(err: unknown): {
31
+ shouldCooldown: boolean;
32
+ shouldFailover: boolean;
33
+ reason: string;
34
+ };
35
+ //# sourceMappingURL=cooldown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cooldown.d.ts","sourceRoot":"","sources":["../src/cooldown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAQ9D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAW5E;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAE5D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAAC,MAAM,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAQ7G;AAID;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG;IACnD,cAAc,EAAE,OAAO,CAAC;IACxB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;CAChB,CA4CA"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Provider cooldown / failback logic.
3
+ *
4
+ * Tracks provider-level errors and applies exponential backoff cooldowns
5
+ * to avoid hammering failing providers.
6
+ */
7
+ // ─── State ───────────────────────────────────────────
8
+ const providerCooldowns = new Map();
9
+ const COOLDOWN_STEPS = [60_000, 300_000, 1_500_000, 3_600_000]; // 1m, 5m, 25m, 1h
10
+ // ─── Cooldown Management ─────────────────────────────
11
+ /**
12
+ * Check if a provider is currently in cooldown.
13
+ */
14
+ export function isProviderInCooldown(provider) {
15
+ const entry = providerCooldowns.get(provider);
16
+ if (!entry)
17
+ return false;
18
+ if (Date.now() >= entry.until) {
19
+ providerCooldowns.delete(provider);
20
+ return false;
21
+ }
22
+ return true;
23
+ }
24
+ /**
25
+ * Mark a provider as temporarily unavailable (cooldown).
26
+ */
27
+ export function markProviderCooldown(provider, reason) {
28
+ const existing = providerCooldowns.get(provider);
29
+ const errorCount = (existing?.errorCount ?? 0) + 1;
30
+ const stepIdx = Math.min(errorCount - 1, COOLDOWN_STEPS.length - 1);
31
+ const cooldownMs = COOLDOWN_STEPS[stepIdx];
32
+ providerCooldowns.set(provider, {
33
+ until: Date.now() + cooldownMs,
34
+ errorCount,
35
+ reason,
36
+ });
37
+ }
38
+ /**
39
+ * Clear cooldown for a provider (e.g. after successful call).
40
+ */
41
+ export function clearProviderCooldown(provider) {
42
+ providerCooldowns.delete(provider);
43
+ }
44
+ /**
45
+ * Get current cooldown state for all providers.
46
+ */
47
+ export function getProviderCooldowns() {
48
+ const result = {};
49
+ for (const [provider, entry] of providerCooldowns) {
50
+ if (Date.now() < entry.until) {
51
+ result[provider] = { ...entry };
52
+ }
53
+ }
54
+ return result;
55
+ }
56
+ // ─── Error Classification ────────────────────────────
57
+ /**
58
+ * Classify an error to determine if it should trigger cooldown or failover.
59
+ */
60
+ export function classifyProviderError(err) {
61
+ if (!(err instanceof Error)) {
62
+ return { shouldCooldown: false, shouldFailover: false, reason: "unknown" };
63
+ }
64
+ const msg = err.message.toLowerCase();
65
+ // Auth errors — cooldown + failover
66
+ if (msg.includes("401") || msg.includes("unauthorized") || msg.includes("invalid api key") ||
67
+ msg.includes("authentication") || msg.includes("forbidden") || msg.includes("403")) {
68
+ return { shouldCooldown: true, shouldFailover: true, reason: "auth" };
69
+ }
70
+ // Rate limit — cooldown + failover
71
+ if (msg.includes("429") || msg.includes("rate limit") || msg.includes("too many requests") ||
72
+ msg.includes("quota exceeded")) {
73
+ return { shouldCooldown: true, shouldFailover: true, reason: "rate_limit" };
74
+ }
75
+ // Billing — long cooldown + failover
76
+ if (msg.includes("insufficient") || msg.includes("credit") || msg.includes("billing") ||
77
+ msg.includes("payment required") || msg.includes("402")) {
78
+ return { shouldCooldown: true, shouldFailover: true, reason: "billing" };
79
+ }
80
+ // Server errors — short cooldown, failover
81
+ if (msg.includes("500") || msg.includes("502") || msg.includes("503") || msg.includes("504") ||
82
+ msg.includes("overloaded") || msg.includes("service unavailable")) {
83
+ return { shouldCooldown: true, shouldFailover: true, reason: "server_error" };
84
+ }
85
+ // Transient network — no cooldown, retry
86
+ if (msg.includes("timeout") || msg.includes("econnreset") || msg.includes("econnrefused") ||
87
+ msg.includes("socket hang up")) {
88
+ return { shouldCooldown: false, shouldFailover: false, reason: "network" };
89
+ }
90
+ // Non-retryable errors (bad request, invalid model, etc.)
91
+ if (msg.includes("400") || msg.includes("invalid") || msg.includes("not found") ||
92
+ msg.includes("404")) {
93
+ return { shouldCooldown: false, shouldFailover: false, reason: "client_error" };
94
+ }
95
+ return { shouldCooldown: false, shouldFailover: false, reason: "unknown" };
96
+ }
97
+ //# sourceMappingURL=cooldown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cooldown.js","sourceRoot":"","sources":["../src/cooldown.ts"],"names":[],"mappings":"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"}
package/dist/cost.d.ts ADDED
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Cost estimation for LLM calls.
3
+ *
4
+ * Calculates cost from AI SDK usage data and model pricing metadata.
5
+ */
6
+ import type { LanguageModelUsage } from "ai";
7
+ import type { ResolvedModel } from "./model-resolver.js";
8
+ export type { LanguageModelUsage };
9
+ export interface CostEstimate {
10
+ inputCost: number;
11
+ outputCost: number;
12
+ cacheReadCost: number;
13
+ cacheWriteCost: number;
14
+ totalCost: number;
15
+ currency: string;
16
+ }
17
+ /**
18
+ * Calculate the cost of an LLM call from AI SDK usage data.
19
+ * Uses pricing from the resolved model metadata.
20
+ * Returns cost in USD.
21
+ */
22
+ export declare function estimateCost(model: ResolvedModel, usage: LanguageModelUsage): CostEstimate;
23
+ //# sourceMappingURL=cost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,IAAI,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAIzD,YAAY,EAAE,kBAAkB,EAAE,CAAC;AAInC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,kBAAkB,GAAG,YAAY,CAoB1F"}
package/dist/cost.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Cost estimation for LLM calls.
3
+ *
4
+ * Calculates cost from AI SDK usage data and model pricing metadata.
5
+ */
6
+ // ─── Cost Calculation ────────────────────────────────
7
+ /**
8
+ * Calculate the cost of an LLM call from AI SDK usage data.
9
+ * Uses pricing from the resolved model metadata.
10
+ * Returns cost in USD.
11
+ */
12
+ export function estimateCost(model, usage) {
13
+ const inputTokens = usage.inputTokens ?? 0;
14
+ const outputTokens = usage.outputTokens ?? 0;
15
+ const cacheReadTokens = usage.inputTokenDetails?.cacheReadTokens ?? 0;
16
+ const cacheWriteTokens = usage.inputTokenDetails?.cacheWriteTokens ?? 0;
17
+ // Cost per token (pricing is per-token from gateway)
18
+ const inputCost = inputTokens * model.cost.input;
19
+ const outputCost = outputTokens * model.cost.output;
20
+ const cacheReadCost = cacheReadTokens * model.cost.cacheRead;
21
+ const cacheWriteCost = cacheWriteTokens * model.cost.cacheWrite;
22
+ return {
23
+ inputCost,
24
+ outputCost,
25
+ cacheReadCost,
26
+ cacheWriteCost,
27
+ totalCost: inputCost + outputCost + cacheReadCost + cacheWriteCost,
28
+ currency: "USD",
29
+ };
30
+ }
31
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAoBH,wDAAwD;AAExD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAoB,EAAE,KAAyB;IAC1E,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,IAAI,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;IAC7C,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,EAAE,eAAe,IAAI,CAAC,CAAC;IACtE,MAAM,gBAAgB,GAAG,KAAK,CAAC,iBAAiB,EAAE,gBAAgB,IAAI,CAAC,CAAC;IAExE,qDAAqD;IACrD,MAAM,SAAS,GAAG,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;IACjD,MAAM,UAAU,GAAG,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;IACpD,MAAM,aAAa,GAAG,eAAe,GAAG,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC;IAC7D,MAAM,cAAc,GAAG,gBAAgB,GAAG,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC;IAEhE,OAAO;QACL,SAAS;QACT,UAAU;QACV,aAAa;QACb,cAAc;QACd,SAAS,EAAE,SAAS,GAAG,UAAU,GAAG,aAAa,GAAG,cAAc;QAClE,QAAQ,EAAE,KAAK;KAChB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * AI Gateway model catalog — fetching, caching, and querying.
3
+ *
4
+ * Uses the public AI Gateway endpoint to list available models and pricing.
5
+ * The catalog is fetched lazily and cached for 1 hour.
6
+ */
7
+ import type { GatewayLanguageModelEntry } from "@ai-sdk/gateway";
8
+ export type { GatewayLanguageModelEntry };
9
+ /**
10
+ * Fetch and cache the AI Gateway model catalog.
11
+ * Uses the public endpoint (no auth required for listing).
12
+ */
13
+ export declare function fetchCatalog(): Promise<GatewayLanguageModelEntry[]>;
14
+ /**
15
+ * Get the cached catalog synchronously (returns empty array if not yet fetched).
16
+ * Triggers a background fetch if cache is stale.
17
+ */
18
+ export declare function getCatalogSync(): GatewayLanguageModelEntry[];
19
+ export interface ModelInfo {
20
+ id: string;
21
+ name: string;
22
+ provider: string;
23
+ reasoning: boolean;
24
+ input: string[];
25
+ contextWindow: number;
26
+ maxTokens: number;
27
+ cost: {
28
+ input: number;
29
+ output: number;
30
+ cacheRead: number;
31
+ cacheWrite: number;
32
+ };
33
+ }
34
+ //# sourceMappingURL=gateway-catalog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-catalog.d.ts","sourceRoot":"","sources":["../src/gateway-catalog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AAIjE,YAAY,EAAE,yBAAyB,EAAE,CAAC;AAS1C;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,yBAAyB,EAAE,CAAC,CA6BzE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,yBAAyB,EAAE,CAO5D;AAID,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;CAChF"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * AI Gateway model catalog — fetching, caching, and querying.
3
+ *
4
+ * Uses the public AI Gateway endpoint to list available models and pricing.
5
+ * The catalog is fetched lazily and cached for 1 hour.
6
+ */
7
+ // ─── Cached gateway catalog ──────────────────────────
8
+ let catalogCache = null;
9
+ let catalogFetchPromise = null;
10
+ let catalogFetchedAt = 0;
11
+ const CATALOG_TTL_MS = 60 * 60 * 1000; // 1 hour
12
+ /**
13
+ * Fetch and cache the AI Gateway model catalog.
14
+ * Uses the public endpoint (no auth required for listing).
15
+ */
16
+ export async function fetchCatalog() {
17
+ const now = Date.now();
18
+ if (catalogCache && now - catalogFetchedAt < CATALOG_TTL_MS) {
19
+ return catalogCache;
20
+ }
21
+ if (catalogFetchPromise && now - catalogFetchedAt < CATALOG_TTL_MS) {
22
+ return catalogFetchPromise;
23
+ }
24
+ catalogFetchPromise = (async () => {
25
+ try {
26
+ const resp = await fetch("https://ai-gateway.vercel.sh/v1/models");
27
+ if (!resp.ok) {
28
+ throw new Error(`Gateway catalog fetch failed: ${resp.status}`);
29
+ }
30
+ const data = (await resp.json());
31
+ const models = data.data ?? [];
32
+ catalogCache = models;
33
+ catalogFetchedAt = Date.now();
34
+ return models;
35
+ }
36
+ catch (err) {
37
+ // On failure, return stale cache if available
38
+ if (catalogCache)
39
+ return catalogCache;
40
+ throw err;
41
+ }
42
+ })();
43
+ return catalogFetchPromise;
44
+ }
45
+ /**
46
+ * Get the cached catalog synchronously (returns empty array if not yet fetched).
47
+ * Triggers a background fetch if cache is stale.
48
+ */
49
+ export function getCatalogSync() {
50
+ const now = Date.now();
51
+ if (!catalogCache || now - catalogFetchedAt > CATALOG_TTL_MS) {
52
+ // Trigger background refresh — don't block
53
+ fetchCatalog().catch(() => { });
54
+ }
55
+ return catalogCache ?? [];
56
+ }
57
+ //# sourceMappingURL=gateway-catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gateway-catalog.js","sourceRoot":"","sources":["../src/gateway-catalog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wDAAwD;AAExD,IAAI,YAAY,GAAuC,IAAI,CAAC;AAC5D,IAAI,mBAAmB,GAAgD,IAAI,CAAC;AAC5E,IAAI,gBAAgB,GAAG,CAAC,CAAC;AACzB,MAAM,cAAc,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,SAAS;AAEhD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,YAAY,IAAI,GAAG,GAAG,gBAAgB,GAAG,cAAc,EAAE,CAAC;QAC5D,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,IAAI,mBAAmB,IAAI,GAAG,GAAG,gBAAgB,GAAG,cAAc,EAAE,CAAC;QACnE,OAAO,mBAAmB,CAAC;IAC7B,CAAC;IAED,mBAAmB,GAAG,CAAC,KAAK,IAAI,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,wCAAwC,CAAC,CAAC;YACnE,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,iCAAiC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAClE,CAAC;YACD,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAA2C,CAAC;YAC3E,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC;YAC/B,YAAY,GAAG,MAAM,CAAC;YACtB,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAC9B,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,8CAA8C;YAC9C,IAAI,YAAY;gBAAE,OAAO,YAAY,CAAC;YACtC,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,IAAI,CAAC,YAAY,IAAI,GAAG,GAAG,gBAAgB,GAAG,cAAc,EAAE,CAAC;QAC7D,2CAA2C;QAC3C,YAAY,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,YAAY,IAAI,EAAE,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @polpo-ai/llm — Multi-provider LLM abstraction built on Vercel AI SDK + AI Gateway.
3
+ *
4
+ * Provides model resolution, streaming, cost tracking, provider cooldown/failover,
5
+ * and API key resolution for all major LLM providers.
6
+ */
7
+ export { fetchCatalog, getCatalogSync, } from "./gateway-catalog.js";
8
+ export type { GatewayLanguageModelEntry, ModelInfo } from "./gateway-catalog.js";
9
+ export { parseModelSpec, resolveModel, resolveModelSpec, resolveModelWithFallback, resolveModelWithFallbackAsync, getModelInfo, listProviders, listModels, buildModelListingForPrompt, setProviderOverrides, getProviderOverrides, setModelAllowlist, getModelAllowlist, isModelAllowed, enforceModelAllowlist, validateProviderKeys, validateProviderKeysDetailed, } from "./model-resolver.js";
10
+ export type { ResolvedModel, ParsedModelSpec, ProviderValidationResult } from "./model-resolver.js";
11
+ export { createCustomProviderModel, createGatewayModel, mapReasoningToProviderOptions, buildStreamOpts, } from "./provider-factory.js";
12
+ export { resolveApiKey, resolveApiKeyAsync, hasOAuthProfiles, PROVIDER_ENV_MAP, } from "./api-keys.js";
13
+ export { estimateCost } from "./cost.js";
14
+ export type { CostEstimate, LanguageModelUsage } from "./cost.js";
15
+ export { isProviderInCooldown, markProviderCooldown, clearProviderCooldown, getProviderCooldowns, classifyProviderError, } from "./cooldown.js";
16
+ export { queryText, queryStream, queryTextWithFallback, } from "./query.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EACL,YAAY,EACZ,cAAc,GACf,MAAM,sBAAsB,CAAC;AAC9B,YAAY,EAAE,yBAAyB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGjF,OAAO,EAEL,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,6BAA6B,EAC7B,YAAY,EAEZ,aAAa,EACb,UAAU,EACV,0BAA0B,EAE1B,oBAAoB,EACpB,oBAAoB,EAEpB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,qBAAqB,EAErB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAC7B,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAC;AAGpG,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,6BAA6B,EAC7B,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAGvB,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,YAAY,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAGlE,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAGvB,OAAO,EACL,SAAS,EACT,WAAW,EACX,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @polpo-ai/llm — Multi-provider LLM abstraction built on Vercel AI SDK + AI Gateway.
3
+ *
4
+ * Provides model resolution, streaming, cost tracking, provider cooldown/failover,
5
+ * and API key resolution for all major LLM providers.
6
+ */
7
+ // ─── Gateway Catalog ─���───────────────────────────────
8
+ export { fetchCatalog, getCatalogSync, } from "./gateway-catalog.js";
9
+ // ─── Model Resolution ────────────────────────────────
10
+ export {
11
+ // Core resolution
12
+ parseModelSpec, resolveModel, resolveModelSpec, resolveModelWithFallback, resolveModelWithFallbackAsync, getModelInfo,
13
+ // Catalog listing (uses resolver state)
14
+ listProviders, listModels, buildModelListingForPrompt,
15
+ // Provider overrides
16
+ setProviderOverrides, getProviderOverrides,
17
+ // Model allowlist
18
+ setModelAllowlist, getModelAllowlist, isModelAllowed, enforceModelAllowlist,
19
+ // Provider validation
20
+ validateProviderKeys, validateProviderKeysDetailed, } from "./model-resolver.js";
21
+ // ─── Provider Factory ──────���─────────────────────────
22
+ export { createCustomProviderModel, createGatewayModel, mapReasoningToProviderOptions, buildStreamOpts, } from "./provider-factory.js";
23
+ // ─── API Keys ────────────────────────────────────────
24
+ export { resolveApiKey, resolveApiKeyAsync, hasOAuthProfiles, PROVIDER_ENV_MAP, } from "./api-keys.js";
25
+ // ─── Cost ─���──────────────────────────────────────────
26
+ export { estimateCost } from "./cost.js";
27
+ // ─── Cooldown ────────────────────────────────────────
28
+ export { isProviderInCooldown, markProviderCooldown, clearProviderCooldown, getProviderCooldowns, classifyProviderError, } from "./cooldown.js";
29
+ // ─── Query Functions ──────────���──────────────────────
30
+ export { queryText, queryStream, queryTextWithFallback, } from "./query.js";
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,0DAA0D;AAC1D,OAAO,EACL,YAAY,EACZ,cAAc,GACf,MAAM,sBAAsB,CAAC;AAG9B,wDAAwD;AACxD,OAAO;AACL,kBAAkB;AAClB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,wBAAwB,EACxB,6BAA6B,EAC7B,YAAY;AACZ,wCAAwC;AACxC,aAAa,EACb,UAAU,EACV,0BAA0B;AAC1B,qBAAqB;AACrB,oBAAoB,EACpB,oBAAoB;AACpB,kBAAkB;AAClB,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,qBAAqB;AACrB,sBAAsB;AACtB,oBAAoB,EACpB,4BAA4B,GAC7B,MAAM,qBAAqB,CAAC;AAG7B,0DAA0D;AAC1D,OAAO,EACL,yBAAyB,EACzB,kBAAkB,EAClB,6BAA6B,EAC7B,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAE/B,wDAAwD;AACxD,OAAO,EACL,aAAa,EACb,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,eAAe,CAAC;AAEvB,0DAA0D;AAC1D,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,wDAAwD;AACxD,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AAEvB,0DAA0D;AAC1D,OAAO,EACL,SAAS,EACT,WAAW,EACX,qBAAqB,GACtB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Model resolution — resolves model specs to AI SDK LanguageModel instances
3
+ * with full metadata. Handles provider overrides, model allowlists,
4
+ * fallback chains, and provider key validation.
5
+ */
6
+ import type { LanguageModel } from "ai";
7
+ import type { ProviderConfig, ModelConfig, ModelAllowlistEntry } from "@polpo-ai/core";
8
+ export type { ParsedModelSpec } from "@polpo-ai/core";
9
+ import { type ModelInfo } from "./gateway-catalog.js";
10
+ /**
11
+ * A resolved model: metadata (from gateway catalog or custom provider config)
12
+ * plus an AI SDK LanguageModel instance ready for generateText/streamText.
13
+ */
14
+ export interface ResolvedModel {
15
+ /** Model identifier (e.g. "claude-sonnet-4.5"). */
16
+ id: string;
17
+ /** Human-readable name. */
18
+ name: string;
19
+ /** Provider name (e.g. "anthropic", "openai"). */
20
+ provider: string;
21
+ /** Whether the model supports reasoning/thinking. */
22
+ reasoning: boolean;
23
+ /** Supported input modalities. */
24
+ input: string[];
25
+ /** Context window size in tokens. */
26
+ contextWindow: number;
27
+ /** Max output tokens. */
28
+ maxTokens: number;
29
+ /** Cost per token (in USD). */
30
+ cost: {
31
+ input: number;
32
+ output: number;
33
+ cacheRead: number;
34
+ cacheWrite: number;
35
+ };
36
+ /** The AI SDK model instance to pass to generateText/streamText. */
37
+ aiModel: LanguageModel;
38
+ }
39
+ export declare function setProviderOverrides(overrides: Record<string, ProviderConfig>): void;
40
+ export declare function getProviderOverrides(): Record<string, ProviderConfig>;
41
+ export declare function setModelAllowlist(allowlist: Record<string, ModelAllowlistEntry> | undefined): void;
42
+ export declare function getModelAllowlist(): Record<string, ModelAllowlistEntry> | undefined;
43
+ /**
44
+ * Check if a model spec is allowed by the allowlist.
45
+ * Returns true if no allowlist is set (everything allowed) or the model is in the list.
46
+ */
47
+ export declare function isModelAllowed(spec: string): boolean;
48
+ /**
49
+ * Enforce model allowlist. Throws if the model is not allowed.
50
+ */
51
+ export declare function enforceModelAllowlist(spec: string): void;
52
+ /**
53
+ * Parse a model spec string into provider + modelId.
54
+ * Falls back to POLPO_MODEL env var. Throws if no model is available.
55
+ */
56
+ export declare function parseModelSpec(spec?: string): {
57
+ provider: string;
58
+ modelId: string;
59
+ };
60
+ /**
61
+ * Resolve a model spec to a ResolvedModel with metadata + AI SDK model instance.
62
+ *
63
+ * Resolution order:
64
+ * 1. If provider has an override with custom baseUrl -> create OpenAI-compatible model
65
+ * 2. Otherwise -> use AI Gateway (provider/modelId format)
66
+ *
67
+ * This ensures custom providers (Ollama, vLLM, etc.) work without being in the gateway.
68
+ */
69
+ export declare function resolveModel(spec?: string): ResolvedModel;
70
+ /**
71
+ * Get detailed model info for a specific model spec.
72
+ */
73
+ export declare function getModelInfo(spec: string): ModelInfo | undefined;
74
+ /**
75
+ * List all available providers from the AI Gateway catalog.
76
+ * Returns synchronously from the cache; triggers background refresh if stale.
77
+ */
78
+ export declare function listProviders(): string[];
79
+ /**
80
+ * List all models for a given provider (or all providers if none specified).
81
+ */
82
+ export declare function listModels(provider?: string): ModelInfo[];
83
+ /**
84
+ * Build a dynamic model listing string for system prompts.
85
+ * Uses the gateway catalog instead of hardcoded lists.
86
+ */
87
+ export declare function buildModelListingForPrompt(): string;
88
+ /**
89
+ * Normalize a model spec that may be string or ModelConfig into a plain string.
90
+ * Useful for APIs that only accept a string model spec.
91
+ */
92
+ export declare function resolveModelSpec(spec: string | ModelConfig | undefined): string | undefined;
93
+ /**
94
+ * Resolve a model from a fallback chain (synchronous).
95
+ * Tries primary first, then each fallback in order.
96
+ * Returns the first model that has a valid API key.
97
+ */
98
+ export declare function resolveModelWithFallback(config: ModelConfig): {
99
+ model: ResolvedModel;
100
+ spec: string;
101
+ };
102
+ /**
103
+ * Resolve a model from a fallback chain (async).
104
+ * Tries primary first, then each fallback in order.
105
+ * Checks the FULL API key resolution chain including OAuth profiles with auto-refresh.
106
+ */
107
+ export declare function resolveModelWithFallbackAsync(config: ModelConfig): Promise<{
108
+ model: ResolvedModel;
109
+ spec: string;
110
+ }>;
111
+ export interface ProviderValidationResult {
112
+ provider: string;
113
+ modelSpec: string;
114
+ hasKey: boolean;
115
+ envVar?: string;
116
+ }
117
+ /**
118
+ * Validate that all required providers have API keys available.
119
+ * Returns detailed validation results for all model specs.
120
+ */
121
+ export declare function validateProviderKeys(modelSpecs: string[]): {
122
+ provider: string;
123
+ modelSpec: string;
124
+ }[];
125
+ /**
126
+ * Get detailed validation for a set of model specs — including which env var to set.
127
+ */
128
+ export declare function validateProviderKeysDetailed(modelSpecs: string[]): ProviderValidationResult[];
129
+ //# sourceMappingURL=model-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-resolver.d.ts","sourceRoot":"","sources":["../src/model-resolver.ts"],"names":[],"mappings":"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"}