@fleetagent/pi-ai 0.2.6 → 0.2.7
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/dist/models.d.ts +5 -4
- package/dist/models.d.ts.map +1 -1
- package/dist/models.generated.d.ts +175 -134
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +243 -211
- package/dist/models.generated.js.map +1 -1
- package/dist/models.js.map +1 -1
- package/package.json +1 -1
package/dist/models.d.ts
CHANGED
|
@@ -35,12 +35,13 @@ export declare function resetModelCatalog(): void;
|
|
|
35
35
|
* The upstream format matches the catalog produced by the publish-model-catalog workflow.
|
|
36
36
|
*/
|
|
37
37
|
export declare function refreshModelCatalog(options?: ModelCatalogRefreshOptions): Promise<ModelCatalogRefreshResult>;
|
|
38
|
-
type
|
|
38
|
+
type ModelId<TProvider extends KnownProvider> = TProvider extends keyof typeof MODELS ? keyof (typeof MODELS)[TProvider] : string;
|
|
39
|
+
type ModelApi<TProvider extends KnownProvider, TModelId extends ModelId<TProvider>> = TProvider extends keyof typeof MODELS ? TModelId extends keyof (typeof MODELS)[TProvider] ? (typeof MODELS)[TProvider][TModelId] extends {
|
|
39
40
|
api: infer TApi;
|
|
40
|
-
} ?
|
|
41
|
-
export declare function getModel<TProvider extends KnownProvider, TModelId extends
|
|
41
|
+
} ? TApi extends Api ? TApi : never : never : Api : Api;
|
|
42
|
+
export declare function getModel<TProvider extends KnownProvider, TModelId extends ModelId<TProvider>>(provider: TProvider, modelId: TModelId): Model<ModelApi<TProvider, TModelId>>;
|
|
42
43
|
export declare function getProviders(): KnownProvider[];
|
|
43
|
-
export declare function getModels<TProvider extends KnownProvider>(provider: TProvider): Model<ModelApi<TProvider,
|
|
44
|
+
export declare function getModels<TProvider extends KnownProvider>(provider: TProvider): Model<ModelApi<TProvider, ModelId<TProvider>>>[];
|
|
44
45
|
export declare function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): UsageCost;
|
|
45
46
|
export declare function getSupportedThinkingLevels<TApi extends Api>(model: Model<TApi>): ModelThinkingLevel[];
|
|
46
47
|
export declare function clampThinkingLevel<TApi extends Api>(model: Model<TApi>, level: ModelThinkingLevel): ModelThinkingLevel;
|
package/dist/models.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import { MODELS } from \"./models.generated.ts\";\nimport type { Api, KnownProvider, Model, ModelThinkingLevel, Usage, UsageCost } from \"./types.ts\";\n\nconst MODEL_CATALOG_SCHEMA_VERSION = 1;\n\ninterface ModelCatalogIndexEntry {\n\tminimumPiVersion: string;\n\trevision: string;\n}\n\ninterface ModelCatalogIndex {\n\tschemaVersion: number;\n\tdefaultRevision?: string;\n\tcatalogs?: ModelCatalogIndexEntry[];\n}\n\ninterface CachedModelCatalog {\n\tschemaVersion: number;\n\tindexUrl: string;\n\trevision: string;\n\tfetchedAt: number;\n\tetag?: string;\n\tlastModified?: string;\n\tmodels: Record<string, Record<string, Model<Api>>>;\n}\n\nexport interface ModelCatalogRefreshOptions {\n\t/** URL of the upstream models/v1/index.json catalog index. Defaults to PI_MODEL_CATALOG_URL. */\n\tindexUrl?: string;\n\t/** Persistent cache file. Defaults to PI_MODEL_CATALOG_CACHE_PATH or ~/.cache/pi/model-catalog.json. */\n\tcachePath?: string;\n\t/** Reuse cache without a network request while it is this fresh. Default: 6 hours. */\n\tttlMs?: number;\n\t/** Ignore TTL and conditional validators. */\n\tforce?: boolean;\n\tsignal?: AbortSignal;\n\t/** Test hook. Defaults to global fetch. */\n\tfetch?: typeof fetch;\n\t/** Test hook. Defaults to Date.now(). */\n\tnow?: () => number;\n}\n\nexport interface ModelCatalogRefreshResult {\n\tloaded: boolean;\n\tupdated: boolean;\n\tfromCache: boolean;\n\trevision?: string;\n\tproviderCount: number;\n\tmodelCount: number;\n}\ninterface NodeDirectoryCreationOptions {\n\trecursive: boolean;\n}\n\ninterface ModelCatalogCounts {\n\tproviderCount: number;\n\tmodelCount: number;\n}\n\ntype NodeFs = {\n\texistsSync(path: string): boolean;\n\tmkdirSync(path: string, options: NodeDirectoryCreationOptions): void;\n\treadFileSync(path: string, encoding: BufferEncoding): string;\n\twriteFileSync(path: string, content: string): void;\n};\n\ntype NodeOs = { homedir(): string };\n\ntype NodePath = {\n\tdirname(path: string): string;\n\tjoin(...parts: string[]): string;\n};\n\nfunction getNodeBuiltin<T>(name: string): T | undefined {\n\treturn typeof process === \"undefined\" ? undefined : (process.getBuiltinModule?.(name) as T | undefined);\n}\n\nfunction getNodeModelCatalogCachePath(): string | undefined {\n\tconst os = getNodeBuiltin<NodeOs>(\"os\");\n\tconst path = getNodeBuiltin<NodePath>(\"path\");\n\tif (!os || !path) return undefined;\n\treturn path.join(os.homedir(), \".cache\", \"pi\", \"model-catalog.json\");\n}\n\nconst modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isFinitePositiveNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\nfunction isModelInput(value: unknown): boolean {\n\treturn Array.isArray(value) && value.every((entry) => entry === \"text\" || entry === \"image\");\n}\n\nfunction isModelCost(value: unknown): boolean {\n\tif (!isRecord(value)) return false;\n\tfor (const field of [\"input\", \"output\", \"cacheRead\", \"cacheWrite\"] as const) {\n\t\tif (typeof value[field] !== \"number\" || !Number.isFinite(value[field])) return false;\n\t}\n\treturn true;\n}\n\nfunction isModel(value: unknown, provider: string, id: string): value is Model<Api> {\n\tif (!isRecord(value)) return false;\n\tif (value.id !== id || value.provider !== provider) return false;\n\tif (typeof value.name !== \"string\" || value.name.length === 0) return false;\n\tif (typeof value.api !== \"string\" || value.api.length === 0) return false;\n\tif (typeof value.baseUrl !== \"string\" || value.baseUrl.length === 0) return false;\n\tif (typeof value.reasoning !== \"boolean\") return false;\n\tif (!isModelInput(value.input)) return false;\n\tif (!isModelCost(value.cost)) return false;\n\treturn isFinitePositiveNumber(value.contextWindow) && isFinitePositiveNumber(value.maxTokens);\n}\n\nfunction validateCatalogModels(value: unknown): Record<string, Record<string, Model<Api>>> {\n\tif (!isRecord(value)) throw new Error(\"Model catalog must contain an object\");\n\tconst providers: Record<string, Record<string, Model<Api>>> = {};\n\tfor (const [provider, providerModels] of Object.entries(value)) {\n\t\tif (!isRecord(providerModels)) throw new Error(`Model catalog provider must contain an object: ${provider}`);\n\t\tconst models: Record<string, Model<Api>> = {};\n\t\tfor (const [id, model] of Object.entries(providerModels)) {\n\t\t\tif (!isModel(model, provider, id)) throw new Error(`Invalid model catalog entry: ${provider}/${id}`);\n\t\t\tmodels[id] = model;\n\t\t}\n\t\tproviders[provider] = models;\n\t}\n\treturn providers;\n}\n\nfunction countCatalogModels(models: Record<string, Record<string, Model<Api>>>): ModelCatalogCounts {\n\tlet modelCount = 0;\n\tfor (const providerModels of Object.values(models)) modelCount += Object.keys(providerModels).length;\n\treturn { providerCount: Object.keys(models).length, modelCount };\n}\n\nfunction applyCatalogModels(models: Record<string, Record<string, Model<Api>>>): void {\n\tfor (const [provider, providerModels] of Object.entries(models)) {\n\t\tconst registryProviderModels = modelRegistry.get(provider) ?? new Map<string, Model<Api>>();\n\t\tfor (const [id, model] of Object.entries(providerModels)) {\n\t\t\tregistryProviderModels.set(id, model);\n\t\t}\n\t\tmodelRegistry.set(provider, registryProviderModels);\n\t}\n}\n\nfunction readCachedCatalog(cachePath: string | undefined, indexUrl?: string): CachedModelCatalog | undefined {\n\ttry {\n\t\tif (!cachePath) return undefined;\n\t\tconst fs = getNodeBuiltin<NodeFs>(\"fs\");\n\t\tif (!fs?.existsSync(cachePath)) return undefined;\n\t\tconst parsed = JSON.parse(fs.readFileSync(cachePath, \"utf8\")) as unknown;\n\t\tif (!isRecord(parsed)) return undefined;\n\t\tif (parsed.schemaVersion !== MODEL_CATALOG_SCHEMA_VERSION) return undefined;\n\t\tif (typeof parsed.indexUrl !== \"string\" || typeof parsed.revision !== \"string\") return undefined;\n\t\tif (indexUrl !== undefined && parsed.indexUrl !== indexUrl) return undefined;\n\t\tif (typeof parsed.fetchedAt !== \"number\" || !Number.isFinite(parsed.fetchedAt)) return undefined;\n\t\tconst cached: CachedModelCatalog = {\n\t\t\tschemaVersion: MODEL_CATALOG_SCHEMA_VERSION,\n\t\t\tindexUrl: parsed.indexUrl,\n\t\t\trevision: parsed.revision,\n\t\t\tfetchedAt: parsed.fetchedAt,\n\t\t\tmodels: validateCatalogModels(parsed.models),\n\t\t};\n\t\tif (typeof parsed.etag === \"string\") cached.etag = parsed.etag;\n\t\tif (typeof parsed.lastModified === \"string\") cached.lastModified = parsed.lastModified;\n\t\treturn cached;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction writeCachedCatalog(cachePath: string | undefined, catalog: CachedModelCatalog): void {\n\tconst fs = getNodeBuiltin<NodeFs>(\"fs\");\n\tconst path = getNodeBuiltin<NodePath>(\"path\");\n\tif (!cachePath || !fs || !path) return;\n\tfs.mkdirSync(path.dirname(cachePath), { recursive: true });\n\tfs.writeFileSync(cachePath, `${JSON.stringify(catalog, null, 2)}\\n`);\n}\n\nfunction getCachePath(options?: Pick<ModelCatalogRefreshOptions, \"cachePath\">): string | undefined {\n\tconst envPath = typeof process === \"undefined\" ? undefined : process.env.PI_MODEL_CATALOG_CACHE_PATH;\n\treturn options?.cachePath ?? envPath ?? getNodeModelCatalogCachePath();\n}\n\nfunction getIndexUrl(options?: Pick<ModelCatalogRefreshOptions, \"indexUrl\">): string | undefined {\n\treturn options?.indexUrl ?? (typeof process === \"undefined\" ? undefined : process.env.PI_MODEL_CATALOG_URL);\n}\n\nfunction resolveCatalogUrl(indexUrl: string, revision: string): string {\n\treturn new URL(`revisions/${encodeURIComponent(revision)}/models.json`, indexUrl).toString();\n}\n\nfunction selectRevision(index: ModelCatalogIndex): string | undefined {\n\treturn index.defaultRevision ?? index.catalogs?.at(-1)?.revision;\n}\n\nfunction createResult(\n\tmodels: Record<string, Record<string, Model<Api>>> | undefined,\n\tresult: Pick<ModelCatalogRefreshResult, \"loaded\" | \"updated\" | \"fromCache\" | \"revision\">,\n): ModelCatalogRefreshResult {\n\tconst counts = models ? countCatalogModels(models) : { providerCount: 0, modelCount: 0 };\n\treturn { ...result, ...counts };\n}\n\nfunction getFreshCatalogCache(\n\toptions: ModelCatalogRefreshOptions,\n\tcached: CachedModelCatalog | undefined,\n\tnow: number,\n\tttlMs: number,\n): CachedModelCatalog | undefined {\n\tif (options.force || !cached || now - cached.fetchedAt >= ttlMs) return undefined;\n\treturn cached;\n}\n\nfunction createConditionalCatalogHeaders(\n\toptions: ModelCatalogRefreshOptions,\n\tcached: CachedModelCatalog | undefined,\n): Record<string, string> {\n\tconst headers: Record<string, string> = {};\n\tif (!options.force && cached?.etag) headers[\"If-None-Match\"] = cached.etag;\n\tif (!options.force && cached?.lastModified) headers[\"If-Modified-Since\"] = cached.lastModified;\n\treturn headers;\n}\n\nfunction reuseCachedCatalog(\n\tcachePath: string | undefined,\n\tcached: CachedModelCatalog,\n\tfetchedAt: number,\n): ModelCatalogRefreshResult {\n\tconst refreshedCache = { ...cached, fetchedAt };\n\twriteCachedCatalog(cachePath, refreshedCache);\n\tapplyCatalogModels(refreshedCache.models);\n\treturn createResult(refreshedCache.models, {\n\t\tloaded: true,\n\t\tupdated: false,\n\t\tfromCache: true,\n\t\trevision: refreshedCache.revision,\n\t});\n}\n\nfunction validateCatalogIndex(value: unknown): ModelCatalogIndex {\n\tif (!isRecord(value) || value.schemaVersion !== MODEL_CATALOG_SCHEMA_VERSION) {\n\t\tthrow new Error(\"Unsupported model catalog index schema\");\n\t}\n\treturn value as unknown as ModelCatalogIndex;\n}\n\nfunction initializeStaticRegistry(): void {\n\tmodelRegistry.clear();\n\tfor (const [provider, models] of Object.entries(MODELS)) {\n\t\tconst providerModels = new Map<string, Model<Api>>();\n\t\tfor (const [id, model] of Object.entries(models)) {\n\t\t\tproviderModels.set(id, model as Model<Api>);\n\t\t}\n\t\tmodelRegistry.set(provider, providerModels);\n\t}\n}\n\ninitializeStaticRegistry();\n\n/**\n * Load a previously refreshed model catalog from disk and overlay it on the generated catalog.\n * This is synchronous so callers can update built-in model lists before constructing registries.\n */\nexport function loadCachedModelCatalog(\n\toptions: Pick<ModelCatalogRefreshOptions, \"cachePath\" | \"indexUrl\"> = {},\n): ModelCatalogRefreshResult {\n\tconst cached = readCachedCatalog(getCachePath(options), getIndexUrl(options));\n\tif (!cached) return createResult(undefined, { loaded: false, updated: false, fromCache: true });\n\tapplyCatalogModels(cached.models);\n\treturn createResult(cached.models, {\n\t\tloaded: true,\n\t\tupdated: false,\n\t\tfromCache: true,\n\t\trevision: cached.revision,\n\t});\n}\n\n/** Reset runtime overlays. Intended for tests. */\nexport function resetModelCatalog(): void {\n\tinitializeStaticRegistry();\n}\n\n/**\n * Fetch an upstream model catalog index, cache the selected revision, and overlay it on generated models.\n * The upstream format matches the catalog produced by the publish-model-catalog workflow.\n */\nexport async function refreshModelCatalog(\n\toptions: ModelCatalogRefreshOptions = {},\n): Promise<ModelCatalogRefreshResult> {\n\tconst indexUrl = getIndexUrl(options);\n\tif (!indexUrl) return createResult(undefined, { loaded: false, updated: false, fromCache: false });\n\tconst cachePath = getCachePath(options);\n\tconst cached = readCachedCatalog(cachePath, indexUrl);\n\tconst now = options.now?.() ?? Date.now();\n\tconst ttlMs = options.ttlMs ?? 6 * 60 * 60 * 1000;\n\tconst freshCache = getFreshCatalogCache(options, cached, now, ttlMs);\n\tif (freshCache) {\n\t\tapplyCatalogModels(freshCache.models);\n\t\treturn createResult(freshCache.models, {\n\t\t\tloaded: true,\n\t\t\tupdated: false,\n\t\t\tfromCache: true,\n\t\t\trevision: freshCache.revision,\n\t\t});\n\t}\n\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst headers = createConditionalCatalogHeaders(options, cached);\n\tconst indexResponse = await fetchImpl(indexUrl, { headers, signal: options.signal });\n\tif (indexResponse.status === 304 && cached) return reuseCachedCatalog(cachePath, cached, now);\n\tif (!indexResponse.ok) throw new Error(`Model catalog index request failed: ${indexResponse.status}`);\n\tconst index = validateCatalogIndex(await indexResponse.json());\n\tconst revision = selectRevision(index);\n\tif (!revision) throw new Error(\"Model catalog index does not contain a revision\");\n\tif (!options.force && cached?.revision === revision) return reuseCachedCatalog(cachePath, cached, now);\n\n\tconst catalogResponse = await fetchImpl(resolveCatalogUrl(indexUrl, revision), { signal: options.signal });\n\tif (!catalogResponse.ok) throw new Error(`Model catalog request failed: ${catalogResponse.status}`);\n\tconst models = validateCatalogModels(await catalogResponse.json());\n\tconst nextCached: CachedModelCatalog = {\n\t\tschemaVersion: MODEL_CATALOG_SCHEMA_VERSION,\n\t\tindexUrl,\n\t\trevision,\n\t\tfetchedAt: now,\n\t\tmodels,\n\t};\n\tconst etag = indexResponse.headers.get(\"etag\");\n\tif (etag) nextCached.etag = etag;\n\tconst lastModified = indexResponse.headers.get(\"last-modified\");\n\tif (lastModified) nextCached.lastModified = lastModified;\n\twriteCachedCatalog(cachePath, nextCached);\n\tapplyCatalogModels(models);\n\treturn createResult(models, { loaded: true, updated: true, fromCache: false, revision });\n}\n\ntype ModelApi<\n\tTProvider extends KnownProvider,\n\tTModelId extends keyof (typeof MODELS)[TProvider],\n> = (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi } ? (TApi extends Api ? TApi : never) : never;\n\nexport function getModel<TProvider extends KnownProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(\n\tprovider: TProvider,\n\tmodelId: TModelId,\n): Model<ModelApi<TProvider, TModelId>> {\n\tconst providerModels = modelRegistry.get(provider);\n\treturn providerModels?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;\n}\n\nexport function getProviders(): KnownProvider[] {\n\treturn Array.from(modelRegistry.keys()) as KnownProvider[];\n}\n\nexport function getModels<TProvider extends KnownProvider>(\n\tprovider: TProvider,\n): Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[] {\n\tconst models = modelRegistry.get(provider);\n\treturn models ? (Array.from(models.values()) as Model<ModelApi<TProvider, keyof (typeof MODELS)[TProvider]>>[]) : [];\n}\n\nexport function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): UsageCost {\n\tusage.cost.input = (model.cost.input / 1000000) * usage.input;\n\tusage.cost.output = (model.cost.output / 1000000) * usage.output;\n\tusage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;\n\tusage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n\treturn usage.cost;\n}\n\nconst EXTENDED_THINKING_LEVELS: ModelThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"];\n\nexport function getSupportedThinkingLevels<TApi extends Api>(model: Model<TApi>): ModelThinkingLevel[] {\n\tif (!model.reasoning) return [\"off\"];\n\n\treturn EXTENDED_THINKING_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\nexport function clampThinkingLevel<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tlevel: ModelThinkingLevel,\n): ModelThinkingLevel {\n\tconst availableLevels = getSupportedThinkingLevels(model);\n\tconst availableLevelSet = new Set(availableLevels);\n\tif (availableLevelSet.has(level)) return level;\n\n\tconst requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);\n\tif (requestedIndex === -1) return availableLevels[0] ?? \"off\";\n\n\tfor (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {\n\t\tconst candidate = EXTENDED_THINKING_LEVELS[i];\n\t\tif (availableLevelSet.has(candidate)) return candidate;\n\t}\n\tfor (let i = requestedIndex - 1; i >= 0; i--) {\n\t\tconst candidate = EXTENDED_THINKING_LEVELS[i];\n\t\tif (availableLevelSet.has(candidate)) return candidate;\n\t}\n\treturn availableLevels[0] ?? \"off\";\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual<TApi extends Api>(\n\ta: Model<TApi> | null | undefined,\n\tb: Model<TApi> | null | undefined,\n): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider === b.provider;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import { MODELS } from \"./models.generated.ts\";\nimport type { Api, KnownProvider, Model, ModelThinkingLevel, Usage, UsageCost } from \"./types.ts\";\n\nconst MODEL_CATALOG_SCHEMA_VERSION = 1;\n\ninterface ModelCatalogIndexEntry {\n\tminimumPiVersion: string;\n\trevision: string;\n}\n\ninterface ModelCatalogIndex {\n\tschemaVersion: number;\n\tdefaultRevision?: string;\n\tcatalogs?: ModelCatalogIndexEntry[];\n}\n\ninterface CachedModelCatalog {\n\tschemaVersion: number;\n\tindexUrl: string;\n\trevision: string;\n\tfetchedAt: number;\n\tetag?: string;\n\tlastModified?: string;\n\tmodels: Record<string, Record<string, Model<Api>>>;\n}\n\nexport interface ModelCatalogRefreshOptions {\n\t/** URL of the upstream models/v1/index.json catalog index. Defaults to PI_MODEL_CATALOG_URL. */\n\tindexUrl?: string;\n\t/** Persistent cache file. Defaults to PI_MODEL_CATALOG_CACHE_PATH or ~/.cache/pi/model-catalog.json. */\n\tcachePath?: string;\n\t/** Reuse cache without a network request while it is this fresh. Default: 6 hours. */\n\tttlMs?: number;\n\t/** Ignore TTL and conditional validators. */\n\tforce?: boolean;\n\tsignal?: AbortSignal;\n\t/** Test hook. Defaults to global fetch. */\n\tfetch?: typeof fetch;\n\t/** Test hook. Defaults to Date.now(). */\n\tnow?: () => number;\n}\n\nexport interface ModelCatalogRefreshResult {\n\tloaded: boolean;\n\tupdated: boolean;\n\tfromCache: boolean;\n\trevision?: string;\n\tproviderCount: number;\n\tmodelCount: number;\n}\ninterface NodeDirectoryCreationOptions {\n\trecursive: boolean;\n}\n\ninterface ModelCatalogCounts {\n\tproviderCount: number;\n\tmodelCount: number;\n}\n\ntype NodeFs = {\n\texistsSync(path: string): boolean;\n\tmkdirSync(path: string, options: NodeDirectoryCreationOptions): void;\n\treadFileSync(path: string, encoding: BufferEncoding): string;\n\twriteFileSync(path: string, content: string): void;\n};\n\ntype NodeOs = { homedir(): string };\n\ntype NodePath = {\n\tdirname(path: string): string;\n\tjoin(...parts: string[]): string;\n};\n\nfunction getNodeBuiltin<T>(name: string): T | undefined {\n\treturn typeof process === \"undefined\" ? undefined : (process.getBuiltinModule?.(name) as T | undefined);\n}\n\nfunction getNodeModelCatalogCachePath(): string | undefined {\n\tconst os = getNodeBuiltin<NodeOs>(\"os\");\n\tconst path = getNodeBuiltin<NodePath>(\"path\");\n\tif (!os || !path) return undefined;\n\treturn path.join(os.homedir(), \".cache\", \"pi\", \"model-catalog.json\");\n}\n\nconst modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isFinitePositiveNumber(value: unknown): value is number {\n\treturn typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\nfunction isModelInput(value: unknown): boolean {\n\treturn Array.isArray(value) && value.every((entry) => entry === \"text\" || entry === \"image\");\n}\n\nfunction isModelCost(value: unknown): boolean {\n\tif (!isRecord(value)) return false;\n\tfor (const field of [\"input\", \"output\", \"cacheRead\", \"cacheWrite\"] as const) {\n\t\tif (typeof value[field] !== \"number\" || !Number.isFinite(value[field])) return false;\n\t}\n\treturn true;\n}\n\nfunction isModel(value: unknown, provider: string, id: string): value is Model<Api> {\n\tif (!isRecord(value)) return false;\n\tif (value.id !== id || value.provider !== provider) return false;\n\tif (typeof value.name !== \"string\" || value.name.length === 0) return false;\n\tif (typeof value.api !== \"string\" || value.api.length === 0) return false;\n\tif (typeof value.baseUrl !== \"string\" || value.baseUrl.length === 0) return false;\n\tif (typeof value.reasoning !== \"boolean\") return false;\n\tif (!isModelInput(value.input)) return false;\n\tif (!isModelCost(value.cost)) return false;\n\treturn isFinitePositiveNumber(value.contextWindow) && isFinitePositiveNumber(value.maxTokens);\n}\n\nfunction validateCatalogModels(value: unknown): Record<string, Record<string, Model<Api>>> {\n\tif (!isRecord(value)) throw new Error(\"Model catalog must contain an object\");\n\tconst providers: Record<string, Record<string, Model<Api>>> = {};\n\tfor (const [provider, providerModels] of Object.entries(value)) {\n\t\tif (!isRecord(providerModels)) throw new Error(`Model catalog provider must contain an object: ${provider}`);\n\t\tconst models: Record<string, Model<Api>> = {};\n\t\tfor (const [id, model] of Object.entries(providerModels)) {\n\t\t\tif (!isModel(model, provider, id)) throw new Error(`Invalid model catalog entry: ${provider}/${id}`);\n\t\t\tmodels[id] = model;\n\t\t}\n\t\tproviders[provider] = models;\n\t}\n\treturn providers;\n}\n\nfunction countCatalogModels(models: Record<string, Record<string, Model<Api>>>): ModelCatalogCounts {\n\tlet modelCount = 0;\n\tfor (const providerModels of Object.values(models)) modelCount += Object.keys(providerModels).length;\n\treturn { providerCount: Object.keys(models).length, modelCount };\n}\n\nfunction applyCatalogModels(models: Record<string, Record<string, Model<Api>>>): void {\n\tfor (const [provider, providerModels] of Object.entries(models)) {\n\t\tconst registryProviderModels = modelRegistry.get(provider) ?? new Map<string, Model<Api>>();\n\t\tfor (const [id, model] of Object.entries(providerModels)) {\n\t\t\tregistryProviderModels.set(id, model);\n\t\t}\n\t\tmodelRegistry.set(provider, registryProviderModels);\n\t}\n}\n\nfunction readCachedCatalog(cachePath: string | undefined, indexUrl?: string): CachedModelCatalog | undefined {\n\ttry {\n\t\tif (!cachePath) return undefined;\n\t\tconst fs = getNodeBuiltin<NodeFs>(\"fs\");\n\t\tif (!fs?.existsSync(cachePath)) return undefined;\n\t\tconst parsed = JSON.parse(fs.readFileSync(cachePath, \"utf8\")) as unknown;\n\t\tif (!isRecord(parsed)) return undefined;\n\t\tif (parsed.schemaVersion !== MODEL_CATALOG_SCHEMA_VERSION) return undefined;\n\t\tif (typeof parsed.indexUrl !== \"string\" || typeof parsed.revision !== \"string\") return undefined;\n\t\tif (indexUrl !== undefined && parsed.indexUrl !== indexUrl) return undefined;\n\t\tif (typeof parsed.fetchedAt !== \"number\" || !Number.isFinite(parsed.fetchedAt)) return undefined;\n\t\tconst cached: CachedModelCatalog = {\n\t\t\tschemaVersion: MODEL_CATALOG_SCHEMA_VERSION,\n\t\t\tindexUrl: parsed.indexUrl,\n\t\t\trevision: parsed.revision,\n\t\t\tfetchedAt: parsed.fetchedAt,\n\t\t\tmodels: validateCatalogModels(parsed.models),\n\t\t};\n\t\tif (typeof parsed.etag === \"string\") cached.etag = parsed.etag;\n\t\tif (typeof parsed.lastModified === \"string\") cached.lastModified = parsed.lastModified;\n\t\treturn cached;\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction writeCachedCatalog(cachePath: string | undefined, catalog: CachedModelCatalog): void {\n\tconst fs = getNodeBuiltin<NodeFs>(\"fs\");\n\tconst path = getNodeBuiltin<NodePath>(\"path\");\n\tif (!cachePath || !fs || !path) return;\n\tfs.mkdirSync(path.dirname(cachePath), { recursive: true });\n\tfs.writeFileSync(cachePath, `${JSON.stringify(catalog, null, 2)}\\n`);\n}\n\nfunction getCachePath(options?: Pick<ModelCatalogRefreshOptions, \"cachePath\">): string | undefined {\n\tconst envPath = typeof process === \"undefined\" ? undefined : process.env.PI_MODEL_CATALOG_CACHE_PATH;\n\treturn options?.cachePath ?? envPath ?? getNodeModelCatalogCachePath();\n}\n\nfunction getIndexUrl(options?: Pick<ModelCatalogRefreshOptions, \"indexUrl\">): string | undefined {\n\treturn options?.indexUrl ?? (typeof process === \"undefined\" ? undefined : process.env.PI_MODEL_CATALOG_URL);\n}\n\nfunction resolveCatalogUrl(indexUrl: string, revision: string): string {\n\treturn new URL(`revisions/${encodeURIComponent(revision)}/models.json`, indexUrl).toString();\n}\n\nfunction selectRevision(index: ModelCatalogIndex): string | undefined {\n\treturn index.defaultRevision ?? index.catalogs?.at(-1)?.revision;\n}\n\nfunction createResult(\n\tmodels: Record<string, Record<string, Model<Api>>> | undefined,\n\tresult: Pick<ModelCatalogRefreshResult, \"loaded\" | \"updated\" | \"fromCache\" | \"revision\">,\n): ModelCatalogRefreshResult {\n\tconst counts = models ? countCatalogModels(models) : { providerCount: 0, modelCount: 0 };\n\treturn { ...result, ...counts };\n}\n\nfunction getFreshCatalogCache(\n\toptions: ModelCatalogRefreshOptions,\n\tcached: CachedModelCatalog | undefined,\n\tnow: number,\n\tttlMs: number,\n): CachedModelCatalog | undefined {\n\tif (options.force || !cached || now - cached.fetchedAt >= ttlMs) return undefined;\n\treturn cached;\n}\n\nfunction createConditionalCatalogHeaders(\n\toptions: ModelCatalogRefreshOptions,\n\tcached: CachedModelCatalog | undefined,\n): Record<string, string> {\n\tconst headers: Record<string, string> = {};\n\tif (!options.force && cached?.etag) headers[\"If-None-Match\"] = cached.etag;\n\tif (!options.force && cached?.lastModified) headers[\"If-Modified-Since\"] = cached.lastModified;\n\treturn headers;\n}\n\nfunction reuseCachedCatalog(\n\tcachePath: string | undefined,\n\tcached: CachedModelCatalog,\n\tfetchedAt: number,\n): ModelCatalogRefreshResult {\n\tconst refreshedCache = { ...cached, fetchedAt };\n\twriteCachedCatalog(cachePath, refreshedCache);\n\tapplyCatalogModels(refreshedCache.models);\n\treturn createResult(refreshedCache.models, {\n\t\tloaded: true,\n\t\tupdated: false,\n\t\tfromCache: true,\n\t\trevision: refreshedCache.revision,\n\t});\n}\n\nfunction validateCatalogIndex(value: unknown): ModelCatalogIndex {\n\tif (!isRecord(value) || value.schemaVersion !== MODEL_CATALOG_SCHEMA_VERSION) {\n\t\tthrow new Error(\"Unsupported model catalog index schema\");\n\t}\n\treturn value as unknown as ModelCatalogIndex;\n}\n\nfunction initializeStaticRegistry(): void {\n\tmodelRegistry.clear();\n\tfor (const [provider, models] of Object.entries(MODELS)) {\n\t\tconst providerModels = new Map<string, Model<Api>>();\n\t\tfor (const [id, model] of Object.entries(models)) {\n\t\t\tproviderModels.set(id, model as Model<Api>);\n\t\t}\n\t\tmodelRegistry.set(provider, providerModels);\n\t}\n}\n\ninitializeStaticRegistry();\n\n/**\n * Load a previously refreshed model catalog from disk and overlay it on the generated catalog.\n * This is synchronous so callers can update built-in model lists before constructing registries.\n */\nexport function loadCachedModelCatalog(\n\toptions: Pick<ModelCatalogRefreshOptions, \"cachePath\" | \"indexUrl\"> = {},\n): ModelCatalogRefreshResult {\n\tconst cached = readCachedCatalog(getCachePath(options), getIndexUrl(options));\n\tif (!cached) return createResult(undefined, { loaded: false, updated: false, fromCache: true });\n\tapplyCatalogModels(cached.models);\n\treturn createResult(cached.models, {\n\t\tloaded: true,\n\t\tupdated: false,\n\t\tfromCache: true,\n\t\trevision: cached.revision,\n\t});\n}\n\n/** Reset runtime overlays. Intended for tests. */\nexport function resetModelCatalog(): void {\n\tinitializeStaticRegistry();\n}\n\n/**\n * Fetch an upstream model catalog index, cache the selected revision, and overlay it on generated models.\n * The upstream format matches the catalog produced by the publish-model-catalog workflow.\n */\nexport async function refreshModelCatalog(\n\toptions: ModelCatalogRefreshOptions = {},\n): Promise<ModelCatalogRefreshResult> {\n\tconst indexUrl = getIndexUrl(options);\n\tif (!indexUrl) return createResult(undefined, { loaded: false, updated: false, fromCache: false });\n\tconst cachePath = getCachePath(options);\n\tconst cached = readCachedCatalog(cachePath, indexUrl);\n\tconst now = options.now?.() ?? Date.now();\n\tconst ttlMs = options.ttlMs ?? 6 * 60 * 60 * 1000;\n\tconst freshCache = getFreshCatalogCache(options, cached, now, ttlMs);\n\tif (freshCache) {\n\t\tapplyCatalogModels(freshCache.models);\n\t\treturn createResult(freshCache.models, {\n\t\t\tloaded: true,\n\t\t\tupdated: false,\n\t\t\tfromCache: true,\n\t\t\trevision: freshCache.revision,\n\t\t});\n\t}\n\n\tconst fetchImpl = options.fetch ?? fetch;\n\tconst headers = createConditionalCatalogHeaders(options, cached);\n\tconst indexResponse = await fetchImpl(indexUrl, { headers, signal: options.signal });\n\tif (indexResponse.status === 304 && cached) return reuseCachedCatalog(cachePath, cached, now);\n\tif (!indexResponse.ok) throw new Error(`Model catalog index request failed: ${indexResponse.status}`);\n\tconst index = validateCatalogIndex(await indexResponse.json());\n\tconst revision = selectRevision(index);\n\tif (!revision) throw new Error(\"Model catalog index does not contain a revision\");\n\tif (!options.force && cached?.revision === revision) return reuseCachedCatalog(cachePath, cached, now);\n\n\tconst catalogResponse = await fetchImpl(resolveCatalogUrl(indexUrl, revision), { signal: options.signal });\n\tif (!catalogResponse.ok) throw new Error(`Model catalog request failed: ${catalogResponse.status}`);\n\tconst models = validateCatalogModels(await catalogResponse.json());\n\tconst nextCached: CachedModelCatalog = {\n\t\tschemaVersion: MODEL_CATALOG_SCHEMA_VERSION,\n\t\tindexUrl,\n\t\trevision,\n\t\tfetchedAt: now,\n\t\tmodels,\n\t};\n\tconst etag = indexResponse.headers.get(\"etag\");\n\tif (etag) nextCached.etag = etag;\n\tconst lastModified = indexResponse.headers.get(\"last-modified\");\n\tif (lastModified) nextCached.lastModified = lastModified;\n\twriteCachedCatalog(cachePath, nextCached);\n\tapplyCatalogModels(models);\n\treturn createResult(models, { loaded: true, updated: true, fromCache: false, revision });\n}\n\ntype ModelId<TProvider extends KnownProvider> = TProvider extends keyof typeof MODELS\n\t? keyof (typeof MODELS)[TProvider]\n\t: string;\n\ntype ModelApi<\n\tTProvider extends KnownProvider,\n\tTModelId extends ModelId<TProvider>,\n> = TProvider extends keyof typeof MODELS\n\t? TModelId extends keyof (typeof MODELS)[TProvider]\n\t\t? (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi }\n\t\t\t? TApi extends Api\n\t\t\t\t? TApi\n\t\t\t\t: never\n\t\t\t: never\n\t\t: Api\n\t: Api;\n\nexport function getModel<TProvider extends KnownProvider, TModelId extends ModelId<TProvider>>(\n\tprovider: TProvider,\n\tmodelId: TModelId,\n): Model<ModelApi<TProvider, TModelId>> {\n\tconst providerModels = modelRegistry.get(provider);\n\treturn providerModels?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;\n}\n\nexport function getProviders(): KnownProvider[] {\n\treturn Array.from(modelRegistry.keys()) as KnownProvider[];\n}\n\nexport function getModels<TProvider extends KnownProvider>(\n\tprovider: TProvider,\n): Model<ModelApi<TProvider, ModelId<TProvider>>>[] {\n\tconst models = modelRegistry.get(provider);\n\treturn models ? (Array.from(models.values()) as Model<ModelApi<TProvider, ModelId<TProvider>>>[]) : [];\n}\n\nexport function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): UsageCost {\n\tusage.cost.input = (model.cost.input / 1000000) * usage.input;\n\tusage.cost.output = (model.cost.output / 1000000) * usage.output;\n\tusage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;\n\tusage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n\treturn usage.cost;\n}\n\nconst EXTENDED_THINKING_LEVELS: ModelThinkingLevel[] = [\"off\", \"minimal\", \"low\", \"medium\", \"high\", \"xhigh\"];\n\nexport function getSupportedThinkingLevels<TApi extends Api>(model: Model<TApi>): ModelThinkingLevel[] {\n\tif (!model.reasoning) return [\"off\"];\n\n\treturn EXTENDED_THINKING_LEVELS.filter((level) => {\n\t\tconst mapped = model.thinkingLevelMap?.[level];\n\t\tif (mapped === null) return false;\n\t\tif (level === \"xhigh\") return mapped !== undefined;\n\t\treturn true;\n\t});\n}\n\nexport function clampThinkingLevel<TApi extends Api>(\n\tmodel: Model<TApi>,\n\tlevel: ModelThinkingLevel,\n): ModelThinkingLevel {\n\tconst availableLevels = getSupportedThinkingLevels(model);\n\tconst availableLevelSet = new Set(availableLevels);\n\tif (availableLevelSet.has(level)) return level;\n\n\tconst requestedIndex = EXTENDED_THINKING_LEVELS.indexOf(level);\n\tif (requestedIndex === -1) return availableLevels[0] ?? \"off\";\n\n\tfor (let i = requestedIndex; i < EXTENDED_THINKING_LEVELS.length; i++) {\n\t\tconst candidate = EXTENDED_THINKING_LEVELS[i];\n\t\tif (availableLevelSet.has(candidate)) return candidate;\n\t}\n\tfor (let i = requestedIndex - 1; i >= 0; i--) {\n\t\tconst candidate = EXTENDED_THINKING_LEVELS[i];\n\t\tif (availableLevelSet.has(candidate)) return candidate;\n\t}\n\treturn availableLevels[0] ?? \"off\";\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual<TApi extends Api>(\n\ta: Model<TApi> | null | undefined,\n\tb: Model<TApi> | null | undefined,\n): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider === b.provider;\n}\n"]}
|
|
@@ -8889,88 +8889,6 @@ export declare const MODELS: {
|
|
|
8889
8889
|
maxTokens: number;
|
|
8890
8890
|
};
|
|
8891
8891
|
};
|
|
8892
|
-
readonly "kimi-coding": {
|
|
8893
|
-
readonly k3: {
|
|
8894
|
-
id: string;
|
|
8895
|
-
name: string;
|
|
8896
|
-
api: "anthropic-messages";
|
|
8897
|
-
provider: string;
|
|
8898
|
-
baseUrl: string;
|
|
8899
|
-
headers: {
|
|
8900
|
-
"User-Agent": string;
|
|
8901
|
-
};
|
|
8902
|
-
reasoning: true;
|
|
8903
|
-
input: ("image" | "text")[];
|
|
8904
|
-
cost: {
|
|
8905
|
-
input: number;
|
|
8906
|
-
output: number;
|
|
8907
|
-
cacheRead: number;
|
|
8908
|
-
cacheWrite: number;
|
|
8909
|
-
};
|
|
8910
|
-
contextWindow: number;
|
|
8911
|
-
maxTokens: number;
|
|
8912
|
-
};
|
|
8913
|
-
readonly "k3-256k": {
|
|
8914
|
-
id: string;
|
|
8915
|
-
name: string;
|
|
8916
|
-
api: "anthropic-messages";
|
|
8917
|
-
provider: string;
|
|
8918
|
-
baseUrl: string;
|
|
8919
|
-
headers: {
|
|
8920
|
-
"User-Agent": string;
|
|
8921
|
-
};
|
|
8922
|
-
reasoning: true;
|
|
8923
|
-
input: ("image" | "text")[];
|
|
8924
|
-
cost: {
|
|
8925
|
-
input: number;
|
|
8926
|
-
output: number;
|
|
8927
|
-
cacheRead: number;
|
|
8928
|
-
cacheWrite: number;
|
|
8929
|
-
};
|
|
8930
|
-
contextWindow: number;
|
|
8931
|
-
maxTokens: number;
|
|
8932
|
-
};
|
|
8933
|
-
readonly "kimi-for-coding": {
|
|
8934
|
-
id: string;
|
|
8935
|
-
name: string;
|
|
8936
|
-
api: "anthropic-messages";
|
|
8937
|
-
provider: string;
|
|
8938
|
-
baseUrl: string;
|
|
8939
|
-
headers: {
|
|
8940
|
-
"User-Agent": string;
|
|
8941
|
-
};
|
|
8942
|
-
reasoning: true;
|
|
8943
|
-
input: ("image" | "text")[];
|
|
8944
|
-
cost: {
|
|
8945
|
-
input: number;
|
|
8946
|
-
output: number;
|
|
8947
|
-
cacheRead: number;
|
|
8948
|
-
cacheWrite: number;
|
|
8949
|
-
};
|
|
8950
|
-
contextWindow: number;
|
|
8951
|
-
maxTokens: number;
|
|
8952
|
-
};
|
|
8953
|
-
readonly "kimi-for-coding-highspeed": {
|
|
8954
|
-
id: string;
|
|
8955
|
-
name: string;
|
|
8956
|
-
api: "anthropic-messages";
|
|
8957
|
-
provider: string;
|
|
8958
|
-
baseUrl: string;
|
|
8959
|
-
headers: {
|
|
8960
|
-
"User-Agent": string;
|
|
8961
|
-
};
|
|
8962
|
-
reasoning: true;
|
|
8963
|
-
input: ("image" | "text")[];
|
|
8964
|
-
cost: {
|
|
8965
|
-
input: number;
|
|
8966
|
-
output: number;
|
|
8967
|
-
cacheRead: number;
|
|
8968
|
-
cacheWrite: number;
|
|
8969
|
-
};
|
|
8970
|
-
contextWindow: number;
|
|
8971
|
-
maxTokens: number;
|
|
8972
|
-
};
|
|
8973
|
-
};
|
|
8974
8892
|
readonly minimax: {
|
|
8975
8893
|
readonly "MiniMax-M2.7": {
|
|
8976
8894
|
id: string;
|
|
@@ -9588,6 +9506,23 @@ export declare const MODELS: {
|
|
|
9588
9506
|
contextWindow: number;
|
|
9589
9507
|
maxTokens: number;
|
|
9590
9508
|
};
|
|
9509
|
+
readonly "zai-glm-5-3": {
|
|
9510
|
+
id: string;
|
|
9511
|
+
name: string;
|
|
9512
|
+
api: "mistral-conversations";
|
|
9513
|
+
provider: string;
|
|
9514
|
+
baseUrl: string;
|
|
9515
|
+
reasoning: true;
|
|
9516
|
+
input: "text"[];
|
|
9517
|
+
cost: {
|
|
9518
|
+
input: number;
|
|
9519
|
+
output: number;
|
|
9520
|
+
cacheRead: number;
|
|
9521
|
+
cacheWrite: number;
|
|
9522
|
+
};
|
|
9523
|
+
contextWindow: number;
|
|
9524
|
+
maxTokens: number;
|
|
9525
|
+
};
|
|
9591
9526
|
};
|
|
9592
9527
|
readonly moonshotai: {
|
|
9593
9528
|
readonly "kimi-k2.6": {
|
|
@@ -11160,6 +11095,34 @@ export declare const MODELS: {
|
|
|
11160
11095
|
contextWindow: number;
|
|
11161
11096
|
maxTokens: number;
|
|
11162
11097
|
};
|
|
11098
|
+
readonly "deepseek-v4.1-flash": {
|
|
11099
|
+
id: string;
|
|
11100
|
+
name: string;
|
|
11101
|
+
api: "openai-completions";
|
|
11102
|
+
provider: string;
|
|
11103
|
+
baseUrl: string;
|
|
11104
|
+
compat: {
|
|
11105
|
+
requiresReasoningContentOnAssistantMessages: true;
|
|
11106
|
+
thinkingFormat: "deepseek";
|
|
11107
|
+
};
|
|
11108
|
+
reasoning: true;
|
|
11109
|
+
thinkingLevelMap: {
|
|
11110
|
+
minimal: null;
|
|
11111
|
+
low: null;
|
|
11112
|
+
medium: null;
|
|
11113
|
+
high: string;
|
|
11114
|
+
xhigh: string;
|
|
11115
|
+
};
|
|
11116
|
+
input: ("image" | "text")[];
|
|
11117
|
+
cost: {
|
|
11118
|
+
input: number;
|
|
11119
|
+
output: number;
|
|
11120
|
+
cacheRead: number;
|
|
11121
|
+
cacheWrite: number;
|
|
11122
|
+
};
|
|
11123
|
+
contextWindow: number;
|
|
11124
|
+
maxTokens: number;
|
|
11125
|
+
};
|
|
11163
11126
|
readonly "gemini-3-flash": {
|
|
11164
11127
|
id: string;
|
|
11165
11128
|
name: string;
|
|
@@ -12157,7 +12120,7 @@ export declare const MODELS: {
|
|
|
12157
12120
|
contextWindow: number;
|
|
12158
12121
|
maxTokens: number;
|
|
12159
12122
|
};
|
|
12160
|
-
readonly "
|
|
12123
|
+
readonly "qwen3.8-flash": {
|
|
12161
12124
|
id: string;
|
|
12162
12125
|
name: string;
|
|
12163
12126
|
api: "anthropic-messages";
|
|
@@ -12695,23 +12658,6 @@ export declare const MODELS: {
|
|
|
12695
12658
|
contextWindow: number;
|
|
12696
12659
|
maxTokens: number;
|
|
12697
12660
|
};
|
|
12698
|
-
readonly "union-alpha": {
|
|
12699
|
-
id: string;
|
|
12700
|
-
name: string;
|
|
12701
|
-
api: "anthropic-messages";
|
|
12702
|
-
provider: string;
|
|
12703
|
-
baseUrl: string;
|
|
12704
|
-
reasoning: true;
|
|
12705
|
-
input: ("image" | "text")[];
|
|
12706
|
-
cost: {
|
|
12707
|
-
input: number;
|
|
12708
|
-
output: number;
|
|
12709
|
-
cacheRead: number;
|
|
12710
|
-
cacheWrite: number;
|
|
12711
|
-
};
|
|
12712
|
-
contextWindow: number;
|
|
12713
|
-
maxTokens: number;
|
|
12714
|
-
};
|
|
12715
12661
|
};
|
|
12716
12662
|
readonly openrouter: {
|
|
12717
12663
|
readonly "aion-labs/aion-2.0": {
|
|
@@ -13725,6 +13671,33 @@ export declare const MODELS: {
|
|
|
13725
13671
|
contextWindow: number;
|
|
13726
13672
|
maxTokens: number;
|
|
13727
13673
|
};
|
|
13674
|
+
readonly "deepseek/deepseek-v4-flash-0731:free": {
|
|
13675
|
+
id: string;
|
|
13676
|
+
name: string;
|
|
13677
|
+
api: "openai-completions";
|
|
13678
|
+
provider: string;
|
|
13679
|
+
baseUrl: string;
|
|
13680
|
+
compat: {
|
|
13681
|
+
requiresReasoningContentOnAssistantMessages: true;
|
|
13682
|
+
};
|
|
13683
|
+
reasoning: true;
|
|
13684
|
+
thinkingLevelMap: {
|
|
13685
|
+
minimal: null;
|
|
13686
|
+
low: null;
|
|
13687
|
+
medium: null;
|
|
13688
|
+
high: string;
|
|
13689
|
+
xhigh: string;
|
|
13690
|
+
};
|
|
13691
|
+
input: "text"[];
|
|
13692
|
+
cost: {
|
|
13693
|
+
input: number;
|
|
13694
|
+
output: number;
|
|
13695
|
+
cacheRead: number;
|
|
13696
|
+
cacheWrite: number;
|
|
13697
|
+
};
|
|
13698
|
+
contextWindow: number;
|
|
13699
|
+
maxTokens: number;
|
|
13700
|
+
};
|
|
13728
13701
|
readonly "deepseek/deepseek-v4-flash-vision-exp": {
|
|
13729
13702
|
id: string;
|
|
13730
13703
|
name: string;
|
|
@@ -15151,23 +15124,6 @@ export declare const MODELS: {
|
|
|
15151
15124
|
contextWindow: number;
|
|
15152
15125
|
maxTokens: number;
|
|
15153
15126
|
};
|
|
15154
|
-
readonly "mistralai/mistral-large-2512": {
|
|
15155
|
-
id: string;
|
|
15156
|
-
name: string;
|
|
15157
|
-
api: "openai-completions";
|
|
15158
|
-
provider: string;
|
|
15159
|
-
baseUrl: string;
|
|
15160
|
-
reasoning: false;
|
|
15161
|
-
input: ("image" | "text")[];
|
|
15162
|
-
cost: {
|
|
15163
|
-
input: number;
|
|
15164
|
-
output: number;
|
|
15165
|
-
cacheRead: number;
|
|
15166
|
-
cacheWrite: number;
|
|
15167
|
-
};
|
|
15168
|
-
contextWindow: number;
|
|
15169
|
-
maxTokens: number;
|
|
15170
|
-
};
|
|
15171
15127
|
readonly "mistralai/mistral-large-2512:batch": {
|
|
15172
15128
|
id: string;
|
|
15173
15129
|
name: string;
|
|
@@ -17396,6 +17352,23 @@ export declare const MODELS: {
|
|
|
17396
17352
|
contextWindow: number;
|
|
17397
17353
|
maxTokens: number;
|
|
17398
17354
|
};
|
|
17355
|
+
readonly "prism-ml/ternary-bonsai-2-27b": {
|
|
17356
|
+
id: string;
|
|
17357
|
+
name: string;
|
|
17358
|
+
api: "openai-completions";
|
|
17359
|
+
provider: string;
|
|
17360
|
+
baseUrl: string;
|
|
17361
|
+
reasoning: true;
|
|
17362
|
+
input: ("image" | "text")[];
|
|
17363
|
+
cost: {
|
|
17364
|
+
input: number;
|
|
17365
|
+
output: number;
|
|
17366
|
+
cacheRead: number;
|
|
17367
|
+
cacheWrite: number;
|
|
17368
|
+
};
|
|
17369
|
+
contextWindow: number;
|
|
17370
|
+
maxTokens: number;
|
|
17371
|
+
};
|
|
17399
17372
|
readonly "qwen/qwen-2.5-72b-instruct": {
|
|
17400
17373
|
id: string;
|
|
17401
17374
|
name: string;
|
|
@@ -18229,7 +18202,7 @@ export declare const MODELS: {
|
|
|
18229
18202
|
contextWindow: number;
|
|
18230
18203
|
maxTokens: number;
|
|
18231
18204
|
};
|
|
18232
|
-
readonly "qwen/qwen3.8-
|
|
18205
|
+
readonly "qwen/qwen3.8-27b:free": {
|
|
18233
18206
|
id: string;
|
|
18234
18207
|
name: string;
|
|
18235
18208
|
api: "openai-completions";
|
|
@@ -18246,7 +18219,7 @@ export declare const MODELS: {
|
|
|
18246
18219
|
contextWindow: number;
|
|
18247
18220
|
maxTokens: number;
|
|
18248
18221
|
};
|
|
18249
|
-
readonly "qwen/qwen3.8-
|
|
18222
|
+
readonly "qwen/qwen3.8-flash": {
|
|
18250
18223
|
id: string;
|
|
18251
18224
|
name: string;
|
|
18252
18225
|
api: "openai-completions";
|
|
@@ -18263,13 +18236,13 @@ export declare const MODELS: {
|
|
|
18263
18236
|
contextWindow: number;
|
|
18264
18237
|
maxTokens: number;
|
|
18265
18238
|
};
|
|
18266
|
-
readonly "
|
|
18239
|
+
readonly "qwen/qwen3.8-max-0902": {
|
|
18267
18240
|
id: string;
|
|
18268
18241
|
name: string;
|
|
18269
18242
|
api: "openai-completions";
|
|
18270
18243
|
provider: string;
|
|
18271
18244
|
baseUrl: string;
|
|
18272
|
-
reasoning:
|
|
18245
|
+
reasoning: true;
|
|
18273
18246
|
input: ("image" | "text")[];
|
|
18274
18247
|
cost: {
|
|
18275
18248
|
input: number;
|
|
@@ -18280,14 +18253,14 @@ export declare const MODELS: {
|
|
|
18280
18253
|
contextWindow: number;
|
|
18281
18254
|
maxTokens: number;
|
|
18282
18255
|
};
|
|
18283
|
-
readonly "
|
|
18256
|
+
readonly "rekaai/reka-edge": {
|
|
18284
18257
|
id: string;
|
|
18285
18258
|
name: string;
|
|
18286
18259
|
api: "openai-completions";
|
|
18287
18260
|
provider: string;
|
|
18288
18261
|
baseUrl: string;
|
|
18289
18262
|
reasoning: false;
|
|
18290
|
-
input: "text"[];
|
|
18263
|
+
input: ("image" | "text")[];
|
|
18291
18264
|
cost: {
|
|
18292
18265
|
input: number;
|
|
18293
18266
|
output: number;
|
|
@@ -18297,14 +18270,14 @@ export declare const MODELS: {
|
|
|
18297
18270
|
contextWindow: number;
|
|
18298
18271
|
maxTokens: number;
|
|
18299
18272
|
};
|
|
18300
|
-
readonly "
|
|
18273
|
+
readonly "relace/relace-search": {
|
|
18301
18274
|
id: string;
|
|
18302
18275
|
name: string;
|
|
18303
18276
|
api: "openai-completions";
|
|
18304
18277
|
provider: string;
|
|
18305
18278
|
baseUrl: string;
|
|
18306
|
-
reasoning:
|
|
18307
|
-
input:
|
|
18279
|
+
reasoning: false;
|
|
18280
|
+
input: "text"[];
|
|
18308
18281
|
cost: {
|
|
18309
18282
|
input: number;
|
|
18310
18283
|
output: number;
|
|
@@ -18314,7 +18287,7 @@ export declare const MODELS: {
|
|
|
18314
18287
|
contextWindow: number;
|
|
18315
18288
|
maxTokens: number;
|
|
18316
18289
|
};
|
|
18317
|
-
readonly "sakana/fugu-
|
|
18290
|
+
readonly "sakana/fugu-max": {
|
|
18318
18291
|
id: string;
|
|
18319
18292
|
name: string;
|
|
18320
18293
|
api: "openai-completions";
|
|
@@ -18331,7 +18304,7 @@ export declare const MODELS: {
|
|
|
18331
18304
|
contextWindow: number;
|
|
18332
18305
|
maxTokens: number;
|
|
18333
18306
|
};
|
|
18334
|
-
readonly "sakana/fugu-ultra
|
|
18307
|
+
readonly "sakana/fugu-ultra": {
|
|
18335
18308
|
id: string;
|
|
18336
18309
|
name: string;
|
|
18337
18310
|
api: "openai-completions";
|
|
@@ -18348,7 +18321,7 @@ export declare const MODELS: {
|
|
|
18348
18321
|
contextWindow: number;
|
|
18349
18322
|
maxTokens: number;
|
|
18350
18323
|
};
|
|
18351
|
-
readonly "sakana/
|
|
18324
|
+
readonly "sakana/fugu-ultra-v2": {
|
|
18352
18325
|
id: string;
|
|
18353
18326
|
name: string;
|
|
18354
18327
|
api: "openai-completions";
|
|
@@ -18365,14 +18338,14 @@ export declare const MODELS: {
|
|
|
18365
18338
|
contextWindow: number;
|
|
18366
18339
|
maxTokens: number;
|
|
18367
18340
|
};
|
|
18368
|
-
readonly "
|
|
18341
|
+
readonly "sakana/sakana-namazu": {
|
|
18369
18342
|
id: string;
|
|
18370
18343
|
name: string;
|
|
18371
18344
|
api: "openai-completions";
|
|
18372
18345
|
provider: string;
|
|
18373
18346
|
baseUrl: string;
|
|
18374
|
-
reasoning:
|
|
18375
|
-
input: "text"[];
|
|
18347
|
+
reasoning: true;
|
|
18348
|
+
input: ("image" | "text")[];
|
|
18376
18349
|
cost: {
|
|
18377
18350
|
input: number;
|
|
18378
18351
|
output: number;
|
|
@@ -18382,14 +18355,14 @@ export declare const MODELS: {
|
|
|
18382
18355
|
contextWindow: number;
|
|
18383
18356
|
maxTokens: number;
|
|
18384
18357
|
};
|
|
18385
|
-
readonly "
|
|
18358
|
+
readonly "sao10k/l3.1-euryale-70b": {
|
|
18386
18359
|
id: string;
|
|
18387
18360
|
name: string;
|
|
18388
18361
|
api: "openai-completions";
|
|
18389
18362
|
provider: string;
|
|
18390
18363
|
baseUrl: string;
|
|
18391
18364
|
reasoning: false;
|
|
18392
|
-
input:
|
|
18365
|
+
input: "text"[];
|
|
18393
18366
|
cost: {
|
|
18394
18367
|
input: number;
|
|
18395
18368
|
output: number;
|
|
@@ -18569,6 +18542,23 @@ export declare const MODELS: {
|
|
|
18569
18542
|
contextWindow: number;
|
|
18570
18543
|
maxTokens: number;
|
|
18571
18544
|
};
|
|
18545
|
+
readonly "unbiased/pareto": {
|
|
18546
|
+
id: string;
|
|
18547
|
+
name: string;
|
|
18548
|
+
api: "openai-completions";
|
|
18549
|
+
provider: string;
|
|
18550
|
+
baseUrl: string;
|
|
18551
|
+
reasoning: false;
|
|
18552
|
+
input: ("image" | "text")[];
|
|
18553
|
+
cost: {
|
|
18554
|
+
input: number;
|
|
18555
|
+
output: number;
|
|
18556
|
+
cacheRead: number;
|
|
18557
|
+
cacheWrite: number;
|
|
18558
|
+
};
|
|
18559
|
+
contextWindow: number;
|
|
18560
|
+
maxTokens: number;
|
|
18561
|
+
};
|
|
18572
18562
|
readonly "upstage/solar-pro-3": {
|
|
18573
18563
|
id: string;
|
|
18574
18564
|
name: string;
|
|
@@ -18994,6 +18984,23 @@ export declare const MODELS: {
|
|
|
18994
18984
|
contextWindow: number;
|
|
18995
18985
|
maxTokens: number;
|
|
18996
18986
|
};
|
|
18987
|
+
readonly "z-ai/glm-5.3-flashx": {
|
|
18988
|
+
id: string;
|
|
18989
|
+
name: string;
|
|
18990
|
+
api: "openai-completions";
|
|
18991
|
+
provider: string;
|
|
18992
|
+
baseUrl: string;
|
|
18993
|
+
reasoning: true;
|
|
18994
|
+
input: ("image" | "text")[];
|
|
18995
|
+
cost: {
|
|
18996
|
+
input: number;
|
|
18997
|
+
output: number;
|
|
18998
|
+
cacheRead: number;
|
|
18999
|
+
cacheWrite: number;
|
|
19000
|
+
};
|
|
19001
|
+
contextWindow: number;
|
|
19002
|
+
maxTokens: number;
|
|
19003
|
+
};
|
|
18997
19004
|
readonly "z-ai/glm-5.3:batch": {
|
|
18998
19005
|
id: string;
|
|
18999
19006
|
name: string;
|
|
@@ -20522,6 +20529,23 @@ export declare const MODELS: {
|
|
|
20522
20529
|
contextWindow: number;
|
|
20523
20530
|
maxTokens: number;
|
|
20524
20531
|
};
|
|
20532
|
+
readonly "alibaba/qwen3.8-omni-flash": {
|
|
20533
|
+
id: string;
|
|
20534
|
+
name: string;
|
|
20535
|
+
api: "anthropic-messages";
|
|
20536
|
+
provider: string;
|
|
20537
|
+
baseUrl: string;
|
|
20538
|
+
reasoning: true;
|
|
20539
|
+
input: ("image" | "text")[];
|
|
20540
|
+
cost: {
|
|
20541
|
+
input: number;
|
|
20542
|
+
output: number;
|
|
20543
|
+
cacheRead: number;
|
|
20544
|
+
cacheWrite: number;
|
|
20545
|
+
};
|
|
20546
|
+
contextWindow: number;
|
|
20547
|
+
maxTokens: number;
|
|
20548
|
+
};
|
|
20525
20549
|
readonly "amazon/nova-2-lite": {
|
|
20526
20550
|
id: string;
|
|
20527
20551
|
name: string;
|
|
@@ -24018,6 +24042,23 @@ export declare const MODELS: {
|
|
|
24018
24042
|
contextWindow: number;
|
|
24019
24043
|
maxTokens: number;
|
|
24020
24044
|
};
|
|
24045
|
+
readonly "zai/glm-5.3-flashx": {
|
|
24046
|
+
id: string;
|
|
24047
|
+
name: string;
|
|
24048
|
+
api: "anthropic-messages";
|
|
24049
|
+
provider: string;
|
|
24050
|
+
baseUrl: string;
|
|
24051
|
+
reasoning: true;
|
|
24052
|
+
input: ("image" | "text")[];
|
|
24053
|
+
cost: {
|
|
24054
|
+
input: number;
|
|
24055
|
+
output: number;
|
|
24056
|
+
cacheRead: number;
|
|
24057
|
+
cacheWrite: number;
|
|
24058
|
+
};
|
|
24059
|
+
contextWindow: number;
|
|
24060
|
+
maxTokens: number;
|
|
24061
|
+
};
|
|
24021
24062
|
readonly "zai/glm-5v-turbo": {
|
|
24022
24063
|
id: string;
|
|
24023
24064
|
name: string;
|