Skip to content
← Public packages

@kody/codex

Create and manage OpenAI Agents API (Codex harness) cloud agent sessions.

src/smoke-test.ts

103 lines · 3.2 KB · TypeScript
import { boolean, number, object, optional, parse, string } from 'remix/data-schema'
import {
	DEFAULT_API_KEY_SECRET,
	DOCS_OVERVIEW,
	KEY_PERMISSIONS,
	LIMITATION_NOTE,
	TOKEN_SETUP_URL,
	pickAuth,
	secretSetupUrl,
} from './client.ts'
import overview from './index.ts'
import listSessions from './sessions/list.ts'

const smokeInput = object(
	{
		apiKeySecret: optional(string()),
		/** Force setup guidance / list dryRun without live OpenAI calls. */
		dryRun: optional(boolean()),
		limit: optional(number()),
	},
	{ unknownKeys: 'error' },
)

/**
 * Read-only smoke test: returns setup guidance by default; with a wired
 * `openaiApiKey` secret and dryRun false, lists sessions. Prefer this after
 * publish to verify secret/host wiring without creating agents.
 *
 * @param raw.dryRun - Force dry guidance / list dryRun (default true when unsure)
 * @param raw.limit - List page size for live mode
 * @param raw.apiKeySecret - Optional alternate secret name
 * @returns `{ ok, mode, … }` with clear next steps
 *
 * @example
 * import smokeTest from 'kody:@kody/codex/smoke-test'
 * const result = await smokeTest({ dryRun: true })
 * // => { ok: true, mode: 'setup-guidance', … }
 */
export default async function smokeTest(raw: unknown = {}) {
	const input = parse(smokeInput, raw ?? {})
	const auth = pickAuth(input)
	const secretName = auth.apiKeySecret || DEFAULT_API_KEY_SECRET
	const meta = await overview()
	const forceDry = input.dryRun !== false

	if (forceDry) {
		const preview = await listSessions({
			apiKeySecret: auth.apiKeySecret,
			limit: input.limit ?? 5,
			dryRun: true,
		})
		return {
			ok: true,
			mode: 'setup-guidance' as const,
			package: meta.name,
			limitation: LIMITATION_NOTE,
			docs: DOCS_OVERVIEW,
			secret: {
				name: secretName,
				setupUrl: secretSetupUrl(secretName),
				defaultSetupUrl: TOKEN_SETUP_URL,
				permissions: [...KEY_PERMISSIONS],
				host: 'api.openai.com',
				betaHeader: 'OpenAI-Beta: agents=v1',
			},
			listPreview: preview,
			nextSteps: [
				`Save user secret \`${secretName}\` with allowed host api.openai.com and permissions ${KEY_PERMISSIONS.join(', ')}: ${secretSetupUrl(secretName)}`,
				'Then: import smokeTest from "kody:@kody/codex/smoke-test"; await smokeTest({ dryRun: false })',
				'Create path: kody:@kody/codex/environments/openai-hosted or sessions/create',
			],
			exports: meta.exports,
			pitOfSuccess: meta.pitOfSuccess,
		}
	}

	try {
		const listed = await listSessions({
			apiKeySecret: auth.apiKeySecret,
			limit: input.limit ?? 5,
		})
		return {
			ok: true,
			mode: 'list-sessions' as const,
			count: listed.count,
			data: listed.data,
			has_more: listed.has_more,
			pitOfSuccess: meta.pitOfSuccess,
			limitation: LIMITATION_NOTE,
			note: 'Live list succeeded. Prefer environments/openai-hosted or sessions/create for new work.',
		}
	} catch (error) {
		const message = error instanceof Error ? error.message : String(error)
		return {
			ok: false,
			mode: 'list-failed' as const,
			error: message,
			setupUrl: secretSetupUrl(secretName),
			hint: `Ensure ${secretName} exists, host api.openai.com is allowed, key has ${KEY_PERMISSIONS.join(', ')}, and OpenAI-Beta agents=v1 is accepted.`,
			limitation: LIMITATION_NOTE,
		}
	}
}