@sriinnu/kosha-discovery 0.6.1 → 1.0.0
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/README.md +53 -268
- package/dist/cli-cmd-model.d.ts +48 -0
- package/dist/cli-cmd-model.d.ts.map +1 -0
- package/dist/cli-cmd-model.js +231 -0
- package/dist/cli-cmd-model.js.map +1 -0
- package/dist/cli-cmd-query.d.ts +40 -0
- package/dist/cli-cmd-query.d.ts.map +1 -0
- package/dist/cli-cmd-query.js +303 -0
- package/dist/cli-cmd-query.js.map +1 -0
- package/dist/cli-commands.d.ts +65 -75
- package/dist/cli-commands.d.ts.map +1 -1
- package/dist/cli-commands.js +93 -543
- package/dist/cli-commands.js.map +1 -1
- package/dist/cli-format.d.ts +32 -0
- package/dist/cli-format.d.ts.map +1 -1
- package/dist/cli-format.js +51 -0
- package/dist/cli-format.js.map +1 -1
- package/dist/cli-help.d.ts +19 -0
- package/dist/cli-help.d.ts.map +1 -0
- package/dist/cli-help.js +150 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.js +4 -1
- package/dist/cli.js.map +1 -1
- package/dist/discovery/anthropic.d.ts +8 -1
- package/dist/discovery/anthropic.d.ts.map +1 -1
- package/dist/discovery/anthropic.js +26 -3
- package/dist/discovery/anthropic.js.map +1 -1
- package/dist/discovery/base.d.ts +26 -0
- package/dist/discovery/base.d.ts.map +1 -1
- package/dist/discovery/base.js +55 -2
- package/dist/discovery/base.js.map +1 -1
- package/dist/discovery/free-tier.d.ts +31 -0
- package/dist/discovery/free-tier.d.ts.map +1 -0
- package/dist/discovery/free-tier.js +47 -0
- package/dist/discovery/free-tier.js.map +1 -0
- package/dist/discovery/google.d.ts +8 -1
- package/dist/discovery/google.d.ts.map +1 -1
- package/dist/discovery/google.js +25 -3
- package/dist/discovery/google.js.map +1 -1
- package/dist/discovery/litellm-seed.d.ts +32 -0
- package/dist/discovery/litellm-seed.d.ts.map +1 -0
- package/dist/discovery/litellm-seed.js +252 -0
- package/dist/discovery/litellm-seed.js.map +1 -0
- package/dist/discovery/modelsdev-catalog.d.ts +95 -0
- package/dist/discovery/modelsdev-catalog.d.ts.map +1 -0
- package/dist/discovery/modelsdev-catalog.js +131 -0
- package/dist/discovery/modelsdev-catalog.js.map +1 -0
- package/dist/discovery/modelsdev-seed.d.ts +19 -0
- package/dist/discovery/modelsdev-seed.d.ts.map +1 -0
- package/dist/discovery/modelsdev-seed.js +203 -0
- package/dist/discovery/modelsdev-seed.js.map +1 -0
- package/dist/discovery/openai-compatible.d.ts.map +1 -1
- package/dist/discovery/openai-compatible.js +12 -1
- package/dist/discovery/openai-compatible.js.map +1 -1
- package/dist/discovery/openai.d.ts +9 -1
- package/dist/discovery/openai.d.ts.map +1 -1
- package/dist/discovery/openai.js +31 -8
- package/dist/discovery/openai.js.map +1 -1
- package/dist/discovery/promo-overrides.d.ts +54 -0
- package/dist/discovery/promo-overrides.d.ts.map +1 -0
- package/dist/discovery/promo-overrides.js +74 -0
- package/dist/discovery/promo-overrides.js.map +1 -0
- package/dist/discovery/public-seed.d.ts +30 -0
- package/dist/discovery/public-seed.d.ts.map +1 -0
- package/dist/discovery/public-seed.js +51 -0
- package/dist/discovery/public-seed.js.map +1 -0
- package/dist/discovery-contract.d.ts +14 -2
- package/dist/discovery-contract.d.ts.map +1 -1
- package/dist/discovery-contract.js +28 -0
- package/dist/discovery-contract.js.map +1 -1
- package/dist/enrichment/litellm-catalog.d.ts +81 -0
- package/dist/enrichment/litellm-catalog.d.ts.map +1 -0
- package/dist/enrichment/litellm-catalog.js +129 -0
- package/dist/enrichment/litellm-catalog.js.map +1 -0
- package/dist/enrichment/litellm.d.ts +9 -2
- package/dist/enrichment/litellm.d.ts.map +1 -1
- package/dist/enrichment/litellm.js +168 -20
- package/dist/enrichment/litellm.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/model-features.d.ts +77 -0
- package/dist/model-features.d.ts.map +1 -0
- package/dist/model-features.js +245 -0
- package/dist/model-features.js.map +1 -0
- package/dist/provider-catalog.d.ts +7 -0
- package/dist/provider-catalog.d.ts.map +1 -1
- package/dist/provider-catalog.js +4 -0
- package/dist/provider-catalog.js.map +1 -1
- package/dist/registry-discovery.d.ts.map +1 -1
- package/dist/registry-discovery.js +11 -1
- package/dist/registry-discovery.js.map +1 -1
- package/dist/registry-runtime.d.ts +20 -1
- package/dist/registry-runtime.d.ts.map +1 -1
- package/dist/registry-runtime.js +296 -8
- package/dist/registry-runtime.js.map +1 -1
- package/dist/registry-selection.js +2 -0
- package/dist/registry-selection.js.map +1 -1
- package/dist/registry.d.ts +9 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +11 -1
- package/dist/registry.js.map +1 -1
- package/dist/tokenizer-family.d.ts +39 -0
- package/dist/tokenizer-family.d.ts.map +1 -0
- package/dist/tokenizer-family.js +92 -0
- package/dist/tokenizer-family.js.map +1 -0
- package/dist/types.d.ts +186 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +8 -2
package/dist/discovery/base.js
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
* @module
|
|
7
7
|
*/
|
|
8
8
|
import { assertCleanPayload } from "../security.js";
|
|
9
|
+
import { getPublicSeed } from "./public-seed.js";
|
|
9
10
|
/** Safety cap for paginated model listing. */
|
|
10
11
|
export const MAX_MODELS_PER_PROVIDER = 10_000;
|
|
11
12
|
/** Common API-key patterns to redact from error messages. */
|
|
12
|
-
const API_KEY_PATTERN = /\b(sk-[A-Za-z0-9_-]{8,}|key-[A-Za-z0-9_-]{8,}|Bearer\s+[A-Za-z0-9._
|
|
13
|
+
const API_KEY_PATTERN = /\b(sk-[A-Za-z0-9_-]{8,}|key-[A-Za-z0-9_-]{8,}|Bearer\s+[A-Za-z0-9._-]{20,})\b/gi;
|
|
13
14
|
/** Sanitize a response body before including it in an error message. */
|
|
14
15
|
function sanitizeErrorBody(raw, maxLen = 200) {
|
|
15
16
|
const redacted = raw.replace(API_KEY_PATTERN, "[REDACTED]");
|
|
@@ -99,7 +100,59 @@ export class BaseDiscoverer {
|
|
|
99
100
|
*/
|
|
100
101
|
/** Validate and normalise a timeout value. Returns defaultMs when invalid. */
|
|
101
102
|
validateTimeout(timeout, defaultMs = 10_000) {
|
|
102
|
-
return
|
|
103
|
+
return Number.isFinite(timeout) && timeout > 0 ? timeout : defaultMs;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Union API discovery results with the public seed for this provider.
|
|
107
|
+
*
|
|
108
|
+
* Merge rules per (providerId, modelId):
|
|
109
|
+
* - **Identity wins from API.** If the API returned the model, the API
|
|
110
|
+
* entry's metadata (name, capabilities, mode, context window) is the
|
|
111
|
+
* authoritative description of "what this model is for this account".
|
|
112
|
+
* - **Pricing falls back to the seed.** Native list endpoints
|
|
113
|
+
* (`/v1/models` on Anthropic, OpenAI, Google) return *no pricing*.
|
|
114
|
+
* The seed (models.dev primary, LiteLLM filler) does. So when the
|
|
115
|
+
* API stub has no pricing and the seed entry does, we lift the seed's
|
|
116
|
+
* pricing onto the API entry.
|
|
117
|
+
* - **Seed-only models survive as filler.** Preview tiers, deprecated-
|
|
118
|
+
* but-still-priced SKUs, region-gated entries that the API doesn't
|
|
119
|
+
* list — keep them so consumers can still resolve historical IDs.
|
|
120
|
+
*
|
|
121
|
+
* Why this matters: without the pricing fallback, the same model can flip
|
|
122
|
+
* between two different prices depending on whether `/v1/models` was
|
|
123
|
+
* reachable when `kosha update` ran. That's a same-day-instability bug
|
|
124
|
+
* for any downstream that locks pricing at midnight (tokmeter et al).
|
|
125
|
+
*
|
|
126
|
+
* Failures in fetching the seed are swallowed — the API result still
|
|
127
|
+
* stands on its own. Pricing-degraded fallback is layered on at the
|
|
128
|
+
* registry-runtime merge step.
|
|
129
|
+
*/
|
|
130
|
+
async mergeWithPublicSeed(apiCards) {
|
|
131
|
+
try {
|
|
132
|
+
const seeds = await getPublicSeed(this.providerId);
|
|
133
|
+
if (seeds.length === 0)
|
|
134
|
+
return apiCards;
|
|
135
|
+
const seedById = new Map(seeds.map((s) => [s.id, s]));
|
|
136
|
+
const enriched = apiCards.map((api) => {
|
|
137
|
+
const seed = seedById.get(api.id);
|
|
138
|
+
if (!seed)
|
|
139
|
+
return api;
|
|
140
|
+
const apiHasPricing = !!api.pricing || !!api.originPricing;
|
|
141
|
+
if (apiHasPricing)
|
|
142
|
+
return api;
|
|
143
|
+
return {
|
|
144
|
+
...api,
|
|
145
|
+
pricing: seed.pricing,
|
|
146
|
+
originPricing: seed.originPricing,
|
|
147
|
+
};
|
|
148
|
+
});
|
|
149
|
+
const apiIds = new Set(apiCards.map((c) => c.id));
|
|
150
|
+
const filler = seeds.filter((s) => !apiIds.has(s.id));
|
|
151
|
+
return [...enriched, ...filler];
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
return apiCards;
|
|
155
|
+
}
|
|
103
156
|
}
|
|
104
157
|
makeCard(partial) {
|
|
105
158
|
const capabilities = partial.capabilities ?? ["chat"];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/discovery/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/discovery/base.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,8CAA8C;AAC9C,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC;AAE9C,6DAA6D;AAC7D,MAAM,eAAe,GAAG,iFAAiF,CAAC;AAE1G,wEAAwE;AACxE,SAAS,iBAAiB,CAAC,GAAW,EAAE,MAAM,GAAG,GAAG;IACnD,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,CAAC,eAAe,EAAE,YAAY,CAAC,CAAC;IAC5D,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,QAAQ,CAAC;IAC/C,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,cAAc,CAAC;AACnD,CAAC;AAED;;;;;;GAMG;AACH,MAAM,OAAgB,cAAc;IAYnC;;;;;;;;;OASG;IACO,KAAK,CAAC,SAAS,CAAI,GAAW,EAAE,OAAgC,EAAE,SAAS,GAAG,MAAM;QAC7F,MAAM,UAAU,GAAG,CAAC,CAAC;QACrB,MAAM,WAAW,GAAG,GAAG,CAAC;QACxB,IAAI,SAA4B,CAAC;QAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,GAAG,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACvD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;YAE9D,IAAI,CAAC;gBACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;oBACjC,OAAO;oBACP,MAAM,EAAE,UAAU,CAAC,MAAM;iBACzB,CAAC,CAAC;gBAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAClB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;oBACnD,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACrD,MAAM,GAAG,GAAG,IAAI,KAAK,CACpB,GAAG,IAAI,CAAC,YAAY,eAAe,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,MAAM,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9G,CAAC;oBAEF,yDAAyD;oBACzD,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC;wBACrD,MAAM,GAAG,CAAC;oBACX,CAAC;oBAED,kCAAkC;oBAClC,SAAS,GAAG,GAAG,CAAC;gBACjB,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAM,CAAC;oBAC1C,kBAAkB,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,YAAY,MAAM,CAAC,CAAC;oBACrD,OAAO,IAAI,CAAC;gBACb,CAAC;YACF,CAAC;YAAC,OAAO,KAAc,EAAE,CAAC;gBACzB,IAAI,KAAK,YAAY,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAClE,SAAS,GAAG,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,gCAAgC,SAAS,IAAI,CAAC,CAAC;gBAC1F,CAAC;qBAAM,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;oBACnC,yDAAyD;oBACzD,SAAS,GAAG,KAAK,CAAC;gBACnB,CAAC;qBAAM,CAAC;oBACP,SAAS,GAAG,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;gBACtC,CAAC;YACF,CAAC;oBAAS,CAAC;gBACV,YAAY,CAAC,KAAK,CAAC,CAAC;YACrB,CAAC;YAED,4DAA4D;YAC5D,IAAI,OAAO,GAAG,UAAU,GAAG,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC;YACjF,CAAC;QACF,CAAC;QAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,GAAG,IAAI,CAAC,YAAY,6BAA6B,UAAU,WAAW,CAAC,CAAC;IACtG,CAAC;IAED;;;;;;;;;;OAUG;IACH,8EAA8E;IACpE,eAAe,CAAC,OAA2B,EAAE,SAAS,GAAG,MAAM;QACxE,OAAO,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,OAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,OAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACO,KAAK,CAAC,mBAAmB,CAAC,QAAqB;QACxD,IAAI,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACnD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,QAAQ,CAAC;YACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;YACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACrC,MAAM,IAAI,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBAClC,IAAI,CAAC,IAAI;oBAAE,OAAO,GAAG,CAAC;gBACtB,MAAM,aAAa,GAAG,CAAC,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC;gBAC3D,IAAI,aAAa;oBAAE,OAAO,GAAG,CAAC;gBAC9B,OAAO;oBACN,GAAG,GAAG;oBACN,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,aAAa,EAAE,IAAI,CAAC,aAAa;iBACjC,CAAC;YACH,CAAC,CAAC,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAClD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACtD,OAAO,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,QAAQ,CAAC;QACjB,CAAC;IACF,CAAC;IAES,QAAQ,CAAC,OAA8D;QAChF,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,OAAO;YACN,IAAI,EAAE,OAAO,CAAC,EAAE;YAChB,IAAI,EAAE,MAAM;YACZ,YAAY;YACZ,eAAe,EAAE,OAAO,CAAC,eAAe,IAAI,CAAC,GAAG,YAAY,CAAC;YAC7D,aAAa,EAAE,CAAC;YAChB,eAAe,EAAE,CAAC;YAClB,OAAO,EAAE,EAAE;YACX,YAAY,EAAE,IAAI,CAAC,GAAG,EAAE;YACxB,MAAM,EAAE,KAAK;YACb,oEAAoE;YACpE,oDAAoD;YACpD,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,QAAQ;YAC1D,GAAG,OAAO;SACV,CAAC;IACH,CAAC;CACD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Free-tier capability flag.
|
|
3
|
+
*
|
|
4
|
+
* Centralised helper that adds the `"free_tier"` capability to a
|
|
5
|
+
* {@link ModelCard} when the model is genuinely free for both input and
|
|
6
|
+
* output usage. Used by the public-catalog seeds (models.dev, LiteLLM)
|
|
7
|
+
* and by the post-discovery enricher so any path that ends up with
|
|
8
|
+
* 0/0 pricing gets the flag consistently.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from "pricing unknown":
|
|
11
|
+
* - `pricing === undefined` → upstream had no pricing field at all.
|
|
12
|
+
* - `pricing = { in: 0, out: 0 }` → upstream said the model is free.
|
|
13
|
+
*
|
|
14
|
+
* Free can mean a structural offering (NVIDIA NIM dev tier, open-weights
|
|
15
|
+
* via deepinfra) or a temporary promotion (DeepSeek off-peak windows).
|
|
16
|
+
* We don't distinguish those today because no upstream catalog labels
|
|
17
|
+
* them — but the flag is enough for downstream cost classification.
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import type { ModelCard } from "../types.js";
|
|
21
|
+
export declare const FREE_TIER_CAPABILITY = "free_tier";
|
|
22
|
+
/**
|
|
23
|
+
* Returns a copy of the card with `"free_tier"` added to capabilities
|
|
24
|
+
* when both input and output pricing are exactly zero. No-op otherwise.
|
|
25
|
+
*
|
|
26
|
+
* Idempotent: calling it twice does not duplicate the flag.
|
|
27
|
+
*/
|
|
28
|
+
export declare function applyFreeTierFlag(card: ModelCard): ModelCard;
|
|
29
|
+
/** True when the card explicitly priced both directions at zero. */
|
|
30
|
+
export declare function isFreeTier(card: ModelCard): boolean;
|
|
31
|
+
//# sourceMappingURL=free-tier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"free-tier.d.ts","sourceRoot":"","sources":["../../src/discovery/free-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,eAAO,MAAM,oBAAoB,cAAc,CAAC;AAEhD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,CAU5D;AAED,oEAAoE;AACpE,wBAAgB,UAAU,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAInD"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Free-tier capability flag.
|
|
3
|
+
*
|
|
4
|
+
* Centralised helper that adds the `"free_tier"` capability to a
|
|
5
|
+
* {@link ModelCard} when the model is genuinely free for both input and
|
|
6
|
+
* output usage. Used by the public-catalog seeds (models.dev, LiteLLM)
|
|
7
|
+
* and by the post-discovery enricher so any path that ends up with
|
|
8
|
+
* 0/0 pricing gets the flag consistently.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from "pricing unknown":
|
|
11
|
+
* - `pricing === undefined` → upstream had no pricing field at all.
|
|
12
|
+
* - `pricing = { in: 0, out: 0 }` → upstream said the model is free.
|
|
13
|
+
*
|
|
14
|
+
* Free can mean a structural offering (NVIDIA NIM dev tier, open-weights
|
|
15
|
+
* via deepinfra) or a temporary promotion (DeepSeek off-peak windows).
|
|
16
|
+
* We don't distinguish those today because no upstream catalog labels
|
|
17
|
+
* them — but the flag is enough for downstream cost classification.
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
export const FREE_TIER_CAPABILITY = "free_tier";
|
|
21
|
+
/**
|
|
22
|
+
* Returns a copy of the card with `"free_tier"` added to capabilities
|
|
23
|
+
* when both input and output pricing are exactly zero. No-op otherwise.
|
|
24
|
+
*
|
|
25
|
+
* Idempotent: calling it twice does not duplicate the flag.
|
|
26
|
+
*/
|
|
27
|
+
export function applyFreeTierFlag(card) {
|
|
28
|
+
if (!isFreeTier(card))
|
|
29
|
+
return card;
|
|
30
|
+
if (card.capabilities.includes(FREE_TIER_CAPABILITY))
|
|
31
|
+
return card;
|
|
32
|
+
const capabilities = [...card.capabilities, FREE_TIER_CAPABILITY];
|
|
33
|
+
const rawCapabilities = card.rawCapabilities
|
|
34
|
+
? card.rawCapabilities.includes(FREE_TIER_CAPABILITY)
|
|
35
|
+
? card.rawCapabilities
|
|
36
|
+
: [...card.rawCapabilities, FREE_TIER_CAPABILITY]
|
|
37
|
+
: undefined;
|
|
38
|
+
return { ...card, capabilities, rawCapabilities };
|
|
39
|
+
}
|
|
40
|
+
/** True when the card explicitly priced both directions at zero. */
|
|
41
|
+
export function isFreeTier(card) {
|
|
42
|
+
const pricing = card.pricing;
|
|
43
|
+
if (!pricing)
|
|
44
|
+
return false;
|
|
45
|
+
return pricing.inputPerMillion === 0 && pricing.outputPerMillion === 0;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=free-tier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"free-tier.js","sourceRoot":"","sources":["../../src/discovery/free-tier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH,MAAM,CAAC,MAAM,oBAAoB,GAAG,WAAW,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAe;IAChD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,oBAAoB,CAAC;QAAE,OAAO,IAAI,CAAC;IAClE,MAAM,YAAY,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,EAAE,oBAAoB,CAAC,CAAC;IAClE,MAAM,eAAe,GAAG,IAAI,CAAC,eAAe;QAC3C,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,oBAAoB,CAAC;YACpD,CAAC,CAAC,IAAI,CAAC,eAAe;YACtB,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe,EAAE,oBAAoB,CAAC;QAClD,CAAC,CAAC,SAAS,CAAC;IACb,OAAO,EAAE,GAAG,IAAI,EAAE,YAAY,EAAE,eAAe,EAAE,CAAC;AACnD,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,IAAe;IACzC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;IAC7B,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,OAAO,CAAC,eAAe,KAAK,CAAC,IAAI,OAAO,CAAC,gBAAgB,KAAK,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -49,7 +49,14 @@ export declare class GoogleDiscoverer extends BaseDiscoverer {
|
|
|
49
49
|
* Gemini Pro, Ultra, and Flash variants support function calling and vision.
|
|
50
50
|
*/
|
|
51
51
|
private inferCapabilities;
|
|
52
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* No-key fallback: source the latest public seed via {@link getPublicSeed},
|
|
54
|
+
* which uses models.dev as the primary source, fills gaps from the public
|
|
55
|
+
* LiteLLM catalog, and applies promo overrides. Falls back to the curated
|
|
56
|
+
* static list only if the public-seed fetch fails or returns no models.
|
|
57
|
+
*/
|
|
58
|
+
private publicCatalogFallback;
|
|
59
|
+
/** Return curated fallback models when both API and public catalog are unavailable. */
|
|
53
60
|
private staticFallbackModels;
|
|
54
61
|
}
|
|
55
62
|
//# sourceMappingURL=google.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/discovery/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,cAAc,EAA2B,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"google.d.ts","sourceRoot":"","sources":["../../src/discovery/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,SAAS,EAAa,MAAM,aAAa,CAAC;AAC1E,OAAO,EAAE,cAAc,EAA2B,MAAM,WAAW,CAAC;AAwBpE;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,cAAc;IACnD,QAAQ,CAAC,UAAU,YAAY;IAC/B,QAAQ,CAAC,YAAY,YAAY;IACjC,QAAQ,CAAC,OAAO,+CAA+C;IAE/D;;;;OAIG;IACG,QAAQ,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC;IA0BlG;;OAEG;IACH,OAAO,CAAC,QAAQ;IAQhB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACH,OAAO,CAAC,SAAS;IAYjB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAgCzB;;;;;OAKG;YACW,qBAAqB;IAUnC,uFAAuF;IACvF,OAAO,CAAC,oBAAoB;CAe5B"}
|
package/dist/discovery/google.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @module
|
|
10
10
|
*/
|
|
11
11
|
import { BaseDiscoverer, MAX_MODELS_PER_PROVIDER } from "./base.js";
|
|
12
|
+
import { getPublicSeed } from "./public-seed.js";
|
|
12
13
|
import { STATIC_GOOGLE_MODELS } from "./static-direct.js";
|
|
13
14
|
/**
|
|
14
15
|
* Discovers models available through the Google Generative Language API.
|
|
@@ -28,7 +29,7 @@ export class GoogleDiscoverer extends BaseDiscoverer {
|
|
|
28
29
|
async discover(credential, options) {
|
|
29
30
|
const apiKey = credential.apiKey ?? credential.accessToken;
|
|
30
31
|
if (!apiKey) {
|
|
31
|
-
return this.
|
|
32
|
+
return this.publicCatalogFallback();
|
|
32
33
|
}
|
|
33
34
|
const timeoutMs = this.validateTimeout(options?.timeout);
|
|
34
35
|
const allModels = [];
|
|
@@ -42,7 +43,11 @@ export class GoogleDiscoverer extends BaseDiscoverer {
|
|
|
42
43
|
if (allModels.length >= MAX_MODELS_PER_PROVIDER)
|
|
43
44
|
break;
|
|
44
45
|
} while (pageToken);
|
|
45
|
-
|
|
46
|
+
const apiCards = allModels.map((model) => this.toModelCard(model));
|
|
47
|
+
// Merge public catalog so any Gemini SKU not in v1beta/models keeps its
|
|
48
|
+
// pricing. API wins on identity; seed wins on pricing where the API
|
|
49
|
+
// stub has none.
|
|
50
|
+
return this.mergeWithPublicSeed(apiCards);
|
|
46
51
|
}
|
|
47
52
|
/**
|
|
48
53
|
* Build the paginated list URL with API key and optional page token.
|
|
@@ -119,7 +124,24 @@ export class GoogleDiscoverer extends BaseDiscoverer {
|
|
|
119
124
|
}
|
|
120
125
|
return capabilities.length > 0 ? capabilities : ["chat"];
|
|
121
126
|
}
|
|
122
|
-
/**
|
|
127
|
+
/**
|
|
128
|
+
* No-key fallback: source the latest public seed via {@link getPublicSeed},
|
|
129
|
+
* which uses models.dev as the primary source, fills gaps from the public
|
|
130
|
+
* LiteLLM catalog, and applies promo overrides. Falls back to the curated
|
|
131
|
+
* static list only if the public-seed fetch fails or returns no models.
|
|
132
|
+
*/
|
|
133
|
+
async publicCatalogFallback() {
|
|
134
|
+
try {
|
|
135
|
+
const seeds = await getPublicSeed(this.providerId);
|
|
136
|
+
if (seeds.length > 0)
|
|
137
|
+
return seeds;
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
/* fall through to static fallback */
|
|
141
|
+
}
|
|
142
|
+
return this.staticFallbackModels();
|
|
143
|
+
}
|
|
144
|
+
/** Return curated fallback models when both API and public catalog are unavailable. */
|
|
123
145
|
staticFallbackModels() {
|
|
124
146
|
return STATIC_GOOGLE_MODELS.map((model) => this.makeCard({
|
|
125
147
|
id: model.id,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/discovery/google.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAsB1D;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,cAAc;IAC1C,UAAU,GAAG,QAAQ,CAAC;IACtB,YAAY,GAAG,QAAQ,CAAC;IACxB,OAAO,GAAG,2CAA2C,CAAC;IAE/D;;;;OAIG;IACH,KAAK,CAAC,QAAQ,CAAC,UAA4B,EAAE,OAA8B;QAC1E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,IAAI,UAAU,CAAC,WAAW,CAAC;QAC3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"google.js","sourceRoot":"","sources":["../../src/discovery/google.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Public-catalog seed for origin providers.
|
|
3
|
+
*
|
|
4
|
+
* Treats the LiteLLM community catalog as the canonical *public* source of
|
|
5
|
+
* "what models exist with what pricing/context/capabilities" and converts
|
|
6
|
+
* it into seed {@link ModelCard} arrays per origin provider.
|
|
7
|
+
*
|
|
8
|
+
* This decouples kosha discovery from API keys: anyone running `kosha
|
|
9
|
+
* latest`, with or without credentials, gets the current state of the
|
|
10
|
+
* world for every supported origin provider.
|
|
11
|
+
*
|
|
12
|
+
* Hardening notes:
|
|
13
|
+
* - All fields are read defensively (`typeof` checks, length caps).
|
|
14
|
+
* - Synthetic IDs are slugified to strict `[A-Za-z0-9._/:-]` so a
|
|
15
|
+
* compromised catalog cannot smuggle injection-shaped strings into
|
|
16
|
+
* downstream consumers.
|
|
17
|
+
* - The maximum number of seeded models per provider is capped to bound
|
|
18
|
+
* cost of a hostile catalog.
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import type { ModelCard } from "../types.js";
|
|
22
|
+
/**
|
|
23
|
+
* Build a fresh array of seed {@link ModelCard}s for the given kosha
|
|
24
|
+
* provider ID, using the shared LiteLLM catalog. Returns `[]` if the
|
|
25
|
+
* provider has no entries in the catalog.
|
|
26
|
+
*
|
|
27
|
+
* The returned cards have `source: "litellm"` so downstream consumers
|
|
28
|
+
* (and the existing pricing enricher) can distinguish public-catalog
|
|
29
|
+
* data from live-API data.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getLiteLLMSeed(providerId: string): Promise<ModelCard[]>;
|
|
32
|
+
//# sourceMappingURL=litellm-seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"litellm-seed.d.ts","sourceRoot":"","sources":["../../src/discovery/litellm-seed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAA2B,MAAM,aAAa,CAAC;AA6CtE;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,EAAE,CAAC,CAyB7E"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* kosha-discovery — Public-catalog seed for origin providers.
|
|
3
|
+
*
|
|
4
|
+
* Treats the LiteLLM community catalog as the canonical *public* source of
|
|
5
|
+
* "what models exist with what pricing/context/capabilities" and converts
|
|
6
|
+
* it into seed {@link ModelCard} arrays per origin provider.
|
|
7
|
+
*
|
|
8
|
+
* This decouples kosha discovery from API keys: anyone running `kosha
|
|
9
|
+
* latest`, with or without credentials, gets the current state of the
|
|
10
|
+
* world for every supported origin provider.
|
|
11
|
+
*
|
|
12
|
+
* Hardening notes:
|
|
13
|
+
* - All fields are read defensively (`typeof` checks, length caps).
|
|
14
|
+
* - Synthetic IDs are slugified to strict `[A-Za-z0-9._/:-]` so a
|
|
15
|
+
* compromised catalog cannot smuggle injection-shaped strings into
|
|
16
|
+
* downstream consumers.
|
|
17
|
+
* - The maximum number of seeded models per provider is capped to bound
|
|
18
|
+
* cost of a hostile catalog.
|
|
19
|
+
* @module
|
|
20
|
+
*/
|
|
21
|
+
import { applyFreeTierFlag } from "./free-tier.js";
|
|
22
|
+
import { loadLiteLLMCatalog, } from "../enrichment/litellm-catalog.js";
|
|
23
|
+
/** Per-token cost → per-million conversion factor. */
|
|
24
|
+
const PER_MILLION = 1_000_000;
|
|
25
|
+
/** Maximum models seeded for a single provider — defensive ceiling. */
|
|
26
|
+
const MAX_MODELS_PER_SEED = 1_000;
|
|
27
|
+
/** Strict charset for model IDs; everything else gets stripped or rejected. */
|
|
28
|
+
const SAFE_ID_PATTERN = /^[A-Za-z0-9._:/\-]+$/;
|
|
29
|
+
/** Maximum length we accept for a model ID. */
|
|
30
|
+
const MAX_ID_LENGTH = 256;
|
|
31
|
+
/**
|
|
32
|
+
* Map kosha provider IDs (the slugs used internally) to the set of
|
|
33
|
+
* `litellm_provider` values that should be treated as the same origin.
|
|
34
|
+
* LiteLLM's slugs differ from kosha's in a few places (`gemini`, `together_ai`,
|
|
35
|
+
* `fireworks_ai`, etc.), so we alias them here rather than scattering
|
|
36
|
+
* conditionals across discoverers.
|
|
37
|
+
*/
|
|
38
|
+
const PROVIDER_SLUG_ALIASES = {
|
|
39
|
+
anthropic: ["anthropic"],
|
|
40
|
+
openai: ["openai"],
|
|
41
|
+
google: ["gemini", "vertex_ai-language-models", "vertex_ai-image-models", "vertex_ai-embedding-models"],
|
|
42
|
+
deepseek: ["deepseek"],
|
|
43
|
+
zai: ["zai"],
|
|
44
|
+
minimax: ["minimax"],
|
|
45
|
+
moonshot: ["moonshot"],
|
|
46
|
+
mistral: ["mistral"],
|
|
47
|
+
cohere: ["cohere", "cohere_chat"],
|
|
48
|
+
groq: ["groq"],
|
|
49
|
+
together: ["together_ai"],
|
|
50
|
+
fireworks: ["fireworks_ai"],
|
|
51
|
+
perplexity: ["perplexity"],
|
|
52
|
+
cerebras: ["cerebras"],
|
|
53
|
+
deepinfra: ["deepinfra"],
|
|
54
|
+
xai: ["xai"],
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Build a fresh array of seed {@link ModelCard}s for the given kosha
|
|
58
|
+
* provider ID, using the shared LiteLLM catalog. Returns `[]` if the
|
|
59
|
+
* provider has no entries in the catalog.
|
|
60
|
+
*
|
|
61
|
+
* The returned cards have `source: "litellm"` so downstream consumers
|
|
62
|
+
* (and the existing pricing enricher) can distinguish public-catalog
|
|
63
|
+
* data from live-API data.
|
|
64
|
+
*/
|
|
65
|
+
export async function getLiteLLMSeed(providerId) {
|
|
66
|
+
const slugs = PROVIDER_SLUG_ALIASES[providerId];
|
|
67
|
+
if (!slugs || slugs.length === 0)
|
|
68
|
+
return [];
|
|
69
|
+
const catalog = await loadLiteLLMCatalog();
|
|
70
|
+
const seeds = [];
|
|
71
|
+
const seenIds = new Set();
|
|
72
|
+
for (const [key, entry] of Object.entries(catalog)) {
|
|
73
|
+
if (seeds.length >= MAX_MODELS_PER_SEED)
|
|
74
|
+
break;
|
|
75
|
+
if (!entry || typeof entry !== "object")
|
|
76
|
+
continue;
|
|
77
|
+
const litellmProvider = entry.litellm_provider;
|
|
78
|
+
if (typeof litellmProvider !== "string")
|
|
79
|
+
continue;
|
|
80
|
+
if (!slugs.includes(litellmProvider))
|
|
81
|
+
continue;
|
|
82
|
+
const id = canonicaliseModelId(key, providerId);
|
|
83
|
+
if (!id || seenIds.has(id))
|
|
84
|
+
continue;
|
|
85
|
+
seenIds.add(id);
|
|
86
|
+
const card = buildSeedCard(id, providerId, entry);
|
|
87
|
+
if (card)
|
|
88
|
+
seeds.push(card);
|
|
89
|
+
}
|
|
90
|
+
return seeds;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Strip a LiteLLM catalog key down to the provider-native model ID.
|
|
94
|
+
*
|
|
95
|
+
* LiteLLM keys come in three shapes:
|
|
96
|
+
* 1. Bare ID: `claude-opus-4-7`
|
|
97
|
+
* 2. Prefixed: `anthropic/claude-opus-4-7`
|
|
98
|
+
* 3. Path-prefixed: `vertex_ai/claude-opus-4-7@default`
|
|
99
|
+
*
|
|
100
|
+
* Returns null when the key is not safe (oversized, illegal chars,
|
|
101
|
+
* or empty after stripping).
|
|
102
|
+
*/
|
|
103
|
+
function canonicaliseModelId(rawKey, providerId) {
|
|
104
|
+
if (typeof rawKey !== "string" || rawKey.length === 0 || rawKey.length > MAX_ID_LENGTH) {
|
|
105
|
+
return null;
|
|
106
|
+
}
|
|
107
|
+
// Drop everything before the last `/`. Most public catalogs prefix the
|
|
108
|
+
// vendor; kosha stores the bare provider-native ID.
|
|
109
|
+
let id = rawKey.includes("/") ? rawKey.slice(rawKey.lastIndexOf("/") + 1) : rawKey;
|
|
110
|
+
// Drop deployment suffixes after `@` (Vertex naming).
|
|
111
|
+
const atIdx = id.indexOf("@");
|
|
112
|
+
if (atIdx > 0)
|
|
113
|
+
id = id.slice(0, atIdx);
|
|
114
|
+
if (!SAFE_ID_PATTERN.test(id))
|
|
115
|
+
return null;
|
|
116
|
+
// Skip pseudo entries the catalog uses for documentation (e.g. "sample_spec").
|
|
117
|
+
if (id === "sample_spec")
|
|
118
|
+
return null;
|
|
119
|
+
// For Google: only keep the gemini-* family, not other vertex bundle entries
|
|
120
|
+
// that aren't real model IDs.
|
|
121
|
+
if (providerId === "google" && !id.startsWith("gemini") && !id.startsWith("imagen") && !id.startsWith("veo")) {
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
return id;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Convert a single LiteLLM entry into a {@link ModelCard}. Returns null
|
|
128
|
+
* when the entry is too sparse to be useful (e.g. no mode and no pricing
|
|
129
|
+
* signal at all).
|
|
130
|
+
*/
|
|
131
|
+
function buildSeedCard(id, providerId, entry) {
|
|
132
|
+
const mode = inferMode(entry);
|
|
133
|
+
const capabilities = inferCapabilities(entry, mode);
|
|
134
|
+
const pricing = extractPricing(entry);
|
|
135
|
+
const contextWindow = pickPositive(entry.max_input_tokens, entry.max_tokens) ?? 0;
|
|
136
|
+
const maxOutputTokens = pickPositive(entry.max_output_tokens, entry.max_tokens) ?? 0;
|
|
137
|
+
const card = {
|
|
138
|
+
id,
|
|
139
|
+
name: id,
|
|
140
|
+
provider: providerId,
|
|
141
|
+
originProvider: providerId,
|
|
142
|
+
mode,
|
|
143
|
+
capabilities,
|
|
144
|
+
rawCapabilities: [...capabilities],
|
|
145
|
+
contextWindow,
|
|
146
|
+
maxOutputTokens,
|
|
147
|
+
maxInputTokens: pickPositive(entry.max_input_tokens),
|
|
148
|
+
dimensions: pickPositive(entry.output_vector_size),
|
|
149
|
+
pricing,
|
|
150
|
+
aliases: [],
|
|
151
|
+
discoveredAt: Date.now(),
|
|
152
|
+
source: "litellm",
|
|
153
|
+
};
|
|
154
|
+
return applyFreeTierFlag(card);
|
|
155
|
+
}
|
|
156
|
+
/** Pick the first finite, positive number from a list of optional values. */
|
|
157
|
+
function pickPositive(...values) {
|
|
158
|
+
for (const value of values) {
|
|
159
|
+
if (typeof value === "number" && Number.isFinite(value) && value > 0)
|
|
160
|
+
return value;
|
|
161
|
+
}
|
|
162
|
+
return undefined;
|
|
163
|
+
}
|
|
164
|
+
/** Map LiteLLM mode strings to the kosha ModelMode union. */
|
|
165
|
+
function inferMode(entry) {
|
|
166
|
+
switch (entry.mode) {
|
|
167
|
+
case "embedding":
|
|
168
|
+
return "embedding";
|
|
169
|
+
case "image_generation":
|
|
170
|
+
return "image";
|
|
171
|
+
case "audio_transcription":
|
|
172
|
+
case "audio_speech":
|
|
173
|
+
return "audio";
|
|
174
|
+
case "moderation":
|
|
175
|
+
return "moderation";
|
|
176
|
+
case "rerank":
|
|
177
|
+
return "rerank";
|
|
178
|
+
default:
|
|
179
|
+
return "chat";
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/** Infer kosha capability flags from LiteLLM's structured boolean fields. */
|
|
183
|
+
function inferCapabilities(entry, mode) {
|
|
184
|
+
if (mode === "embedding")
|
|
185
|
+
return ["embedding"];
|
|
186
|
+
if (mode === "image")
|
|
187
|
+
return ["image_generation"];
|
|
188
|
+
if (mode === "audio")
|
|
189
|
+
return ["audio"];
|
|
190
|
+
if (mode === "moderation")
|
|
191
|
+
return ["moderation"];
|
|
192
|
+
if (mode === "rerank")
|
|
193
|
+
return ["rerank"];
|
|
194
|
+
const caps = new Set(["chat"]);
|
|
195
|
+
if (entry.supports_vision)
|
|
196
|
+
caps.add("vision");
|
|
197
|
+
if (entry.supports_function_calling || entry.supports_tool_choice)
|
|
198
|
+
caps.add("function_calling");
|
|
199
|
+
if (entry.supports_prompt_caching)
|
|
200
|
+
caps.add("prompt_caching");
|
|
201
|
+
if (entry.supports_response_schema)
|
|
202
|
+
caps.add("structured_output");
|
|
203
|
+
// Most modern chat models cover code / NLU; LiteLLM doesn't expose those
|
|
204
|
+
// flags, but kosha consumers expect them present for chat-class models.
|
|
205
|
+
caps.add("code");
|
|
206
|
+
caps.add("nlu");
|
|
207
|
+
return Array.from(caps);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Convert LiteLLM per-token costs to per-million pricing.
|
|
211
|
+
* Returns undefined unless both base input and output pricing are present.
|
|
212
|
+
*/
|
|
213
|
+
function extractPricing(entry) {
|
|
214
|
+
const baseInput = isFinite(entry.input_cost_per_token) ? entry.input_cost_per_token : undefined;
|
|
215
|
+
const baseOutput = isFinite(entry.output_cost_per_token) ? entry.output_cost_per_token : undefined;
|
|
216
|
+
const reasoningInput = firstFinite(entry.input_cost_per_reasoning_token, entry.reasoning_input_cost_per_token);
|
|
217
|
+
const reasoningOutput = firstFinite(entry.output_cost_per_reasoning_token, entry.reasoning_output_cost_per_token);
|
|
218
|
+
if (baseInput === undefined || baseOutput === undefined)
|
|
219
|
+
return undefined;
|
|
220
|
+
const pricing = {
|
|
221
|
+
inputPerMillion: baseInput * PER_MILLION,
|
|
222
|
+
outputPerMillion: baseOutput * PER_MILLION,
|
|
223
|
+
};
|
|
224
|
+
if (reasoningInput !== undefined)
|
|
225
|
+
pricing.reasoningInputPerMillion = reasoningInput * PER_MILLION;
|
|
226
|
+
if (reasoningOutput !== undefined)
|
|
227
|
+
pricing.reasoningOutputPerMillion = reasoningOutput * PER_MILLION;
|
|
228
|
+
if (isFinite(entry.cache_read_input_token_cost)) {
|
|
229
|
+
pricing.cacheReadPerMillion = entry.cache_read_input_token_cost * PER_MILLION;
|
|
230
|
+
}
|
|
231
|
+
if (isFinite(entry.cache_creation_input_token_cost)) {
|
|
232
|
+
pricing.cacheWritePerMillion = entry.cache_creation_input_token_cost * PER_MILLION;
|
|
233
|
+
}
|
|
234
|
+
if (isFinite(entry.input_cost_per_token_batches)) {
|
|
235
|
+
pricing.batchInputPerMillion = entry.input_cost_per_token_batches * PER_MILLION;
|
|
236
|
+
}
|
|
237
|
+
if (isFinite(entry.output_cost_per_token_batches)) {
|
|
238
|
+
pricing.batchOutputPerMillion = entry.output_cost_per_token_batches * PER_MILLION;
|
|
239
|
+
}
|
|
240
|
+
return pricing;
|
|
241
|
+
}
|
|
242
|
+
function firstFinite(...values) {
|
|
243
|
+
for (const value of values) {
|
|
244
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
245
|
+
return value;
|
|
246
|
+
}
|
|
247
|
+
return undefined;
|
|
248
|
+
}
|
|
249
|
+
function isFinite(value) {
|
|
250
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=litellm-seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"litellm-seed.js","sourceRoot":"","sources":["../../src/discovery/litellm-seed.ts"],"names":[],"mappings":"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"}
|