Skip to content
← Public packages

@cameronpak/zo-computer

Typed Zo Computer API client with Result-based error handling and SSE streaming.

src/types.ts

105 lines · 2.6 KB · TypeScript
/**
 * Options every request accepts.
 */
export type ZoClientOptions = {
	/**
	 * Zo API key. Omit this to use the `ZO_API_KEY` Kody secret.
	 *
	 * Pass a literal key only when you already hold one, for example in a test.
	 */
	apiKey?: string
	/** Override the API origin. Defaults to `https://api.zo.computer`. */
	baseUrl?: string
	/** Abort signal forwarded to `fetch`. */
	signal?: AbortSignal
	/** Retry policy for network failures. Retries never apply to 4xx or 5xx. */
	retry?: ZoRetryOptions
}

/**
 * Retry policy for network-level failures.
 */
export type ZoRetryOptions = {
	/** Maximum retries after the first attempt. */
	times: number
	/** Delay before the first retry, in milliseconds. Defaults to 250. */
	delayMs?: number
	/** Backoff curve. Defaults to `exponential`. */
	backoff?: 'constant' | 'linear' | 'exponential'
	/** Add randomness to each delay. Defaults to true. */
	jitter?: boolean
}

/**
 * Input for a single `/zo/ask` call.
 */
export type ZoAskInput = {
	/** The message you send to Zo. Required. */
	input: string
	/** Continue an existing conversation. */
	conversationId?: string
	/** Model name from `listModels`. */
	modelName?: string
	/** Persona id from `listPersonas`. */
	personaId?: string
	/** JSON Schema. Zo returns `output` as an object when you set this. */
	outputFormat?: Record<string, unknown>
}

/**
 * A completed `/zo/ask` response.
 */
export type ZoAskResult = {
	/** A string, or an object when you set `outputFormat`. */
	output: string | Record<string, unknown>
	/** Pass this back as `conversationId` to continue the thread. */
	conversationId: string
}

/**
 * One model you can pass as `modelName`.
 */
export type ZoModel = {
	modelName: string
	label: string
	vendor: string
	description: string | null
	type: string | null
	contextWindow: number | null
	isByok: boolean
}

/**
 * One persona you can pass as `personaId`.
 */
export type ZoPersona = {
	id: string
	name: string
	prompt: string
	model: string | null
	image: string | null
}

/**
 * One Server-Sent Event from a streaming `/zo/ask` call.
 *
 * `data` holds the parsed JSON payload, or the raw string when the payload is
 * not JSON.
 */
export type ZoStreamEvent = {
	/** Event name. Zo documents `FrontendModelResponse`, `End`, and `Error`. */
	event: string
	data: unknown
	/** The raw `data:` text, before parsing. */
	raw: string
}

/**
 * An open stream plus the conversation id Zo returned in the response headers.
 */
export type ZoStream = {
	/** Value of the `x-conversation-id` header, when Zo sent one. */
	conversationId: string | null
	/** Iterate this to read events in order. */
	events: AsyncIterable<ZoStreamEvent>
}