@fleetagent/pi-ai 0.2.5 → 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 +196 -134
- package/dist/models.generated.d.ts.map +1 -1
- package/dist/models.generated.js +258 -208
- 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"]}
|
|
@@ -4480,6 +4480,27 @@ export declare const MODELS: {
|
|
|
4480
4480
|
contextWindow: number;
|
|
4481
4481
|
maxTokens: number;
|
|
4482
4482
|
};
|
|
4483
|
+
readonly "gpt-6-astra": {
|
|
4484
|
+
id: string;
|
|
4485
|
+
name: string;
|
|
4486
|
+
api: "openai-responses";
|
|
4487
|
+
provider: string;
|
|
4488
|
+
baseUrl: string;
|
|
4489
|
+
reasoning: true;
|
|
4490
|
+
thinkingLevelMap: {
|
|
4491
|
+
off: null;
|
|
4492
|
+
xhigh: string;
|
|
4493
|
+
};
|
|
4494
|
+
input: ("image" | "text")[];
|
|
4495
|
+
cost: {
|
|
4496
|
+
input: number;
|
|
4497
|
+
output: number;
|
|
4498
|
+
cacheRead: number;
|
|
4499
|
+
cacheWrite: number;
|
|
4500
|
+
};
|
|
4501
|
+
contextWindow: number;
|
|
4502
|
+
maxTokens: number;
|
|
4503
|
+
};
|
|
4483
4504
|
readonly o3: {
|
|
4484
4505
|
id: string;
|
|
4485
4506
|
name: string;
|
|
@@ -8868,88 +8889,6 @@ export declare const MODELS: {
|
|
|
8868
8889
|
maxTokens: number;
|
|
8869
8890
|
};
|
|
8870
8891
|
};
|
|
8871
|
-
readonly "kimi-coding": {
|
|
8872
|
-
readonly k3: {
|
|
8873
|
-
id: string;
|
|
8874
|
-
name: string;
|
|
8875
|
-
api: "anthropic-messages";
|
|
8876
|
-
provider: string;
|
|
8877
|
-
baseUrl: string;
|
|
8878
|
-
headers: {
|
|
8879
|
-
"User-Agent": string;
|
|
8880
|
-
};
|
|
8881
|
-
reasoning: true;
|
|
8882
|
-
input: ("image" | "text")[];
|
|
8883
|
-
cost: {
|
|
8884
|
-
input: number;
|
|
8885
|
-
output: number;
|
|
8886
|
-
cacheRead: number;
|
|
8887
|
-
cacheWrite: number;
|
|
8888
|
-
};
|
|
8889
|
-
contextWindow: number;
|
|
8890
|
-
maxTokens: number;
|
|
8891
|
-
};
|
|
8892
|
-
readonly "k3-256k": {
|
|
8893
|
-
id: string;
|
|
8894
|
-
name: string;
|
|
8895
|
-
api: "anthropic-messages";
|
|
8896
|
-
provider: string;
|
|
8897
|
-
baseUrl: string;
|
|
8898
|
-
headers: {
|
|
8899
|
-
"User-Agent": string;
|
|
8900
|
-
};
|
|
8901
|
-
reasoning: true;
|
|
8902
|
-
input: ("image" | "text")[];
|
|
8903
|
-
cost: {
|
|
8904
|
-
input: number;
|
|
8905
|
-
output: number;
|
|
8906
|
-
cacheRead: number;
|
|
8907
|
-
cacheWrite: number;
|
|
8908
|
-
};
|
|
8909
|
-
contextWindow: number;
|
|
8910
|
-
maxTokens: number;
|
|
8911
|
-
};
|
|
8912
|
-
readonly "kimi-for-coding": {
|
|
8913
|
-
id: string;
|
|
8914
|
-
name: string;
|
|
8915
|
-
api: "anthropic-messages";
|
|
8916
|
-
provider: string;
|
|
8917
|
-
baseUrl: string;
|
|
8918
|
-
headers: {
|
|
8919
|
-
"User-Agent": string;
|
|
8920
|
-
};
|
|
8921
|
-
reasoning: true;
|
|
8922
|
-
input: ("image" | "text")[];
|
|
8923
|
-
cost: {
|
|
8924
|
-
input: number;
|
|
8925
|
-
output: number;
|
|
8926
|
-
cacheRead: number;
|
|
8927
|
-
cacheWrite: number;
|
|
8928
|
-
};
|
|
8929
|
-
contextWindow: number;
|
|
8930
|
-
maxTokens: number;
|
|
8931
|
-
};
|
|
8932
|
-
readonly "kimi-for-coding-highspeed": {
|
|
8933
|
-
id: string;
|
|
8934
|
-
name: string;
|
|
8935
|
-
api: "anthropic-messages";
|
|
8936
|
-
provider: string;
|
|
8937
|
-
baseUrl: string;
|
|
8938
|
-
headers: {
|
|
8939
|
-
"User-Agent": string;
|
|
8940
|
-
};
|
|
8941
|
-
reasoning: true;
|
|
8942
|
-
input: ("image" | "text")[];
|
|
8943
|
-
cost: {
|
|
8944
|
-
input: number;
|
|
8945
|
-
output: number;
|
|
8946
|
-
cacheRead: number;
|
|
8947
|
-
cacheWrite: number;
|
|
8948
|
-
};
|
|
8949
|
-
contextWindow: number;
|
|
8950
|
-
maxTokens: number;
|
|
8951
|
-
};
|
|
8952
|
-
};
|
|
8953
8892
|
readonly minimax: {
|
|
8954
8893
|
readonly "MiniMax-M2.7": {
|
|
8955
8894
|
id: string;
|
|
@@ -9567,6 +9506,23 @@ export declare const MODELS: {
|
|
|
9567
9506
|
contextWindow: number;
|
|
9568
9507
|
maxTokens: number;
|
|
9569
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
|
+
};
|
|
9570
9526
|
};
|
|
9571
9527
|
readonly moonshotai: {
|
|
9572
9528
|
readonly "kimi-k2.6": {
|
|
@@ -11139,6 +11095,34 @@ export declare const MODELS: {
|
|
|
11139
11095
|
contextWindow: number;
|
|
11140
11096
|
maxTokens: number;
|
|
11141
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
|
+
};
|
|
11142
11126
|
readonly "gemini-3-flash": {
|
|
11143
11127
|
id: string;
|
|
11144
11128
|
name: string;
|
|
@@ -12136,7 +12120,7 @@ export declare const MODELS: {
|
|
|
12136
12120
|
contextWindow: number;
|
|
12137
12121
|
maxTokens: number;
|
|
12138
12122
|
};
|
|
12139
|
-
readonly "
|
|
12123
|
+
readonly "qwen3.8-flash": {
|
|
12140
12124
|
id: string;
|
|
12141
12125
|
name: string;
|
|
12142
12126
|
api: "anthropic-messages";
|
|
@@ -12674,23 +12658,6 @@ export declare const MODELS: {
|
|
|
12674
12658
|
contextWindow: number;
|
|
12675
12659
|
maxTokens: number;
|
|
12676
12660
|
};
|
|
12677
|
-
readonly "union-alpha": {
|
|
12678
|
-
id: string;
|
|
12679
|
-
name: string;
|
|
12680
|
-
api: "anthropic-messages";
|
|
12681
|
-
provider: string;
|
|
12682
|
-
baseUrl: string;
|
|
12683
|
-
reasoning: true;
|
|
12684
|
-
input: ("image" | "text")[];
|
|
12685
|
-
cost: {
|
|
12686
|
-
input: number;
|
|
12687
|
-
output: number;
|
|
12688
|
-
cacheRead: number;
|
|
12689
|
-
cacheWrite: number;
|
|
12690
|
-
};
|
|
12691
|
-
contextWindow: number;
|
|
12692
|
-
maxTokens: number;
|
|
12693
|
-
};
|
|
12694
12661
|
};
|
|
12695
12662
|
readonly openrouter: {
|
|
12696
12663
|
readonly "aion-labs/aion-2.0": {
|
|
@@ -13704,6 +13671,33 @@ export declare const MODELS: {
|
|
|
13704
13671
|
contextWindow: number;
|
|
13705
13672
|
maxTokens: number;
|
|
13706
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
|
+
};
|
|
13707
13701
|
readonly "deepseek/deepseek-v4-flash-vision-exp": {
|
|
13708
13702
|
id: string;
|
|
13709
13703
|
name: string;
|
|
@@ -15130,23 +15124,6 @@ export declare const MODELS: {
|
|
|
15130
15124
|
contextWindow: number;
|
|
15131
15125
|
maxTokens: number;
|
|
15132
15126
|
};
|
|
15133
|
-
readonly "mistralai/mistral-large-2512": {
|
|
15134
|
-
id: string;
|
|
15135
|
-
name: string;
|
|
15136
|
-
api: "openai-completions";
|
|
15137
|
-
provider: string;
|
|
15138
|
-
baseUrl: string;
|
|
15139
|
-
reasoning: false;
|
|
15140
|
-
input: ("image" | "text")[];
|
|
15141
|
-
cost: {
|
|
15142
|
-
input: number;
|
|
15143
|
-
output: number;
|
|
15144
|
-
cacheRead: number;
|
|
15145
|
-
cacheWrite: number;
|
|
15146
|
-
};
|
|
15147
|
-
contextWindow: number;
|
|
15148
|
-
maxTokens: number;
|
|
15149
|
-
};
|
|
15150
15127
|
readonly "mistralai/mistral-large-2512:batch": {
|
|
15151
15128
|
id: string;
|
|
15152
15129
|
name: string;
|
|
@@ -17375,6 +17352,23 @@ export declare const MODELS: {
|
|
|
17375
17352
|
contextWindow: number;
|
|
17376
17353
|
maxTokens: number;
|
|
17377
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
|
+
};
|
|
17378
17372
|
readonly "qwen/qwen-2.5-72b-instruct": {
|
|
17379
17373
|
id: string;
|
|
17380
17374
|
name: string;
|
|
@@ -18208,7 +18202,7 @@ export declare const MODELS: {
|
|
|
18208
18202
|
contextWindow: number;
|
|
18209
18203
|
maxTokens: number;
|
|
18210
18204
|
};
|
|
18211
|
-
readonly "qwen/qwen3.8-
|
|
18205
|
+
readonly "qwen/qwen3.8-27b:free": {
|
|
18212
18206
|
id: string;
|
|
18213
18207
|
name: string;
|
|
18214
18208
|
api: "openai-completions";
|
|
@@ -18225,7 +18219,7 @@ export declare const MODELS: {
|
|
|
18225
18219
|
contextWindow: number;
|
|
18226
18220
|
maxTokens: number;
|
|
18227
18221
|
};
|
|
18228
|
-
readonly "qwen/qwen3.8-
|
|
18222
|
+
readonly "qwen/qwen3.8-flash": {
|
|
18229
18223
|
id: string;
|
|
18230
18224
|
name: string;
|
|
18231
18225
|
api: "openai-completions";
|
|
@@ -18242,13 +18236,13 @@ export declare const MODELS: {
|
|
|
18242
18236
|
contextWindow: number;
|
|
18243
18237
|
maxTokens: number;
|
|
18244
18238
|
};
|
|
18245
|
-
readonly "
|
|
18239
|
+
readonly "qwen/qwen3.8-max-0902": {
|
|
18246
18240
|
id: string;
|
|
18247
18241
|
name: string;
|
|
18248
18242
|
api: "openai-completions";
|
|
18249
18243
|
provider: string;
|
|
18250
18244
|
baseUrl: string;
|
|
18251
|
-
reasoning:
|
|
18245
|
+
reasoning: true;
|
|
18252
18246
|
input: ("image" | "text")[];
|
|
18253
18247
|
cost: {
|
|
18254
18248
|
input: number;
|
|
@@ -18259,14 +18253,14 @@ export declare const MODELS: {
|
|
|
18259
18253
|
contextWindow: number;
|
|
18260
18254
|
maxTokens: number;
|
|
18261
18255
|
};
|
|
18262
|
-
readonly "
|
|
18256
|
+
readonly "rekaai/reka-edge": {
|
|
18263
18257
|
id: string;
|
|
18264
18258
|
name: string;
|
|
18265
18259
|
api: "openai-completions";
|
|
18266
18260
|
provider: string;
|
|
18267
18261
|
baseUrl: string;
|
|
18268
18262
|
reasoning: false;
|
|
18269
|
-
input: "text"[];
|
|
18263
|
+
input: ("image" | "text")[];
|
|
18270
18264
|
cost: {
|
|
18271
18265
|
input: number;
|
|
18272
18266
|
output: number;
|
|
@@ -18276,14 +18270,14 @@ export declare const MODELS: {
|
|
|
18276
18270
|
contextWindow: number;
|
|
18277
18271
|
maxTokens: number;
|
|
18278
18272
|
};
|
|
18279
|
-
readonly "
|
|
18273
|
+
readonly "relace/relace-search": {
|
|
18280
18274
|
id: string;
|
|
18281
18275
|
name: string;
|
|
18282
18276
|
api: "openai-completions";
|
|
18283
18277
|
provider: string;
|
|
18284
18278
|
baseUrl: string;
|
|
18285
|
-
reasoning:
|
|
18286
|
-
input:
|
|
18279
|
+
reasoning: false;
|
|
18280
|
+
input: "text"[];
|
|
18287
18281
|
cost: {
|
|
18288
18282
|
input: number;
|
|
18289
18283
|
output: number;
|
|
@@ -18293,7 +18287,7 @@ export declare const MODELS: {
|
|
|
18293
18287
|
contextWindow: number;
|
|
18294
18288
|
maxTokens: number;
|
|
18295
18289
|
};
|
|
18296
|
-
readonly "sakana/fugu-
|
|
18290
|
+
readonly "sakana/fugu-max": {
|
|
18297
18291
|
id: string;
|
|
18298
18292
|
name: string;
|
|
18299
18293
|
api: "openai-completions";
|
|
@@ -18310,7 +18304,7 @@ export declare const MODELS: {
|
|
|
18310
18304
|
contextWindow: number;
|
|
18311
18305
|
maxTokens: number;
|
|
18312
18306
|
};
|
|
18313
|
-
readonly "sakana/fugu-ultra
|
|
18307
|
+
readonly "sakana/fugu-ultra": {
|
|
18314
18308
|
id: string;
|
|
18315
18309
|
name: string;
|
|
18316
18310
|
api: "openai-completions";
|
|
@@ -18327,7 +18321,7 @@ export declare const MODELS: {
|
|
|
18327
18321
|
contextWindow: number;
|
|
18328
18322
|
maxTokens: number;
|
|
18329
18323
|
};
|
|
18330
|
-
readonly "sakana/
|
|
18324
|
+
readonly "sakana/fugu-ultra-v2": {
|
|
18331
18325
|
id: string;
|
|
18332
18326
|
name: string;
|
|
18333
18327
|
api: "openai-completions";
|
|
@@ -18344,14 +18338,14 @@ export declare const MODELS: {
|
|
|
18344
18338
|
contextWindow: number;
|
|
18345
18339
|
maxTokens: number;
|
|
18346
18340
|
};
|
|
18347
|
-
readonly "
|
|
18341
|
+
readonly "sakana/sakana-namazu": {
|
|
18348
18342
|
id: string;
|
|
18349
18343
|
name: string;
|
|
18350
18344
|
api: "openai-completions";
|
|
18351
18345
|
provider: string;
|
|
18352
18346
|
baseUrl: string;
|
|
18353
|
-
reasoning:
|
|
18354
|
-
input: "text"[];
|
|
18347
|
+
reasoning: true;
|
|
18348
|
+
input: ("image" | "text")[];
|
|
18355
18349
|
cost: {
|
|
18356
18350
|
input: number;
|
|
18357
18351
|
output: number;
|
|
@@ -18361,14 +18355,14 @@ export declare const MODELS: {
|
|
|
18361
18355
|
contextWindow: number;
|
|
18362
18356
|
maxTokens: number;
|
|
18363
18357
|
};
|
|
18364
|
-
readonly "
|
|
18358
|
+
readonly "sao10k/l3.1-euryale-70b": {
|
|
18365
18359
|
id: string;
|
|
18366
18360
|
name: string;
|
|
18367
18361
|
api: "openai-completions";
|
|
18368
18362
|
provider: string;
|
|
18369
18363
|
baseUrl: string;
|
|
18370
18364
|
reasoning: false;
|
|
18371
|
-
input:
|
|
18365
|
+
input: "text"[];
|
|
18372
18366
|
cost: {
|
|
18373
18367
|
input: number;
|
|
18374
18368
|
output: number;
|
|
@@ -18548,6 +18542,23 @@ export declare const MODELS: {
|
|
|
18548
18542
|
contextWindow: number;
|
|
18549
18543
|
maxTokens: number;
|
|
18550
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
|
+
};
|
|
18551
18562
|
readonly "upstage/solar-pro-3": {
|
|
18552
18563
|
id: string;
|
|
18553
18564
|
name: string;
|
|
@@ -18973,6 +18984,23 @@ export declare const MODELS: {
|
|
|
18973
18984
|
contextWindow: number;
|
|
18974
18985
|
maxTokens: number;
|
|
18975
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
|
+
};
|
|
18976
19004
|
readonly "z-ai/glm-5.3:batch": {
|
|
18977
19005
|
id: string;
|
|
18978
19006
|
name: string;
|
|
@@ -20501,6 +20529,23 @@ export declare const MODELS: {
|
|
|
20501
20529
|
contextWindow: number;
|
|
20502
20530
|
maxTokens: number;
|
|
20503
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
|
+
};
|
|
20504
20549
|
readonly "amazon/nova-2-lite": {
|
|
20505
20550
|
id: string;
|
|
20506
20551
|
name: string;
|
|
@@ -23997,6 +24042,23 @@ export declare const MODELS: {
|
|
|
23997
24042
|
contextWindow: number;
|
|
23998
24043
|
maxTokens: number;
|
|
23999
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
|
+
};
|
|
24000
24062
|
readonly "zai/glm-5v-turbo": {
|
|
24001
24063
|
id: string;
|
|
24002
24064
|
name: string;
|