# @kody/ai — agent notes Human setup and intent live in [`README.md`](./README.md). This file is for agents: imports, smoke/dryRun execute snippets, and edge cases. Secrets by **name** only — never paste key values. Do not disable live webhooks or jobs (this package ships none). ## Secrets / storage | Kind | Name | Notes | | --- | --- | --- | | User secret | `openaiApiKey` | Host `api.openai.com` | | User secret | `anthropicApiKey` | Host `api.anthropic.com` | | User secret | `groqApiKey` | Host `api.groq.com` | | User secret | `cloudflareApiToken` | Hosts `api.cloudflare.com`, `gateway.ai.cloudflare.com` | | User secret | `openaiCompatibleApiKey` | Approve the host you pass as `baseUrl` | | Package storage (after fork) | `provider`, `model`, `baseUrl`, `cloudflareAccountId`, `cloudflareAiGatewayId` | Readable defaults via `./settings` | Multi-account: `account: "work"` → `openaiApiKey-work` (or matching provider secret), or pass `apiKeySecret` explicitly. Live `@kody/ai` storage is the platform bucket — fork (or invoke the user's copy) before writing defaults. ## Import paths | Export | Import | | --- | --- | | root dispatcher / re-exports | `kody:@kody/ai` | | one chat completion (`generateText`) | `kody:@kody/ai/complete` | | structured JSON (`generateObject`) | `kody:@kody/ai/generate-object` | | model-only step + default tool schemas | `kody:@kody/ai/model-step` | | optional tool-using agent turn | `kody:@kody/ai/turn` | | fork-local provider/model defaults | `kody:@kody/ai/settings` | | console steps / prefilled secret URLs | `kody:@kody/ai/guide` | | smoke-test | `kody:@kody/ai/smoke-test` | | types | `kody:@kody/ai/types` | Prefer static `kody:@kody/ai/...` imports from `execute`. Do not lead with `packages.invoke`. Prefer `runModelStep` when a host package should execute tools in its own package context (correct secret allowlists). `runAgentTurn` still runs tools as package `ai`. ## Smoke test (read-only) Safe before credentials: returns `{ ok: true, live: false }` plus setup URLs. With a secret and host approval, lists models only — no completion tokens. ```js import smokeTest from 'kody:@kody/ai/smoke-test' export default async function main() { return await smokeTest() } ``` Equivalent via root: ```js import ai from 'kody:@kody/ai' export default async function main() { return await ai() } ``` ## dryRun / confirm `./settings` writes **default to dry-run** and need `confirm: true`. Completions are live when you pass messages (that is the helper). Pass `dryRun: true` to preview the provider, model, URL, and body without calling the vendor. ```js import { generateText } from 'kody:@kody/ai' export default async function main() { return await generateText({ provider: 'openai', messages: [{ role: 'user', content: 'Say hello in one word.' }], dryRun: true, }) } ``` Live completion after the secret exists: ```js import { generateText } from 'kody:@kody/ai' export default async function main() { return await generateText({ provider: 'openai', messages: [{ role: 'user', content: 'Say hello in one word.' }], }) } ``` Structured JSON: ```js import { generateObject } from 'kody:@kody/ai' export default async function main() { return await generateObject({ provider: 'openai', messages: [{ role: 'user', content: 'Label this: I love this package' }], schema: { type: 'object', properties: { label: { type: 'string', enum: ['positive', 'neutral', 'negative'] }, }, required: ['label'], additionalProperties: false, }, dryRun: true, }) } ``` ## Edge cases | Symptom | What to do | | --- | --- | | Missing API key / 401 | Save the provider secret and approve its host | | Cloudflare missing account | Fork, then `./settings` with `cloudflareAccountId` and `confirm: true` | | openai-compatible missing baseUrl | Pass `baseUrl` (https) or store it in `./settings` on your fork | | Unknown provider | Use `openai`, `anthropic`, `groq`, `cloudflare`, or `openai-compatible` |