@warlock.js/ai-anthropic 4.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/llms-full.txt ADDED
@@ -0,0 +1,143 @@
1
+ # Warlock AI Anthropic — full skills
2
+
3
+ > Package: `@warlock.js/ai-anthropic`
4
+
5
+ > Generated artifact. Concatenates every SKILL.md and reference file under `@warlock.js/ai-anthropic/skills/`. Re-run `node scripts/generate-llms.mjs` after any change.
6
+
7
+ ## setup-anthropic `@warlock.js/ai-anthropic/setup-anthropic/SKILL.md`
8
+
9
+ ---
10
+ name: setup-anthropic
11
+ description: 'Wire @warlock.js/ai-anthropic — new AnthropicSDK({apiKey, baseURL?, provider?}) for Claude, .model({name, vision?, structuredOutput?, maxTokens?}). System-prompt hoisting, max_tokens required (default 4096), no first-party embeddings. Triggers: `AnthropicSDK`, `anthropic.model`, `anthropic.count`, `maxTokens`, `claude-sonnet-4-6`, `claude-haiku-4-5`, `claude-opus-4-7`; "wire claude into warlock agent", "configure anthropic provider", "use claude sonnet", "anthropic gateway baseURL"; typical import `import { AnthropicSDK } from "@warlock.js/ai-anthropic"`. Skip: embeddings — `@warlock.js/ai-openai/setup-openai/SKILL.md`; sibling adapters `@warlock.js/ai-openai`, `@warlock.js/ai-bedrock`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `@anthropic-ai/sdk`; Vercel `@ai-sdk/anthropic`.'
12
+ ---
13
+
14
+ # `@warlock.js/ai-anthropic`
15
+
16
+ Provider adapter that turns Anthropic's Messages API into a vendor-neutral `ModelContract`. Mirrors `@warlock.js/ai-openai` — same shape, Claude-specific wire mapping.
17
+
18
+ ## Construction
19
+
20
+ ```ts
21
+ import { AnthropicSDK } from "@warlock.js/ai-anthropic";
22
+
23
+ const anthropic = new AnthropicSDK({ apiKey: process.env.ANTHROPIC_API_KEY! });
24
+
25
+ // Proxied / gateway endpoints speaking the Anthropic protocol:
26
+ const proxied = new AnthropicSDK({
27
+ apiKey: process.env.GATEWAY_KEY!,
28
+ baseURL: "https://gateway.internal/anthropic",
29
+ provider: "anthropic-proxy",
30
+ });
31
+ ```
32
+
33
+ `AnthropicSDK` is a class with a long-lived `Anthropic` client. `provider` defaults to `"anthropic"`.
34
+
35
+ ## Producing a model
36
+
37
+ ```ts
38
+ anthropic.model({ name: "claude-sonnet-4-6" }) // common case
39
+ anthropic.model({ name: "claude-haiku-4-5", temperature: 0.2 }) // sampling controls
40
+ anthropic.model({ name: "claude-opus-4-7", maxTokens: 8192 }) // raise the cap
41
+ ```
42
+
43
+ ## Capabilities — what's auto-set
44
+
45
+ | Flag | Default |
46
+ | --- | --- |
47
+ | `structuredOutput` | `true` (via Anthropic's native `output_config.format`) |
48
+ | `vision` | Inferred from model name. `true` for Claude 3 / 3.5 / 3.7 / 4 family; `false` for pre-3 and unknown. |
49
+
50
+ Explicit config always wins.
51
+
52
+ ## Pricing & cost
53
+
54
+ Pricing is opt-in. Supply USD-per-million-token rates and every report this SDK's models produce carries `Usage.cost`; omit them and `cost` stays `undefined` (honest absence, never a false zero). Two declaration sites:
55
+
56
+ ```ts
57
+ // SDK-level registry — one source of truth, keyed by model name:
58
+ const anthropic = new AnthropicSDK({
59
+ apiKey,
60
+ pricing: {
61
+ "claude-haiku-4-5": { input: 1, output: 5, cachedInput: 0.1 },
62
+ "claude-sonnet-4-6": { input: 3, output: 15, cachedInput: 0.3 },
63
+ },
64
+ });
65
+
66
+ // Per-model override (multi-tenant / contract-specific rates):
67
+ anthropic.model({ name: "claude-sonnet-4-6", pricing: { input: 3, output: 15 } });
68
+ ```
69
+
70
+ Resolution at `model()` time: per-model `pricing` > SDK registry entry for that name > `undefined`. `ModelPricing` is `{ input, output, cachedInput?, cachedOutput? }`. Anthropic meters cache **reads** — when present they surface as `usage.cachedTokens` and bill at the `cachedInput` rate (falling back to `input` when unset).
71
+
72
+ ## `max_tokens` is required
73
+
74
+ Unlike OpenAI, Anthropic **requires** `max_tokens` on every request. Resolution: per-call `options.maxTokens` > `config.maxTokens` > **default `4096`**. A caller who never sets a cap still gets a complete answer instead of a 400.
75
+
76
+ ## System prompt
77
+
78
+ Anthropic has no `"system"` role inside `messages`. The adapter hoists every neutral `role: "system"` message into the top-level `system` parameter (multiple system messages join with a blank line). Transparent to the agent.
79
+
80
+ ## Tool calls
81
+
82
+ - Outgoing: vendor-neutral tools → Anthropic `tools` with `input_schema` (non-object schemas degrade to a parameterless object so registration never fails).
83
+ - Assistant tool calls in history → `assistant` message with an optional leading `text` block + one `tool_use` block per call.
84
+ - Tool results (`role: "tool"`) → a `user` turn carrying a single `tool_result` block keyed by `tool_use_id`.
85
+ - Response `tool_use` blocks → neutral `toolCalls`; `stop_reason: "tool_use"` → `finishReason: "tool_calls"`.
86
+
87
+ ## Structured output
88
+
89
+ When the agent passes `responseSchema` and the model is `structuredOutput`-capable, an **object-root** schema is forwarded as `output_config: { format: { type: "json_schema", schema } }` (Anthropic native). Non-object schemas or `structuredOutput: false` omit it; the agent's soft system-prompt hint + client-side `validate()` still enforce shape.
90
+
91
+ ## Multipart messages (vision)
92
+
93
+ `ContentPart[]` user content maps to Anthropic content blocks:
94
+
95
+ - `{ type: "text", text }` → `{ type: "text", text }`
96
+ - `{ type: "image", source: { url } }` → `{ type: "image", source: { type: "url", url } }`
97
+ - `{ type: "image", source: { base64, mediaType } }` → `{ type: "image", source: { type: "base64", media_type, data } }`
98
+
99
+ ## Streaming
100
+
101
+ `model.stream()` drains `messages.create({ stream: true })`:
102
+
103
+ - `content_block_delta` text → `{ type: "delta", content }`
104
+ - `tool_use` blocks accumulate `input_json_delta` fragments and emit one consolidated `{ type: "tool-call", ... }` at `content_block_stop` (no partial-arg `{}` artifact — input is parsed once, whole)
105
+ - terminal `{ type: "done", finishReason, usage }` — `usage.input` from `message_start`, `usage.output` from `message_delta`, `total` computed
106
+
107
+ ## Finish-reason mapping
108
+
109
+ `end_turn` / `stop_sequence` → `stop` · `max_tokens` → `length` · `tool_use` → `tool_calls` · `refusal` / `pause_turn` / unknown / null → `error`.
110
+
111
+ ## Errors
112
+
113
+ Raw SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy. Dispatch keys on `error.type` (Anthropic has no per-error machine `code`), falling back to HTTP status:
114
+
115
+ - `authentication_error` / `permission_error` / 401 / 403 → `ProviderAuthError`
116
+ - `rate_limit_error` / 429 → `ProviderRateLimitError` (+`retryAfter` from `retry-after`)
117
+ - `billing_error` → `QuotaExceededError`
118
+ - `invalid_request_error` with "prompt is too long" → `ContextLengthExceededError`, else `InvalidRequestError`
119
+ - 5xx / overloaded → `ProviderError`
120
+ - Connection timeouts → `ProviderTimeoutError`
121
+
122
+ ## Token counting
123
+
124
+ ```ts
125
+ await anthropic.count("some text") // approximate heuristic, offline
126
+ ```
127
+
128
+ ## No embeddings
129
+
130
+ Anthropic ships no first-party embeddings API, so `AnthropicSDK` intentionally does **not** implement `embedder()` (the `SDKAdapterContract.embedder` slot is optional). Use [`@warlock.js/ai-openai`](@warlock.js/ai-openai/setup-openai/SKILL.md) (or another embeddings-capable adapter) for vectors.
131
+
132
+ ## When NOT to use this skill
133
+
134
+ - Direct calls to `@anthropic-ai/sdk` without going through `@warlock.js/ai` agents.
135
+ - OpenAI / Bedrock / Gemini / Ollama models — those have their own adapter packages.
136
+
137
+ ## See also
138
+
139
+ - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md)
140
+ - [`@warlock.js/ai/pick-ai-provider/SKILL.md`](@warlock.js/ai/pick-ai-provider/SKILL.md)
141
+ - [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md)
142
+
143
+
package/llms.txt ADDED
@@ -0,0 +1,9 @@
1
+ # Warlock AI Anthropic
2
+
3
+ > Package: `@warlock.js/ai-anthropic`
4
+
5
+ > Anthropic SDK adapter for @warlock.js/ai
6
+
7
+ ## Skills
8
+
9
+ - [setup-anthropic](@warlock.js/ai-anthropic/setup-anthropic/SKILL.md): Wire @warlock.js/ai-anthropic — new AnthropicSDK({apiKey, baseURL?, provider?}) for Claude, .model({name, vision?, structuredOutput?, maxTokens?}). System-prompt hoisting, max_tokens required (default 4096), no first-party embeddings. Triggers: `AnthropicSDK`, `anthropic.model`, `anthropic.count`, `maxTokens`, `claude-sonnet-4-6`, `claude-haiku-4-5`, `claude-opus-4-7`; "wire claude into warlock agent", "configure anthropic provider", "use claude sonnet", "anthropic gateway baseURL"; typical import `import { AnthropicSDK } from "@warlock.js/ai-anthropic"`. Skip: embeddings — `@warlock.js/ai-openai/setup-openai/SKILL.md`; sibling adapters `@warlock.js/ai-openai`, `@warlock.js/ai-bedrock`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `@anthropic-ai/sdk`; Vercel `@ai-sdk/anthropic`.
package/package.json ADDED
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "@warlock.js/ai-anthropic",
3
+ "description": "Anthropic SDK adapter for @warlock.js/ai",
4
+ "keywords": [
5
+ "warlock",
6
+ "ai",
7
+ "anthropic",
8
+ "claude"
9
+ ],
10
+ "author": "Hasan Zohdy",
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/warlockjs/ai-anthropic"
15
+ },
16
+ "dependencies": {
17
+ "@anthropic-ai/sdk": "^0.96.0",
18
+ "@warlock.js/logger": "*"
19
+ },
20
+ "peerDependencies": {
21
+ "@warlock.js/ai": "*"
22
+ },
23
+ "version": "4.1.1",
24
+ "main": "./cjs/index.cjs",
25
+ "module": "./esm/index.mjs",
26
+ "types": "./esm/index.d.mts",
27
+ "exports": {
28
+ ".": {
29
+ "import": {
30
+ "types": "./esm/index.d.mts",
31
+ "default": "./esm/index.mjs"
32
+ },
33
+ "require": {
34
+ "types": "./esm/index.d.mts",
35
+ "default": "./cjs/index.cjs"
36
+ }
37
+ }
38
+ }
39
+ }
@@ -0,0 +1,9 @@
1
+ # `@warlock.js/ai-anthropic` — skills index
2
+
3
+ Per-task skills. All cross-references use the form `@warlock.js/<pkg>/<skill>/SKILL.md`.
4
+
5
+ ## Skills
6
+
7
+ ### [`setup-anthropic/`](./setup-anthropic/SKILL.md)
8
+
9
+ Wire @warlock.js/ai-anthropic — new AnthropicSDK({apiKey, baseURL?, provider?}) for Claude, .model({name, vision?, structuredOutput?, maxTokens?}). System-prompt hoisting, max_tokens required (default 4096), no first-party embeddings. Load when wiring a Claude-backed model into a @warlock.js agent.
@@ -0,0 +1,133 @@
1
+ ---
2
+ name: setup-anthropic
3
+ description: 'Wire @warlock.js/ai-anthropic — new AnthropicSDK({apiKey, baseURL?, provider?}) for Claude, .model({name, vision?, structuredOutput?, maxTokens?}). System-prompt hoisting, max_tokens required (default 4096), no first-party embeddings. Triggers: `AnthropicSDK`, `anthropic.model`, `anthropic.count`, `maxTokens`, `claude-sonnet-4-6`, `claude-haiku-4-5`, `claude-opus-4-7`; "wire claude into warlock agent", "configure anthropic provider", "use claude sonnet", "anthropic gateway baseURL"; typical import `import { AnthropicSDK } from "@warlock.js/ai-anthropic"`. Skip: embeddings — `@warlock.js/ai-openai/setup-openai/SKILL.md`; sibling adapters `@warlock.js/ai-openai`, `@warlock.js/ai-bedrock`, `@warlock.js/ai-google`, `@warlock.js/ai-ollama`; raw `@anthropic-ai/sdk`; Vercel `@ai-sdk/anthropic`.'
4
+ ---
5
+
6
+ # `@warlock.js/ai-anthropic`
7
+
8
+ Provider adapter that turns Anthropic's Messages API into a vendor-neutral `ModelContract`. Mirrors `@warlock.js/ai-openai` — same shape, Claude-specific wire mapping.
9
+
10
+ ## Construction
11
+
12
+ ```ts
13
+ import { AnthropicSDK } from "@warlock.js/ai-anthropic";
14
+
15
+ const anthropic = new AnthropicSDK({ apiKey: process.env.ANTHROPIC_API_KEY! });
16
+
17
+ // Proxied / gateway endpoints speaking the Anthropic protocol:
18
+ const proxied = new AnthropicSDK({
19
+ apiKey: process.env.GATEWAY_KEY!,
20
+ baseURL: "https://gateway.internal/anthropic",
21
+ provider: "anthropic-proxy",
22
+ });
23
+ ```
24
+
25
+ `AnthropicSDK` is a class with a long-lived `Anthropic` client. `provider` defaults to `"anthropic"`.
26
+
27
+ ## Producing a model
28
+
29
+ ```ts
30
+ anthropic.model({ name: "claude-sonnet-4-6" }) // common case
31
+ anthropic.model({ name: "claude-haiku-4-5", temperature: 0.2 }) // sampling controls
32
+ anthropic.model({ name: "claude-opus-4-7", maxTokens: 8192 }) // raise the cap
33
+ ```
34
+
35
+ ## Capabilities — what's auto-set
36
+
37
+ | Flag | Default |
38
+ | --- | --- |
39
+ | `structuredOutput` | `true` (via Anthropic's native `output_config.format`) |
40
+ | `vision` | Inferred from model name. `true` for Claude 3 / 3.5 / 3.7 / 4 family; `false` for pre-3 and unknown. |
41
+
42
+ Explicit config always wins.
43
+
44
+ ## Pricing & cost
45
+
46
+ Pricing is opt-in. Supply USD-per-million-token rates and every report this SDK's models produce carries `Usage.cost`; omit them and `cost` stays `undefined` (honest absence, never a false zero). Two declaration sites:
47
+
48
+ ```ts
49
+ // SDK-level registry — one source of truth, keyed by model name:
50
+ const anthropic = new AnthropicSDK({
51
+ apiKey,
52
+ pricing: {
53
+ "claude-haiku-4-5": { input: 1, output: 5, cachedInput: 0.1 },
54
+ "claude-sonnet-4-6": { input: 3, output: 15, cachedInput: 0.3 },
55
+ },
56
+ });
57
+
58
+ // Per-model override (multi-tenant / contract-specific rates):
59
+ anthropic.model({ name: "claude-sonnet-4-6", pricing: { input: 3, output: 15 } });
60
+ ```
61
+
62
+ Resolution at `model()` time: per-model `pricing` > SDK registry entry for that name > `undefined`. `ModelPricing` is `{ input, output, cachedInput?, cachedOutput? }`. Anthropic meters cache **reads** — when present they surface as `usage.cachedTokens` and bill at the `cachedInput` rate (falling back to `input` when unset).
63
+
64
+ ## `max_tokens` is required
65
+
66
+ Unlike OpenAI, Anthropic **requires** `max_tokens` on every request. Resolution: per-call `options.maxTokens` > `config.maxTokens` > **default `4096`**. A caller who never sets a cap still gets a complete answer instead of a 400.
67
+
68
+ ## System prompt
69
+
70
+ Anthropic has no `"system"` role inside `messages`. The adapter hoists every neutral `role: "system"` message into the top-level `system` parameter (multiple system messages join with a blank line). Transparent to the agent.
71
+
72
+ ## Tool calls
73
+
74
+ - Outgoing: vendor-neutral tools → Anthropic `tools` with `input_schema` (non-object schemas degrade to a parameterless object so registration never fails).
75
+ - Assistant tool calls in history → `assistant` message with an optional leading `text` block + one `tool_use` block per call.
76
+ - Tool results (`role: "tool"`) → a `user` turn carrying a single `tool_result` block keyed by `tool_use_id`.
77
+ - Response `tool_use` blocks → neutral `toolCalls`; `stop_reason: "tool_use"` → `finishReason: "tool_calls"`.
78
+
79
+ ## Structured output
80
+
81
+ When the agent passes `responseSchema` and the model is `structuredOutput`-capable, an **object-root** schema is forwarded as `output_config: { format: { type: "json_schema", schema } }` (Anthropic native). Non-object schemas or `structuredOutput: false` omit it; the agent's soft system-prompt hint + client-side `validate()` still enforce shape.
82
+
83
+ ## Multipart messages (vision)
84
+
85
+ `ContentPart[]` user content maps to Anthropic content blocks:
86
+
87
+ - `{ type: "text", text }` → `{ type: "text", text }`
88
+ - `{ type: "image", source: { url } }` → `{ type: "image", source: { type: "url", url } }`
89
+ - `{ type: "image", source: { base64, mediaType } }` → `{ type: "image", source: { type: "base64", media_type, data } }`
90
+
91
+ ## Streaming
92
+
93
+ `model.stream()` drains `messages.create({ stream: true })`:
94
+
95
+ - `content_block_delta` text → `{ type: "delta", content }`
96
+ - `tool_use` blocks accumulate `input_json_delta` fragments and emit one consolidated `{ type: "tool-call", ... }` at `content_block_stop` (no partial-arg `{}` artifact — input is parsed once, whole)
97
+ - terminal `{ type: "done", finishReason, usage }` — `usage.input` from `message_start`, `usage.output` from `message_delta`, `total` computed
98
+
99
+ ## Finish-reason mapping
100
+
101
+ `end_turn` / `stop_sequence` → `stop` · `max_tokens` → `length` · `tool_use` → `tool_calls` · `refusal` / `pause_turn` / unknown / null → `error`.
102
+
103
+ ## Errors
104
+
105
+ Raw SDK errors are wrapped into the typed `@warlock.js/ai` `AIError` hierarchy. Dispatch keys on `error.type` (Anthropic has no per-error machine `code`), falling back to HTTP status:
106
+
107
+ - `authentication_error` / `permission_error` / 401 / 403 → `ProviderAuthError`
108
+ - `rate_limit_error` / 429 → `ProviderRateLimitError` (+`retryAfter` from `retry-after`)
109
+ - `billing_error` → `QuotaExceededError`
110
+ - `invalid_request_error` with "prompt is too long" → `ContextLengthExceededError`, else `InvalidRequestError`
111
+ - 5xx / overloaded → `ProviderError`
112
+ - Connection timeouts → `ProviderTimeoutError`
113
+
114
+ ## Token counting
115
+
116
+ ```ts
117
+ await anthropic.count("some text") // approximate heuristic, offline
118
+ ```
119
+
120
+ ## No embeddings
121
+
122
+ Anthropic ships no first-party embeddings API, so `AnthropicSDK` intentionally does **not** implement `embedder()` (the `SDKAdapterContract.embedder` slot is optional). Use [`@warlock.js/ai-openai`](@warlock.js/ai-openai/setup-openai/SKILL.md) (or another embeddings-capable adapter) for vectors.
123
+
124
+ ## When NOT to use this skill
125
+
126
+ - Direct calls to `@anthropic-ai/sdk` without going through `@warlock.js/ai` agents.
127
+ - OpenAI / Bedrock / Gemini / Ollama models — those have their own adapter packages.
128
+
129
+ ## See also
130
+
131
+ - [`@warlock.js/ai/run-ai-agent/SKILL.md`](@warlock.js/ai/run-ai-agent/SKILL.md)
132
+ - [`@warlock.js/ai/pick-ai-provider/SKILL.md`](@warlock.js/ai/pick-ai-provider/SKILL.md)
133
+ - [`@warlock.js/ai/handle-ai-errors/SKILL.md`](@warlock.js/ai/handle-ai-errors/SKILL.md)