@theokit/sdk 4.12.2 → 4.13.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/CHANGELOG.md +6 -0
- package/dist/cron.cjs +164 -78
- package/dist/cron.cjs.map +1 -1
- package/dist/cron.js +164 -78
- package/dist/cron.js.map +1 -1
- package/dist/eval.cjs +164 -78
- package/dist/eval.cjs.map +1 -1
- package/dist/eval.js +164 -78
- package/dist/eval.js.map +1 -1
- package/dist/index.cjs +178 -92
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +178 -92
- package/dist/index.js.map +1 -1
- package/dist/internal/providers/catalog-loader.d.ts +8 -0
- package/dist/internal/providers/catalog-schema.d.ts +53 -0
- package/dist/internal/providers/catalog-source-models-dev.d.ts +33 -0
- package/dist/models.cjs +332 -257
- package/dist/models.cjs.map +1 -1
- package/dist/models.d.cts +2 -0
- package/dist/models.d.ts +2 -0
- package/dist/models.js +330 -258
- package/dist/models.js.map +1 -1
- package/dist/provider-catalog.json +571 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 4.13.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Model catalog enrichment (agent-builder M44): the vendored `provider-catalog.json` now carries OPTIONAL per-model data (`models` block — models.dev shape verbatim: `cost{input,output,cache_read,cache_write}` USD-per-1M, `limit{context,input,output}`, `modalities`, `tool_call`/`reasoning`/`structured_output`/`cache_control`, `release_date`, `status`), loaded into an internal model-info index keyed `provider/model` (entry id + aliases). Fully additive: entries without `models` behave byte-identically, `ProviderProfile` is untouched, the 10 builtins + all 43 catalog entries keep resolving, and a malformed model sub-entry drops that model with WARN keeping the provider. DRY reconciliation: `resolveModelCapabilities` is now catalog-backed (the hand-curated EXACT map migrated into the catalog and was deleted — parity-tested over the full old-map snapshot), and `getPricingEntry` gains a step-5 catalog fallback on total LiteLLM miss (provenance `pricingVersion:"catalog-vendored"`; the LiteLLM snapshot keeps absolute precedence — and the new drift advisory caught a real stale rate: `openai/o3` corrected 10/40 → 2/8). New on `@theokit/sdk/models`: `getModelInfo(modelId)` (the enriched per-model view) and `refreshModelCatalog({url?, force?})` — an EXPLICIT opt-in models.dev refresh with a 1h-TTL atomic disk cache under `~/.theokit/cache/models-dev/`, kill-switch `THEOKIT_DISABLE_MODELS_FETCH`, and the vendored catalog as offline fallback; startup and requests never touch the network. Mechanism adapted from OpenCode's models.dev consumption (MIT); see NOTICE. Maintenance: `scripts/refresh-catalog.mjs` regenerates the curated vendored subset (30 models, +36KB).
|
|
8
|
+
|
|
3
9
|
## 4.12.2
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/dist/cron.cjs
CHANGED
|
@@ -570,10 +570,10 @@ function buildToolPrompt(prompt) {
|
|
|
570
570
|
Respond by calling the \`output\` tool with the structured answer that matches the schema.`;
|
|
571
571
|
}
|
|
572
572
|
function setupStructuredOutput(schema, maxRetries) {
|
|
573
|
-
const
|
|
573
|
+
const z10 = requireZod();
|
|
574
574
|
const jsonSchema = toJsonSchema(schema, { unrepresentable: "any" });
|
|
575
575
|
return {
|
|
576
|
-
z:
|
|
576
|
+
z: z10,
|
|
577
577
|
jsonSchema,
|
|
578
578
|
maxRetries: maxRetries ?? 1,
|
|
579
579
|
initialUsage: { inputTokens: 0, outputTokens: 0 }
|
|
@@ -10504,6 +10504,144 @@ function applyToolResultGuard(parts, opts) {
|
|
|
10504
10504
|
)
|
|
10505
10505
|
);
|
|
10506
10506
|
}
|
|
10507
|
+
var MODALITIES = ["text", "audio", "image", "video", "pdf"];
|
|
10508
|
+
var costSchema = zod.z.object({
|
|
10509
|
+
/** USD per 1M tokens (models.dev convention). */
|
|
10510
|
+
input: zod.z.number().nonnegative(),
|
|
10511
|
+
output: zod.z.number().nonnegative(),
|
|
10512
|
+
cache_read: zod.z.number().nonnegative().optional(),
|
|
10513
|
+
cache_write: zod.z.number().nonnegative().optional()
|
|
10514
|
+
}).loose();
|
|
10515
|
+
var limitSchema = zod.z.object({
|
|
10516
|
+
context: zod.z.number().positive(),
|
|
10517
|
+
input: zod.z.number().positive().optional(),
|
|
10518
|
+
output: zod.z.number().positive().optional()
|
|
10519
|
+
}).loose();
|
|
10520
|
+
var modalitiesSchema = zod.z.object({
|
|
10521
|
+
input: zod.z.array(zod.z.enum(MODALITIES)).optional(),
|
|
10522
|
+
output: zod.z.array(zod.z.enum(MODALITIES)).optional()
|
|
10523
|
+
}).loose();
|
|
10524
|
+
var catalogModelSchema = zod.z.object({
|
|
10525
|
+
name: zod.z.string().optional(),
|
|
10526
|
+
release_date: zod.z.string().optional(),
|
|
10527
|
+
attachment: zod.z.boolean().optional(),
|
|
10528
|
+
reasoning: zod.z.boolean().optional(),
|
|
10529
|
+
temperature: zod.z.boolean().optional(),
|
|
10530
|
+
tool_call: zod.z.boolean().optional(),
|
|
10531
|
+
/** theokit extension — maps to ModelCapabilities.supportsStructuredOutput. */
|
|
10532
|
+
structured_output: zod.z.boolean().optional(),
|
|
10533
|
+
/** theokit extension — maps to ModelCapabilities.supportsCacheControl. */
|
|
10534
|
+
cache_control: zod.z.boolean().optional(),
|
|
10535
|
+
cost: costSchema.optional(),
|
|
10536
|
+
limit: limitSchema.optional(),
|
|
10537
|
+
modalities: modalitiesSchema.optional(),
|
|
10538
|
+
status: zod.z.enum(["alpha", "beta", "deprecated"]).optional()
|
|
10539
|
+
}).loose();
|
|
10540
|
+
|
|
10541
|
+
// src/internal/providers/registry.ts
|
|
10542
|
+
var REGISTRY = /* @__PURE__ */ new Map();
|
|
10543
|
+
var ALIASES = /* @__PURE__ */ new Map();
|
|
10544
|
+
function registerProvider(profile) {
|
|
10545
|
+
if (REGISTRY.has(profile.name)) {
|
|
10546
|
+
process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
|
|
10547
|
+
`);
|
|
10548
|
+
}
|
|
10549
|
+
REGISTRY.set(profile.name, profile);
|
|
10550
|
+
for (const alias of profile.aliases ?? []) {
|
|
10551
|
+
const previous = ALIASES.get(alias);
|
|
10552
|
+
if (previous !== void 0 && previous !== profile.name) {
|
|
10553
|
+
process.stderr.write(
|
|
10554
|
+
`[theokit-sdk] Alias "${alias}" collision: was "${previous}", now "${profile.name}".
|
|
10555
|
+
`
|
|
10556
|
+
);
|
|
10557
|
+
}
|
|
10558
|
+
ALIASES.set(alias, profile.name);
|
|
10559
|
+
}
|
|
10560
|
+
}
|
|
10561
|
+
function getProviderProfile(name) {
|
|
10562
|
+
const canonical = ALIASES.get(name) ?? name;
|
|
10563
|
+
return REGISTRY.get(canonical);
|
|
10564
|
+
}
|
|
10565
|
+
|
|
10566
|
+
// src/internal/providers/catalog-loader.ts
|
|
10567
|
+
var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cron.cjs', document.baseURI).href))));
|
|
10568
|
+
var modelInfoIndex = /* @__PURE__ */ new Map();
|
|
10569
|
+
function getCatalogModelInfo(key) {
|
|
10570
|
+
ensureModelIndexLoaded();
|
|
10571
|
+
return modelInfoIndex.get(key);
|
|
10572
|
+
}
|
|
10573
|
+
var _modelIndexLoaded = false;
|
|
10574
|
+
function ensureModelIndexLoaded() {
|
|
10575
|
+
if (_modelIndexLoaded) return;
|
|
10576
|
+
_modelIndexLoaded = true;
|
|
10577
|
+
const catalog = loadProviderCatalog();
|
|
10578
|
+
for (const entry of Object.values(catalog)) {
|
|
10579
|
+
indexEntryModels(entry);
|
|
10580
|
+
}
|
|
10581
|
+
}
|
|
10582
|
+
function indexEntryModels(entry) {
|
|
10583
|
+
if (entry.models === void 0 || typeof entry.models !== "object") return;
|
|
10584
|
+
for (const [modelId, raw] of Object.entries(entry.models)) {
|
|
10585
|
+
const parsed = catalogModelSchema.safeParse(raw);
|
|
10586
|
+
if (!parsed.success) {
|
|
10587
|
+
process.stderr.write(
|
|
10588
|
+
`[theokit-sdk] WARN: Skipping malformed catalog model "${entry.id}/${modelId}": ${parsed.error.issues[0]?.message ?? "invalid"}
|
|
10589
|
+
`
|
|
10590
|
+
);
|
|
10591
|
+
continue;
|
|
10592
|
+
}
|
|
10593
|
+
modelInfoIndex.set(`${entry.id}/${modelId}`, parsed.data);
|
|
10594
|
+
for (const alias of entry.aliases ?? []) {
|
|
10595
|
+
const key = `${alias}/${modelId}`;
|
|
10596
|
+
if (!modelInfoIndex.has(key)) modelInfoIndex.set(key, parsed.data);
|
|
10597
|
+
}
|
|
10598
|
+
}
|
|
10599
|
+
}
|
|
10600
|
+
function validateEntry(raw) {
|
|
10601
|
+
if (typeof raw.id !== "string" || typeof raw.displayName !== "string" || typeof raw.apiMode !== "string" || typeof raw.authType !== "string" || typeof raw.baseUrl !== "string" || !Array.isArray(raw.envVars) || !Array.isArray(raw.fallbackModels) || raw.capabilities == null || typeof raw.capabilities !== "object") {
|
|
10602
|
+
return null;
|
|
10603
|
+
}
|
|
10604
|
+
return raw;
|
|
10605
|
+
}
|
|
10606
|
+
function loadProviderCatalog(opts) {
|
|
10607
|
+
const catalogPath = path.join(__dirname_resolved, "provider-catalog.json");
|
|
10608
|
+
const rawText = fs.readFileSync(catalogPath, "utf-8");
|
|
10609
|
+
let entries = JSON.parse(rawText);
|
|
10610
|
+
const result = {};
|
|
10611
|
+
for (const raw of entries) {
|
|
10612
|
+
const validated = validateEntry(raw);
|
|
10613
|
+
if (validated === null) {
|
|
10614
|
+
process.stderr.write(
|
|
10615
|
+
`[theokit-sdk] WARN: Skipping malformed catalog entry: ${JSON.stringify(raw).slice(0, 100)}
|
|
10616
|
+
`
|
|
10617
|
+
);
|
|
10618
|
+
continue;
|
|
10619
|
+
}
|
|
10620
|
+
result[validated.id] = validated;
|
|
10621
|
+
}
|
|
10622
|
+
return result;
|
|
10623
|
+
}
|
|
10624
|
+
function registerCatalogProviders(opts) {
|
|
10625
|
+
const catalog = loadProviderCatalog();
|
|
10626
|
+
for (const entry of Object.values(catalog)) {
|
|
10627
|
+
if (getProviderProfile(entry.id) !== void 0) continue;
|
|
10628
|
+
if (entry.aliases?.some((a) => getProviderProfile(a) !== void 0)) continue;
|
|
10629
|
+
const profile = {
|
|
10630
|
+
name: entry.id,
|
|
10631
|
+
apiMode: entry.apiMode,
|
|
10632
|
+
authType: entry.authType,
|
|
10633
|
+
baseUrl: entry.baseUrl,
|
|
10634
|
+
envVars: entry.envVars,
|
|
10635
|
+
fallbackModels: entry.fallbackModels,
|
|
10636
|
+
displayName: entry.displayName,
|
|
10637
|
+
aliases: entry.aliases,
|
|
10638
|
+
modelsUrl: entry.modelsUrl,
|
|
10639
|
+
hostname: entry.hostname,
|
|
10640
|
+
extraHeaders: entry.extraHeaders
|
|
10641
|
+
};
|
|
10642
|
+
registerProvider(profile);
|
|
10643
|
+
}
|
|
10644
|
+
}
|
|
10507
10645
|
|
|
10508
10646
|
// src/internal/budget/pricing-data.json
|
|
10509
10647
|
var pricing_data_default = {
|
|
@@ -10596,9 +10734,9 @@ var pricing_data_default = {
|
|
|
10596
10734
|
cacheRead: 0.025
|
|
10597
10735
|
},
|
|
10598
10736
|
"openai/o3": {
|
|
10599
|
-
input:
|
|
10600
|
-
output:
|
|
10601
|
-
cacheRead:
|
|
10737
|
+
input: 2,
|
|
10738
|
+
output: 8,
|
|
10739
|
+
cacheRead: 0.5
|
|
10602
10740
|
},
|
|
10603
10741
|
"openai/o3-mini": {
|
|
10604
10742
|
input: 1.1,
|
|
@@ -10686,6 +10824,27 @@ function getPricingEntry(opts) {
|
|
|
10686
10824
|
if (found2 !== void 0) return buildEntry(stripped, found2);
|
|
10687
10825
|
}
|
|
10688
10826
|
}
|
|
10827
|
+
const catalogEntry = catalogCostFallback(opts.provider, cleaned);
|
|
10828
|
+
if (catalogEntry !== void 0) return catalogEntry;
|
|
10829
|
+
return void 0;
|
|
10830
|
+
}
|
|
10831
|
+
function catalogCostFallback(provider, cleanedModel) {
|
|
10832
|
+
const keys = [`${provider}/${cleanedModel}`, cleanedModel];
|
|
10833
|
+
for (const key of keys) {
|
|
10834
|
+
const info = getCatalogModelInfo(key);
|
|
10835
|
+
const cost = info?.cost;
|
|
10836
|
+
if (cost === void 0) continue;
|
|
10837
|
+
const [prov, ...modelParts] = key.split("/");
|
|
10838
|
+
return {
|
|
10839
|
+
provider: prov ?? provider,
|
|
10840
|
+
model: modelParts.join("/") || cleanedModel,
|
|
10841
|
+
inputCostPerMillion: cost.input,
|
|
10842
|
+
outputCostPerMillion: cost.output,
|
|
10843
|
+
...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
|
|
10844
|
+
...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
|
|
10845
|
+
pricingVersion: "catalog-vendored"
|
|
10846
|
+
};
|
|
10847
|
+
}
|
|
10689
10848
|
return void 0;
|
|
10690
10849
|
}
|
|
10691
10850
|
|
|
@@ -11202,79 +11361,6 @@ function abortError(signal) {
|
|
|
11202
11361
|
// src/internal/llm/router.ts
|
|
11203
11362
|
init_errors();
|
|
11204
11363
|
|
|
11205
|
-
// src/internal/providers/registry.ts
|
|
11206
|
-
var REGISTRY = /* @__PURE__ */ new Map();
|
|
11207
|
-
var ALIASES = /* @__PURE__ */ new Map();
|
|
11208
|
-
function registerProvider(profile) {
|
|
11209
|
-
if (REGISTRY.has(profile.name)) {
|
|
11210
|
-
process.stderr.write(`[theokit-sdk] Provider "${profile.name}" overridden by user plugin.
|
|
11211
|
-
`);
|
|
11212
|
-
}
|
|
11213
|
-
REGISTRY.set(profile.name, profile);
|
|
11214
|
-
for (const alias of profile.aliases ?? []) {
|
|
11215
|
-
const previous = ALIASES.get(alias);
|
|
11216
|
-
if (previous !== void 0 && previous !== profile.name) {
|
|
11217
|
-
process.stderr.write(
|
|
11218
|
-
`[theokit-sdk] Alias "${alias}" collision: was "${previous}", now "${profile.name}".
|
|
11219
|
-
`
|
|
11220
|
-
);
|
|
11221
|
-
}
|
|
11222
|
-
ALIASES.set(alias, profile.name);
|
|
11223
|
-
}
|
|
11224
|
-
}
|
|
11225
|
-
function getProviderProfile(name) {
|
|
11226
|
-
const canonical = ALIASES.get(name) ?? name;
|
|
11227
|
-
return REGISTRY.get(canonical);
|
|
11228
|
-
}
|
|
11229
|
-
|
|
11230
|
-
// src/internal/providers/catalog-loader.ts
|
|
11231
|
-
var __dirname_resolved = path.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cron.cjs', document.baseURI).href))));
|
|
11232
|
-
function validateEntry(raw) {
|
|
11233
|
-
if (typeof raw.id !== "string" || typeof raw.displayName !== "string" || typeof raw.apiMode !== "string" || typeof raw.authType !== "string" || typeof raw.baseUrl !== "string" || !Array.isArray(raw.envVars) || !Array.isArray(raw.fallbackModels) || raw.capabilities == null || typeof raw.capabilities !== "object") {
|
|
11234
|
-
return null;
|
|
11235
|
-
}
|
|
11236
|
-
return raw;
|
|
11237
|
-
}
|
|
11238
|
-
function loadProviderCatalog(opts) {
|
|
11239
|
-
const catalogPath = path.join(__dirname_resolved, "provider-catalog.json");
|
|
11240
|
-
const rawText = fs.readFileSync(catalogPath, "utf-8");
|
|
11241
|
-
let entries = JSON.parse(rawText);
|
|
11242
|
-
const result = {};
|
|
11243
|
-
for (const raw of entries) {
|
|
11244
|
-
const validated = validateEntry(raw);
|
|
11245
|
-
if (validated === null) {
|
|
11246
|
-
process.stderr.write(
|
|
11247
|
-
`[theokit-sdk] WARN: Skipping malformed catalog entry: ${JSON.stringify(raw).slice(0, 100)}
|
|
11248
|
-
`
|
|
11249
|
-
);
|
|
11250
|
-
continue;
|
|
11251
|
-
}
|
|
11252
|
-
result[validated.id] = validated;
|
|
11253
|
-
}
|
|
11254
|
-
return result;
|
|
11255
|
-
}
|
|
11256
|
-
function registerCatalogProviders(opts) {
|
|
11257
|
-
const catalog = loadProviderCatalog();
|
|
11258
|
-
for (const entry of Object.values(catalog)) {
|
|
11259
|
-
if (getProviderProfile(entry.id) !== void 0) continue;
|
|
11260
|
-
if (entry.aliases?.some((a) => getProviderProfile(a) !== void 0)) continue;
|
|
11261
|
-
const profile = {
|
|
11262
|
-
name: entry.id,
|
|
11263
|
-
apiMode: entry.apiMode,
|
|
11264
|
-
authType: entry.authType,
|
|
11265
|
-
baseUrl: entry.baseUrl,
|
|
11266
|
-
envVars: entry.envVars,
|
|
11267
|
-
fallbackModels: entry.fallbackModels,
|
|
11268
|
-
displayName: entry.displayName,
|
|
11269
|
-
aliases: entry.aliases,
|
|
11270
|
-
modelsUrl: entry.modelsUrl,
|
|
11271
|
-
hostname: entry.hostname,
|
|
11272
|
-
extraHeaders: entry.extraHeaders
|
|
11273
|
-
};
|
|
11274
|
-
registerProvider(profile);
|
|
11275
|
-
}
|
|
11276
|
-
}
|
|
11277
|
-
|
|
11278
11364
|
// src/internal/providers/builtin/anthropic.ts
|
|
11279
11365
|
var ANTHROPIC = {
|
|
11280
11366
|
name: "anthropic",
|