← Public packages
@cameronpak/zo-computer
Typed Zo Computer API client with Result-based error handling and SSE streaming.
src/list-personas.ts
54 lines · 1.6 KB · TypeScriptimport { Result } from 'better-result'
import { isRecord, zoJson } from './core'
import { ZoParseError, type ZoRequestError } from './errors'
import type { ZoClientOptions, ZoPersona } from './types'
function toPersona(raw: unknown): ZoPersona | null {
if (!isRecord(raw)) return null
if (typeof raw.id !== 'string') return null
return {
id: raw.id,
name: typeof raw.name === 'string' ? raw.name : raw.id,
prompt: typeof raw.prompt === 'string' ? raw.prompt : '',
model: typeof raw.model === 'string' ? raw.model : null,
image: typeof raw.image === 'string' ? raw.image : null,
}
}
/**
* List the personas you can pass to `ask` as `personaId`.
*
* @example
* import listPersonas from 'kody:@cameronpak/zo-computer/list-personas'
* const personas = await listPersonas({})
* if (personas.status === 'ok') console.log(personas.value.map((p) => p.name))
*/
export default async function listPersonas(
params: ZoClientOptions = {},
): Promise<Result<Array<ZoPersona>, ZoRequestError>> {
const parsed = await zoJson(
'/personas/available',
{ method: 'GET', accept: 'application/json' },
params,
)
if (Result.isError(parsed)) return parsed
const payload = parsed.value
if (!isRecord(payload) || !Array.isArray(payload.personas)) {
return Result.err(
new ZoParseError({
url: '/personas/available',
body: JSON.stringify(payload).slice(0, 2000),
message: 'Zo response did not contain a personas array',
}),
)
}
const personas: Array<ZoPersona> = []
for (const entry of payload.personas) {
const persona = toPersona(entry)
if (persona !== null) personas.push(persona)
}
return Result.ok(personas)
}