← Public packages
@cameronpak/zo-computer
Typed Zo Computer API client with Result-based error handling and SSE streaming.
src/list-models.ts
59 lines · 1.8 KB · TypeScriptimport { Result } from 'better-result'
import { isRecord, zoJson } from './core'
import { ZoParseError, type ZoRequestError } from './errors'
import type { ZoClientOptions, ZoModel } from './types'
function toModel(raw: unknown): ZoModel | null {
if (!isRecord(raw)) return null
if (typeof raw.model_name !== 'string') return null
return {
modelName: raw.model_name,
label: typeof raw.label === 'string' ? raw.label : raw.model_name,
vendor: typeof raw.vendor === 'string' ? raw.vendor : '',
description: typeof raw.description === 'string' ? raw.description : null,
type: typeof raw.type === 'string' ? raw.type : null,
contextWindow:
typeof raw.context_window === 'number' ? raw.context_window : null,
isByok: raw.is_byok === true,
}
}
/**
* List the models you can pass to `ask` as `modelName`.
*
* This is a read-only call. Use it as a smoke test for a new API key.
*
* @example
* import listModels from 'kody:@cameronpak/zo-computer/list-models'
* const models = await listModels({})
* if (models.status === 'ok') console.log(models.value.length)
*/
export default async function listModels(
params: ZoClientOptions = {},
): Promise<Result<Array<ZoModel>, ZoRequestError>> {
const parsed = await zoJson(
'/models/available',
{ method: 'GET', accept: 'application/json' },
params,
)
if (Result.isError(parsed)) return parsed
const payload = parsed.value
if (!isRecord(payload) || !Array.isArray(payload.models)) {
return Result.err(
new ZoParseError({
url: '/models/available',
body: JSON.stringify(payload).slice(0, 2000),
message: 'Zo response did not contain a models array',
}),
)
}
const models: Array<ZoModel> = []
for (const entry of payload.models) {
const model = toModel(entry)
if (model !== null) models.push(model)
}
return Result.ok(models)
}