← Public packages
@kentcdodds/jev
Call TypeSafe Jev evaluations via Cloudflare AI Gateway (same token/gateway as @kentcdodds/ai).
AGENTS.md
93 lines · 2.9 KB · Markdown@kentcdodds/jev — agent notes
Human setup and intent live in README.md. This file is for
agents: imports, smoke checks, snippets, and edge cases. Secrets by name
only — never paste token values.
Secret / storage
- Secret name:
cloudflareApiToken(user scope) — placeholder{{secret:cloudflareApiToken}}in fetch headers only - Hosts:
api.cloudflare.com(required for/ai/run);gateway.ai.cloudflare.comoptional for shared@kentcdodds/aichat path - Package storage (via
./settings, no republish):cloudflareAccountId,cloudflareAiGatewayId(optional; defaultkody),cloudflareJevModel(optional; defaulttypesafe/jev) - When Jev storage is empty, resolve uses
packages.invokeon@kentcdodds/ai/settings(target package runtime) for accountId + gatewayId, then caches into Jev storage. Statickody:@stamp cannot see ai storage.
Import paths
| Export | Import |
|---|---|
| overview / checklist | kody:@kentcdodds/jev |
| evaluate (preferred) | kody:@kentcdodds/jev/evaluate |
raw /ai/run | kody:@kentcdodds/jev/request |
| settings read/write | kody:@kentcdodds/jev/settings |
| types | kody:@kentcdodds/jev/types |
| smoke dry/live | kody:@kentcdodds/jev/smoke-test |
Prefer static kody:@kentcdodds/jev/... imports from execute. Do not lead with
packages.invoke.
Smoke / dry checks
Dry (no model spend):
import smokeTest from 'kody:@kentcdodds/jev/smoke-test'
export default async function main() {
return await smokeTest()
}Live tiny noul:
import smokeTest from 'kody:@kentcdodds/jev/smoke-test'
export default async function main() {
return await smokeTest({ live: true })
// => { ok, status, answers, model, usage } — no tokens
}Main helper:
import evaluate from 'kody:@kentcdodds/jev/evaluate'
export default async function main() {
return await evaluate({
state: 'hello',
questions: {
greeting: { type: 'noul', instructions: 'Is this a greeting?' },
},
})
}Gateway call shape
POST https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/run
- Header
Authorization: Bearer {{secret:cloudflareApiToken}} - Header
cf-aig-gateway-id: {gatewayId} - Body
{ model: "typesafe/jev", input: { state, questions } }
Edge cases
- If accountId is missing, exports return
setup.secretsNewUrlinstead of throwing loudly. - Never log Authorization headers or secret placeholders into returned chat text.
- Question types:
noul(boolean probability),choice(criteria map),score(criteria array). Cloudflare docs usenoul; Vercel AI SDK may label the boolean type differently — this package follows Cloudflare. - Prefer
./evaluatefor parsed answers;./requestwhen you need the raw Cloudflare envelope. - HTTP 402 from
/ai/runmeans AI Gateway Unified Billing needs credits (or configure TypeSafe BYOK) — not a missing secret.