Skip to content

Kody is live

Watch the launch video — what Kody is, and why it exists.

← Public packages

@kentcdodds/jev

Call TypeSafe Jev evaluations via Cloudflare AI Gateway (same token/gateway as @kentcdodds/ai).

src/smoke-test.ts

97 lines · 2.2 KB · TypeScript
/**
 * Tiny Jev smoke check. Default is dry (settings/setup only).
 * Pass `{ live: true }` for one cheap noul evaluation.
 *
 * @param input.live - When true, call Jev with a trivial greeting noul question.
 * @returns Setup status, or live `{ ok, status, answers }` without secrets.
 *
 * @example
 * import smokeTest from 'kody:@kentcdodds/jev/smoke-test'
 * const dry = await smokeTest()
 * const live = await smokeTest({ live: true })
 */

import evaluate from './evaluate.ts'
import { missingSetup, secretsNewUrl } from './resolve.ts'
import jevSettings from './settings.ts'

export type SmokeTestInput = {
	live?: boolean
}

/**
 * Tiny Jev smoke check. Default is dry (settings/setup only).
 * Pass `{ live: true }` for one cheap noul evaluation.
 *
 * @param input.live - When true, call Jev with a trivial greeting noul question.
 * @returns Setup status, or live `{ ok, status, answers }` without secrets.
 *
 * @example
 * import smokeTest from 'kody:@kentcdodds/jev/smoke-test'
 * const dry = await smokeTest()
 * const live = await smokeTest({ live: true })
 */
export default async function smokeTest(input: SmokeTestInput = {}) {
	const settings = await jevSettings()
	const ready = Boolean(settings.accountId)

	if (!input.live) {
		return {
			mode: 'dry' as const,
			ready,
			settings: {
				accountIdSet: ready,
				gatewayId: settings.gatewayId,
				model: settings.model,
				sources: settings.sources,
			},
			setup: ready ? undefined : missingSetup(''),
			secretsNewUrl,
		}
	}

	if (!ready) {
		return {
			mode: 'live' as const,
			ok: false as const,
			error: 'cloudflareAccountId is not set',
			setup: missingSetup(''),
			secretsNewUrl,
		}
	}

	const result = await evaluate({
		state: 'hello',
		questions: {
			greeting: {
				type: 'noul',
				instructions: 'Is this a greeting?',
				criteria: {
					true: 'A greeting or hello',
					false: 'Not a greeting',
				},
			},
		},
	})

	if (!result.ok) {
		return {
			mode: 'live' as const,
			ok: false as const,
			status: result.status,
			error: result.error,
			setup: result.setup,
			secretsNewUrl,
		}
	}

	return {
		mode: 'live' as const,
		ok: true as const,
		status: result.status,
		model: result.model,
		answers: result.answers,
		usage: result.usage,
		meta: result.meta,
	}
}