{"_id":"@agentiny/anthropic","_rev":"2-26a4975b9c4b27ea8d874295ceb4a9f5","name":"@agentiny/anthropic","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@agentiny/anthropic","version":"0.1.0","keywords":["agent","anthropic","adapter","llm","claude"],"author":{"name":"Thomas Wiegold"},"license":"MIT","_id":"@agentiny/anthropic@0.1.0","maintainers":[{"name":"keldrik","email":"mail@keldrik.com"}],"homepage":"https://github.com/Keldrik/agentiny#readme","bugs":{"url":"https://github.com/Keldrik/agentiny/issues"},"dist":{"shasum":"59019cc92fd39c437d87416b40ff286072b5905f","tarball":"https://registry.npmjs.org/@agentiny/anthropic/-/anthropic-0.1.0.tgz","fileCount":8,"integrity":"sha512-xgGaAUQHHSMtdtc5q/Z6C4hmg1eL0PIyP29MahOZ6eCNDgQL1qxXXmJ+mSydxv9PdiFVTeQod2DB51pcF5whYA==","signatures":[{"sig":"MEUCIQCaWMlLqybRXkVznfq27tpaAuZwfwBfxG1GxqBbsYExGgIgDDHuQ5RsODGwL+p5k3I+53xSDxKfjUsck5UKhHNt06E=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":27161},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"gitHead":"3786539b9293b63a5cfef4f425dbe53e01fbf16e","scripts":{"build":"tsup","typecheck":"tsc --noEmit"},"_npmUser":{"name":"keldrik","email":"mail@keldrik.com"},"repository":{"url":"git+https://github.com/Keldrik/agentiny.git","type":"git"},"_npmVersion":"11.6.2","description":"Anthropic Claude adapter for @agentiny/core","directories":{},"_nodeVersion":"24.6.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.9.3","@types/node":"^24.8.1","@agentiny/core":"*","@anthropic-ai/sdk":"^0.67.0"},"peerDependencies":{"@agentiny/core":"*","@anthropic-ai/sdk":"^0.67.0"},"peerDependenciesMeta":{"@agentiny/core":{"optional":false},"@anthropic-ai/sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/anthropic_0.1.0_1760761649427_0.9095708305471908","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@agentiny/anthropic","version":"0.2.0","description":"Anthropic Claude adapter for @agentiny/core","repository":{"type":"git","url":"git+https://github.com/Keldrik/agentiny.git"},"publishConfig":{"access":"public"},"type":"module","main":"./dist/index.cjs","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist/index.cjs"}},"scripts":{"build":"tsup","typecheck":"tsc --noEmit","test":"vitest","test:run":"vitest run"},"keywords":["agent","anthropic","adapter","llm","claude"],"author":{"name":"Thomas Wiegold"},"license":"MIT","peerDependencies":{"@agentiny/core":"*","@anthropic-ai/sdk":">=0.67.0 <1.0.0","zod":"^3.25 || ^4.0"},"peerDependenciesMeta":{"@agentiny/core":{"optional":false},"@anthropic-ai/sdk":{"optional":false},"zod":{"optional":true}},"devDependencies":{"@agentiny/core":"*","@anthropic-ai/sdk":"^0.117.1","@types/node":"^26.2.0","typescript":"^7.0.2","vitest":"^4.1.10"},"gitHead":"28ba9afd8739d392a39d17a9604347e059198217","_id":"@agentiny/anthropic@0.2.0","bugs":{"url":"https://github.com/Keldrik/agentiny/issues"},"homepage":"https://github.com/Keldrik/agentiny#readme","_nodeVersion":"26.7.0","_npmVersion":"11.19.0","dist":{"integrity":"sha512-F1Dh6blSgZC1/sZ34saZrYYfAJx9PBSwgq+3Cbho2tFShOdS4M6PCt0HDuLHMjOQvcHwFDdFRpnoDq1jQPZkTw==","shasum":"c72b42e93c97ebf483db1fb84471b9da755b3432","tarball":"https://registry.npmjs.org/@agentiny/anthropic/-/anthropic-0.2.0.tgz","fileCount":9,"unpackedSize":101257,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCyfeZKiyybODP19DGbPUJyL/aGS+8JIPKlFylPmLp3kgIgIX3Jyl6NMucscKH6OwL4G6APv4iuBVXBfEezNfcOzAk="}]},"_npmUser":{"name":"keldrik","email":"mail@keldrik.com"},"directories":{},"maintainers":[{"name":"keldrik","email":"mail@keldrik.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/anthropic_0.2.0_1786987242990_0.9091875501671423"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-18T04:27:29.372Z","modified":"2026-08-17T17:20:43.366Z","0.1.0":"2025-10-18T04:27:29.657Z","0.2.0":"2026-08-17T17:20:43.148Z"},"bugs":{"url":"https://github.com/Keldrik/agentiny/issues"},"author":{"name":"Thomas Wiegold"},"license":"MIT","homepage":"https://github.com/Keldrik/agentiny#readme","keywords":["agent","anthropic","adapter","llm","claude"],"repository":{"type":"git","url":"git+https://github.com/Keldrik/agentiny.git"},"description":"Anthropic Claude adapter for @agentiny/core","maintainers":[{"name":"keldrik","email":"mail@keldrik.com"}],"readme":"# @agentiny/anthropic\n\nAnthropic adapter for [@agentiny/core](https://www.npmjs.com/package/@agentiny/core). Turns a state-in / state-out Claude Messages call into an agent `ActionFn`.\n\n## Migration from 0.1.x\n\n`0.2.0` is a breaking change:\n\n- `createAnthropicAction(config, options)` is now a **single options object**.\n- `onResponse` receives a result object. Use `result.text` for the previous string.\n- The default model is still the `claude-haiku-4-5` alias.\n- `maxTokens` is still sent as required `max_tokens` (default 1024).\n\n```typescript\n// 0.1.x\ncreateAnthropicAction(\n  { apiKey: process.env.ANTHROPIC_API_KEY! },\n  {\n    prompt: (state) => state.input,\n    onResponse: (text, state) => {\n      state.output = text;\n    },\n  },\n);\n\n// 0.2.0\ncreateAnthropicAction({\n  apiKey: process.env.ANTHROPIC_API_KEY,\n  prompt: (state) => state.input,\n  onResponse: (result, state) => {\n    state.output = result.text;\n  },\n});\n```\n\n## Installation\n\n```bash\nnpm install @agentiny/core @agentiny/anthropic @anthropic-ai/sdk\n```\n\n### Requirements\n\n- **Node.js** 18+\n- **@agentiny/core** (peer)\n- **@anthropic-ai/sdk** `>=0.67.0 <1.0.0` (peer, install separately)\n- **zod** `^3.25 || ^4.0` (optional peer, only if you pass a Zod schema)\n\n### Other adapters\n\n- [@agentiny/openai](https://www.npmjs.com/package/@agentiny/openai)\n- [@agentiny/gemini](https://www.npmjs.com/package/@agentiny/gemini)\n\n## Quick start\n\n```typescript\nimport { createAnthropicAction } from '@agentiny/anthropic';\nimport { Agent } from '@agentiny/core';\n\ninterface AnalysisState {\n  data: string;\n  analysis?: string;\n}\n\nconst agent = new Agent<AnalysisState>({\n  initialState: { data: '' },\n});\n\nconst analyzeAction = createAnthropicAction({\n  apiKey: process.env.ANTHROPIC_API_KEY,\n  prompt: (state) => `Analyze this: ${state.data}`,\n  onResponse: (result, state) => {\n    state.analysis = result.text;\n  },\n});\n\nagent.addTrigger({\n  id: 'analyze-trigger',\n  check: (state) => !!state.data && !state.analysis,\n  actions: [analyzeAction],\n  repeat: false,\n});\n\nawait agent.start();\nagent.setState({ data: 'What is Claude?' });\n```\n\n## API\n\n### `createAnthropicAction<TState, TParsed>(options)`\n\nCreates an `ActionFn<TState>` that calls the Anthropic Messages API.\n\nThe client is created once in the factory (or taken from `options.client`) and reused. When the agent passes an `ActionContext`, its abort signal is forwarded to the SDK.\n\n#### Client\n\n- `client` (optional) — Existing `Anthropic` instance or compatible client. When set, `apiKey` and `baseURL` are ignored.\n- `apiKey` (optional) — Used when `client` is omitted. The SDK also reads `ANTHROPIC_API_KEY`.\n- `baseURL` (optional) — Custom endpoint. The SDK also reads `ANTHROPIC_BASE_URL`.\n- `model` (optional) — Default: `claude-haiku-4-5`.\n\n#### Prompt (exactly one of `prompt` or `messages`)\n\n- `prompt` — `(state) => string` turned into a single user message.\n- `messages` — `(state) => AnthropicMessage[]` for multi-turn history. Roles must be `user` or `assistant` only.\n- `system` — `string` or `(state) => string`. Sent as the top-level Messages API `system` field, **not** as a `role: 'system'` message.\n\n#### Result\n\n- `onResponse` — `(result, state) => void | Promise<void>`. Always receives:\n\n  | Field          | Meaning                                                                                        |\n  | -------------- | ---------------------------------------------------------------------------------------------- |\n  | `text`         | Concatenated text blocks (empty string if none)                                                |\n  | `data`         | `text` when no `schema`; parsed value when `schema` is set                                     |\n  | `usage`        | `{ promptTokens, completionTokens, totalTokens }` mapped from `input_tokens` / `output_tokens` |\n  | `finishReason` | API `stop_reason`, or `null`                                                                   |\n  | `model`        | Model reported by the API (falls back to the requested model)                                  |\n  | `raw`          | The message or last stream event                                                               |\n\n- `onDelta` — `(delta, state) => void | Promise<void>`. Uses `messages.stream()` when available, otherwise `create({ stream: true })`. `onResponse` still runs once at the end.\n\n#### Generation\n\n- `maxTokens` — Sent as required `max_tokens`. Default: `1024`.\n- `temperature` — Optional passthrough (0–1).\n- `schema` — JSON Schema object, or a Zod-like object with `safeParse`. Enables structured output; `result.data` is the parsed value.\n- `schemaName` — Kept for adapter API parity. Claude’s `output_config.format` has no name field.\n\n## Examples\n\n### Injected client\n\n```typescript\nimport { Anthropic } from '@anthropic-ai/sdk';\nimport { createAnthropicAction } from '@agentiny/anthropic';\n\nconst client = new Anthropic();\n\nconst action = createAnthropicAction({\n  client,\n  prompt: (state) => state.input,\n  onResponse: (result, state) => {\n    state.output = result.text;\n  },\n});\n```\n\n### System prompt and message history\n\nHistory must be `user` / `assistant` turns. The system prompt is a separate field:\n\n```typescript\nconst reply = createAnthropicAction({\n  client,\n  system: 'You are terse.',\n  messages: (state) => state.history,\n  onResponse: (result, state) => {\n    state.history.push({ role: 'assistant', content: result.text });\n  },\n});\n```\n\n### Temperature and max tokens\n\n```typescript\nconst creative = createAnthropicAction({\n  apiKey: process.env.ANTHROPIC_API_KEY,\n  model: 'claude-sonnet-5',\n  prompt: (state) => `Write a short story about: ${state.topic}`,\n  temperature: 0.8,\n  maxTokens: 500,\n  onResponse: (result, state) => {\n    state.story = result.text;\n  },\n});\n```\n\n### Structured output\n\nJSON Schema (sent as `output_config.format`):\n\n```typescript\nconst extract = createAnthropicAction({\n  prompt: (state) => state.email,\n  schema: {\n    type: 'object',\n    additionalProperties: false,\n    properties: {\n      tasks: { type: 'array', items: { type: 'string' } },\n    },\n    required: ['tasks'],\n  },\n  onResponse: (result, state) => {\n    state.tasks = result.data.tasks;\n  },\n});\n```\n\nZod (optional peer — install `zod` yourself):\n\n```typescript\nimport { z } from 'zod';\n\nconst TaskList = z.object({\n  tasks: z.array(z.string()),\n});\n\nconst extract = createAnthropicAction({\n  prompt: (state) => state.email,\n  schema: TaskList,\n  onResponse: (result, state) => {\n    state.tasks = result.data.tasks;\n  },\n});\n```\n\n### Streaming into state\n\n```typescript\nconst stream = createAnthropicAction({\n  prompt: (state) => state.prompt,\n  onDelta: (delta, state) => {\n    state.draft += delta;\n  },\n  onResponse: (result, state) => {\n    state.draft = result.text;\n  },\n});\n```\n\n`onDelta` plus `schema` is allowed: deltas are the raw text (usually JSON), and `result.data` is parsed after the stream ends.\n\n### Chained triggers\n\n```typescript\ninterface ProcessState {\n  text: string;\n  summary?: string;\n  sentiment?: string;\n}\n\nconst agent = new Agent<ProcessState>({\n  initialState: { text: 'Your text here' },\n});\n\nconst client = new Anthropic();\n\nconst summarize = createAnthropicAction({\n  client,\n  prompt: (state) => `Summarize: ${state.text}`,\n  onResponse: (result, state) => {\n    state.summary = result.text;\n  },\n});\n\nconst analyzeSentiment = createAnthropicAction({\n  client,\n  prompt: (state) => `Analyze sentiment of: ${state.summary}`,\n  onResponse: (result, state) => {\n    state.sentiment = result.text;\n  },\n});\n\nagent.addTrigger({\n  id: 'summarize-trigger',\n  check: (state) => !!state.text && !state.summary,\n  actions: [summarize],\n});\n\nagent.addTrigger({\n  id: 'analyze-trigger',\n  check: (state) => !!state.summary && !state.sentiment,\n  actions: [analyzeSentiment],\n});\n```\n\n### Custom endpoint\n\n```typescript\nconst custom = createAnthropicAction({\n  apiKey: process.env.CUSTOM_API_KEY,\n  baseURL: 'https://your-anthropic-compatible-endpoint.example',\n  prompt: (state) => `Process: ${state.data}`,\n  onResponse: (result, state) => {\n    state.result = result.text;\n  },\n});\n```\n\n### Errors and cancellation\n\nAPI errors and abort errors propagate to the agent's `onError`. Long-running calls stop when the agent is paused or stopped because `ctx.signal` is forwarded.\n\n```typescript\nconst agent = new Agent<TextState>({\n  initialState: { input: '' },\n  onError: (error) => {\n    console.error('Agent error:', error.message);\n  },\n});\n```\n\nFor retries, wrap the action with `@agentiny/utils` `withRetry`.\n\n## Models\n\nUse current aliases unless you need a pinned snapshot:\n\n| Alias              | Role                                          |\n| ------------------ | --------------------------------------------- |\n| `claude-haiku-4-5` | Default. Fastest and cheapest.                |\n| `claude-sonnet-5`  | Balanced speed and quality.                   |\n| `claude-opus-5`    | Complex work.                                 |\n| `claude-fable-5`   | Frontier capability. Not the adapter default. |\n\n## Best practices\n\n1. Keep API keys in the environment; pass a shared `client` when you have more than one action.\n2. Prefer aliases (`claude-haiku-4-5`, `claude-sonnet-5`) over dated snapshots.\n3. Set `maxTokens` when you need more or less than the 1024 default. Anthropic requires this field.\n4. Keep conversation history as alternating `user` / `assistant` turns. Put instructions in `system`.\n5. Use `schema` when the next trigger needs structured state.\n\n## Troubleshooting\n\n### \"API key is missing or invalid\"\n\nSet `ANTHROPIC_API_KEY`, pass `apiKey`, or inject a `client` that already has credentials.\n\n### \"Cannot find module '@anthropic-ai/sdk'\"\n\n`@anthropic-ai/sdk` is a peer dependency: `npm install @anthropic-ai/sdk`.\n\n### \"system: Extra inputs are not permitted\" / invalid role\n\nDo not put `{ role: 'system' }` in `messages`. Use the `system` option.\n\n### Rate limit exceeded\n\nWrap the action with `withRetry` from `@agentiny/utils`, or space calls out with a trigger `delay`.\n\n## License\n\nMIT\n\n## See also\n\n- [@agentiny/core](https://www.npmjs.com/package/@agentiny/core)\n- [@agentiny/openai](https://www.npmjs.com/package/@agentiny/openai)\n- [@agentiny/gemini](https://www.npmjs.com/package/@agentiny/gemini)\n- [Anthropic API reference](https://docs.anthropic.com/en/api/messages)\n","readmeFilename":"README.md"}