chub-dev 0.2.0-beta.2 → 0.2.0-beta.4
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/package.json +2 -2
- package/src/commands/annotate.js +83 -0
- package/src/commands/build.js +9 -0
- package/src/commands/get.js +64 -39
- package/src/index.js +14 -13
- package/src/lib/annotations.js +57 -0
- package/src/lib/bm25.js +170 -0
- package/src/lib/cache.js +14 -0
- package/src/lib/config.js +1 -1
- package/src/lib/registry.js +103 -20
- package/dist/anthropic/docs/sdk/javascript/DOC.md +0 -499
- package/dist/anthropic/docs/sdk/python/DOC.md +0 -382
- package/dist/openai/docs/chat/javascript/DOC.md +0 -350
- package/dist/openai/docs/chat/python/DOC.md +0 -526
- package/dist/pinecone/docs/sdk/javascript/DOC.md +0 -984
- package/dist/pinecone/docs/sdk/python/DOC.md +0 -1395
- package/dist/registry.json +0 -276
- package/dist/resend/docs/sdk/DOC.md +0 -1271
- package/dist/stripe/docs/api/DOC.md +0 -1726
- package/dist/supabase/docs/sdk/DOC.md +0 -1606
- package/dist/twilio/docs/sdk/python/DOC.md +0 -469
- package/dist/twilio/docs/sdk/typescript/DOC.md +0 -946
package/src/lib/registry.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { loadSourceRegistry } from './cache.js';
|
|
1
|
+
import { loadSourceRegistry, loadSearchIndex } from './cache.js';
|
|
2
2
|
import { loadConfig } from './config.js';
|
|
3
3
|
import { normalizeLanguage } from './normalize.js';
|
|
4
|
+
import { search as bm25Search } from './bm25.js';
|
|
4
5
|
|
|
5
6
|
let _merged = null;
|
|
7
|
+
let _searchIndex = null;
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Load and merge entries from all configured sources.
|
|
@@ -14,11 +16,16 @@ function getMerged() {
|
|
|
14
16
|
const config = loadConfig();
|
|
15
17
|
const allDocs = [];
|
|
16
18
|
const allSkills = [];
|
|
19
|
+
const searchIndexes = [];
|
|
17
20
|
|
|
18
21
|
for (const source of config.sources) {
|
|
19
22
|
const registry = loadSourceRegistry(source);
|
|
20
23
|
if (!registry) continue;
|
|
21
24
|
|
|
25
|
+
// Load BM25 search index if available
|
|
26
|
+
const idx = loadSearchIndex(source);
|
|
27
|
+
if (idx) searchIndexes.push(idx);
|
|
28
|
+
|
|
22
29
|
// Support both new format (docs/skills) and old format (entries)
|
|
23
30
|
if (registry.docs) {
|
|
24
31
|
for (const doc of registry.docs) {
|
|
@@ -46,6 +53,53 @@ function getMerged() {
|
|
|
46
53
|
}
|
|
47
54
|
}
|
|
48
55
|
|
|
56
|
+
// Merge search indexes (combine documents and recompute IDF)
|
|
57
|
+
if (searchIndexes.length > 0) {
|
|
58
|
+
if (searchIndexes.length === 1) {
|
|
59
|
+
_searchIndex = searchIndexes[0];
|
|
60
|
+
} else {
|
|
61
|
+
// Merge multiple indexes: combine documents, recompute global IDF
|
|
62
|
+
const allDocuments = searchIndexes.flatMap((idx) => idx.documents);
|
|
63
|
+
const N = allDocuments.length;
|
|
64
|
+
const dfMap = {};
|
|
65
|
+
const fieldLengths = { name: [], description: [], tags: [] };
|
|
66
|
+
|
|
67
|
+
for (const doc of allDocuments) {
|
|
68
|
+
const allTerms = new Set([
|
|
69
|
+
...(doc.tokens.name || []),
|
|
70
|
+
...(doc.tokens.description || []),
|
|
71
|
+
...(doc.tokens.tags || []),
|
|
72
|
+
]);
|
|
73
|
+
for (const term of allTerms) {
|
|
74
|
+
dfMap[term] = (dfMap[term] || 0) + 1;
|
|
75
|
+
}
|
|
76
|
+
fieldLengths.name.push((doc.tokens.name || []).length);
|
|
77
|
+
fieldLengths.description.push((doc.tokens.description || []).length);
|
|
78
|
+
fieldLengths.tags.push((doc.tokens.tags || []).length);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const idf = {};
|
|
82
|
+
for (const [term, df] of Object.entries(dfMap)) {
|
|
83
|
+
idf[term] = Math.log((N - df + 0.5) / (df + 0.5) + 1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const avg = (arr) => arr.length === 0 ? 0 : arr.reduce((a, b) => a + b, 0) / arr.length;
|
|
87
|
+
_searchIndex = {
|
|
88
|
+
version: '1.0.0',
|
|
89
|
+
algorithm: 'bm25',
|
|
90
|
+
params: searchIndexes[0].params,
|
|
91
|
+
totalDocs: N,
|
|
92
|
+
avgFieldLengths: {
|
|
93
|
+
name: avg(fieldLengths.name),
|
|
94
|
+
description: avg(fieldLengths.description),
|
|
95
|
+
tags: avg(fieldLengths.tags),
|
|
96
|
+
},
|
|
97
|
+
idf,
|
|
98
|
+
documents: allDocuments,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
49
103
|
_merged = { docs: allDocs, skills: allSkills };
|
|
50
104
|
return _merged;
|
|
51
105
|
}
|
|
@@ -121,11 +175,10 @@ export function getDisplayId(entry) {
|
|
|
121
175
|
|
|
122
176
|
/**
|
|
123
177
|
* Search entries by query string. Searches both docs and skills.
|
|
178
|
+
* Uses BM25 when a search index is available, falls back to keyword matching.
|
|
124
179
|
*/
|
|
125
180
|
export function searchEntries(query, filters = {}) {
|
|
126
181
|
const entries = applySourceFilter(getAllEntries());
|
|
127
|
-
const q = query.toLowerCase();
|
|
128
|
-
const words = q.split(/\s+/);
|
|
129
182
|
|
|
130
183
|
// Deduplicate: same id+source appearing as both doc and skill → show once
|
|
131
184
|
const seen = new Set();
|
|
@@ -138,27 +191,50 @@ export function searchEntries(query, filters = {}) {
|
|
|
138
191
|
}
|
|
139
192
|
}
|
|
140
193
|
|
|
141
|
-
|
|
142
|
-
|
|
194
|
+
// Build entry lookup by id
|
|
195
|
+
const entryById = new Map();
|
|
196
|
+
for (const entry of deduped) {
|
|
197
|
+
entryById.set(entry.id, entry);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
let results;
|
|
201
|
+
|
|
202
|
+
if (_searchIndex) {
|
|
203
|
+
// BM25 search
|
|
204
|
+
const bm25Results = bm25Search(query, _searchIndex);
|
|
205
|
+
results = bm25Results
|
|
206
|
+
.map((r) => {
|
|
207
|
+
const entry = entryById.get(r.id);
|
|
208
|
+
return entry ? { entry, score: r.score } : null;
|
|
209
|
+
})
|
|
210
|
+
.filter(Boolean);
|
|
211
|
+
} else {
|
|
212
|
+
// Fallback: keyword matching
|
|
213
|
+
const q = query.toLowerCase();
|
|
214
|
+
const words = q.split(/\s+/);
|
|
143
215
|
|
|
144
|
-
|
|
145
|
-
|
|
216
|
+
results = deduped.map((entry) => {
|
|
217
|
+
let score = 0;
|
|
146
218
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
else if (nameLower.includes(q)) score += 40;
|
|
219
|
+
if (entry.id === q) score += 100;
|
|
220
|
+
else if (entry.id.includes(q)) score += 50;
|
|
150
221
|
|
|
151
|
-
|
|
152
|
-
if (
|
|
153
|
-
if (nameLower.includes(
|
|
154
|
-
if (entry.description?.toLowerCase().includes(word)) score += 5;
|
|
155
|
-
if (entry.tags?.some((t) => t.toLowerCase().includes(word))) score += 15;
|
|
156
|
-
}
|
|
222
|
+
const nameLower = entry.name.toLowerCase();
|
|
223
|
+
if (nameLower === q) score += 80;
|
|
224
|
+
else if (nameLower.includes(q)) score += 40;
|
|
157
225
|
|
|
158
|
-
|
|
159
|
-
|
|
226
|
+
for (const word of words) {
|
|
227
|
+
if (entry.id.includes(word)) score += 10;
|
|
228
|
+
if (nameLower.includes(word)) score += 10;
|
|
229
|
+
if (entry.description?.toLowerCase().includes(word)) score += 5;
|
|
230
|
+
if (entry.tags?.some((t) => t.toLowerCase().includes(word))) score += 15;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return { entry, score };
|
|
234
|
+
});
|
|
160
235
|
|
|
161
|
-
|
|
236
|
+
results = results.filter((r) => r.score > 0);
|
|
237
|
+
}
|
|
162
238
|
|
|
163
239
|
const filtered = applyFilters(results.map((r) => r.entry), filters);
|
|
164
240
|
const filteredSet = new Set(filtered);
|
|
@@ -255,6 +331,13 @@ export function resolveDocPath(entry, language, version) {
|
|
|
255
331
|
let verObj = null;
|
|
256
332
|
if (version) {
|
|
257
333
|
verObj = langObj.versions?.find((v) => v.version === version);
|
|
334
|
+
if (!verObj) {
|
|
335
|
+
return {
|
|
336
|
+
versionNotFound: true,
|
|
337
|
+
requested: version,
|
|
338
|
+
available: langObj.versions?.map((v) => v.version) || [],
|
|
339
|
+
};
|
|
340
|
+
}
|
|
258
341
|
} else {
|
|
259
342
|
const rec = langObj.recommendedVersion;
|
|
260
343
|
verObj = langObj.versions?.find((v) => v.version === rec) || langObj.versions?.[0];
|
|
@@ -272,7 +355,7 @@ export function resolveDocPath(entry, language, version) {
|
|
|
272
355
|
* Given a resolved path and a type ("doc" or "skill"), return the entry file path.
|
|
273
356
|
*/
|
|
274
357
|
export function resolveEntryFile(resolved, type) {
|
|
275
|
-
if (!resolved || resolved.needsLanguage) return { error: 'unresolved' };
|
|
358
|
+
if (!resolved || resolved.needsLanguage || resolved.versionNotFound) return { error: 'unresolved' };
|
|
276
359
|
|
|
277
360
|
const fileName = type === 'skill' ? 'SKILL.md' : 'DOC.md';
|
|
278
361
|
|
|
@@ -1,499 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sdk
|
|
3
|
-
description: "Claude AI assistant API for text generation, analysis, conversation, streaming, tool use, vision, and batch processing"
|
|
4
|
-
metadata:
|
|
5
|
-
languages: "javascript"
|
|
6
|
-
versions: "0.67.0"
|
|
7
|
-
updated-on: "2025-10-24"
|
|
8
|
-
source: maintainer
|
|
9
|
-
tags: "anthropic,sdk,llm,ai,claude"
|
|
10
|
-
---
|
|
11
|
-
|
|
12
|
-
# Anthropic JavaScript/TypeScript SDK Coding Guidelines
|
|
13
|
-
|
|
14
|
-
You are an Anthropic API coding expert. Help me with writing code using the Anthropic API calling the official libraries and SDKs.
|
|
15
|
-
|
|
16
|
-
You can find the official SDK documentation and code samples here:
|
|
17
|
-
https://docs.anthropic.com/claude/reference/
|
|
18
|
-
|
|
19
|
-
## Golden Rule: Use the Correct and Current SDK
|
|
20
|
-
|
|
21
|
-
Always use the Anthropic TypeScript SDK to call the Claude models, which is the standard library for all Anthropic API interactions. Do not use legacy libraries or unofficial SDKs.
|
|
22
|
-
|
|
23
|
-
- **Library Name:** Anthropic TypeScript SDK
|
|
24
|
-
- **NPM Package:** `@anthropic-ai/sdk`
|
|
25
|
-
- **Legacy Libraries**: Other unofficial packages are not recommended
|
|
26
|
-
|
|
27
|
-
**Installation:**
|
|
28
|
-
|
|
29
|
-
- **Correct:** `npm install @anthropic-ai/sdk`
|
|
30
|
-
|
|
31
|
-
**APIs and Usage:**
|
|
32
|
-
|
|
33
|
-
- **Correct:** `import Anthropic from '@anthropic-ai/sdk'`
|
|
34
|
-
- **Correct:** `const client = new Anthropic({})`
|
|
35
|
-
- **Correct:** `await client.messages.create(...)`
|
|
36
|
-
- **Correct:** `await client.messages.stream(...)`
|
|
37
|
-
- **Incorrect:** `AnthropicClient` or `AnthropicAPI`
|
|
38
|
-
- **Incorrect:** `client.generate` or `client.completions`
|
|
39
|
-
- **Incorrect:** Legacy completion endpoints
|
|
40
|
-
|
|
41
|
-
## Initialization and API key
|
|
42
|
-
|
|
43
|
-
The `@anthropic-ai/sdk` library requires creating an `Anthropic` instance for all API calls.
|
|
44
|
-
|
|
45
|
-
- Always use `const client = new Anthropic({})` to create an instance.
|
|
46
|
-
- Set the `ANTHROPIC_API_KEY` environment variable, which will be picked up automatically.
|
|
47
|
-
|
|
48
|
-
```javascript
|
|
49
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
50
|
-
|
|
51
|
-
// Uses the ANTHROPIC_API_KEY environment variable if apiKey not specified
|
|
52
|
-
const client = new Anthropic({});
|
|
53
|
-
|
|
54
|
-
// Or pass the API key directly
|
|
55
|
-
// const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Models
|
|
59
|
-
|
|
60
|
-
- By default, use the following models when using `@anthropic-ai/sdk`:
|
|
61
|
-
- **General Tasks:** `claude-sonnet-4-20250514`
|
|
62
|
-
- **Legacy Model (if needed):** `claude-3-7-sonnet-latest`
|
|
63
|
-
|
|
64
|
-
- Advanced models available:
|
|
65
|
-
- **High-performance:** `claude-opus-4-20250514`
|
|
66
|
-
|
|
67
|
-
## Basic Inference (Text Generation)
|
|
68
|
-
|
|
69
|
-
Here's how to generate a response from a text prompt.
|
|
70
|
-
|
|
71
|
-
```javascript
|
|
72
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
73
|
-
|
|
74
|
-
const client = new Anthropic({}); // Assumes ANTHROPIC_API_KEY is set
|
|
75
|
-
|
|
76
|
-
async function run() {
|
|
77
|
-
const message = await client.messages.create({
|
|
78
|
-
max_tokens: 1024,
|
|
79
|
-
messages: [{ role: 'user', content: 'Hello, Claude' }],
|
|
80
|
-
model: 'claude-sonnet-4-20250514',
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
console.log(message.content);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
run();
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Multimodal inputs are supported by passing image data in the messages array. You can include images, documents, and other file types using base64 encoding or file uploads.
|
|
90
|
-
|
|
91
|
-
For file uploads, use the `client.beta.files.upload` method:
|
|
92
|
-
|
|
93
|
-
```javascript
|
|
94
|
-
import fs from 'fs';
|
|
95
|
-
import Anthropic, { toFile } from '@anthropic-ai/sdk';
|
|
96
|
-
|
|
97
|
-
const client = new Anthropic();
|
|
98
|
-
|
|
99
|
-
// File upload example
|
|
100
|
-
await client.beta.files.upload({
|
|
101
|
-
file: await toFile(fs.createReadStream('/path/to/file'), undefined, { type: 'application/json' }),
|
|
102
|
-
betas: ['files-api-2025-04-14'],
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Streaming Responses
|
|
107
|
-
|
|
108
|
-
We provide comprehensive support for streaming responses using Server Sent Events (SSE).
|
|
109
|
-
|
|
110
|
-
### Basic Streaming
|
|
111
|
-
|
|
112
|
-
```javascript
|
|
113
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
114
|
-
|
|
115
|
-
const client = new Anthropic();
|
|
116
|
-
|
|
117
|
-
const stream = await client.messages.create({
|
|
118
|
-
max_tokens: 1024,
|
|
119
|
-
messages: [{ role: 'user', content: 'Hello, Claude' }],
|
|
120
|
-
model: 'claude-sonnet-4-20250514',
|
|
121
|
-
stream: true,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
for await (const messageStreamEvent of stream) {
|
|
125
|
-
console.log(messageStreamEvent.type);
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
### Advanced Streaming with Helpers
|
|
130
|
-
|
|
131
|
-
The SDK provides powerful streaming helpers for convenience:
|
|
132
|
-
|
|
133
|
-
```javascript
|
|
134
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
135
|
-
|
|
136
|
-
const client = new Anthropic();
|
|
137
|
-
|
|
138
|
-
async function main() {
|
|
139
|
-
const stream = client.messages
|
|
140
|
-
.stream({
|
|
141
|
-
model: 'claude-sonnet-4-20250514',
|
|
142
|
-
max_tokens: 1024,
|
|
143
|
-
messages: [
|
|
144
|
-
{
|
|
145
|
-
role: 'user',
|
|
146
|
-
content: 'Say hello there!',
|
|
147
|
-
},
|
|
148
|
-
],
|
|
149
|
-
})
|
|
150
|
-
.on('text', (text) => {
|
|
151
|
-
console.log(text);
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
const message = await stream.finalMessage();
|
|
155
|
-
console.log(message);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
main();
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
You can cancel streams by calling `stream.controller.abort()` or breaking from loops.
|
|
162
|
-
|
|
163
|
-
## Tool Use (Function Calling)
|
|
164
|
-
|
|
165
|
-
The SDK supports tool use (function calling) for extending Claude's capabilities.
|
|
166
|
-
|
|
167
|
-
### Custom Tools
|
|
168
|
-
|
|
169
|
-
Define custom functions that Claude can call:
|
|
170
|
-
|
|
171
|
-
```javascript
|
|
172
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
173
|
-
|
|
174
|
-
const client = new Anthropic();
|
|
175
|
-
|
|
176
|
-
async function run() {
|
|
177
|
-
const response = await client.messages.create({
|
|
178
|
-
model: 'claude-sonnet-4-20250514',
|
|
179
|
-
max_tokens: 1024,
|
|
180
|
-
messages: [{ role: 'user', content: "What's the weather like in San Francisco?" }],
|
|
181
|
-
tools: [
|
|
182
|
-
{
|
|
183
|
-
name: 'get_weather',
|
|
184
|
-
description: 'Get the current weather in a given location',
|
|
185
|
-
input_schema: {
|
|
186
|
-
type: 'object',
|
|
187
|
-
properties: {
|
|
188
|
-
location: { description: 'The city and state, e.g. San Francisco, CA', type: 'string' },
|
|
189
|
-
unit: { description: 'Unit for the output - one of (celsius, fahrenheit)', type: 'string' },
|
|
190
|
-
},
|
|
191
|
-
required: ['location'],
|
|
192
|
-
},
|
|
193
|
-
type: 'custom',
|
|
194
|
-
},
|
|
195
|
-
],
|
|
196
|
-
tool_choice: { type: 'auto' },
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// Handle tool use in the response
|
|
200
|
-
if (response.content.some((block) => block.type === 'tool_use')) {
|
|
201
|
-
// Process tool calls and provide results back to Claude
|
|
202
|
-
console.log('Claude wants to use a tool!');
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
run();
|
|
207
|
-
```
|
|
208
|
-
|
|
209
|
-
### Built-in Beta Tools
|
|
210
|
-
|
|
211
|
-
The beta API provides specialized built-in tools.
|
|
212
|
-
|
|
213
|
-
#### Bash Tool
|
|
214
|
-
|
|
215
|
-
```javascript
|
|
216
|
-
const response = await client.beta.messages.create({
|
|
217
|
-
model: 'claude-sonnet-4-20250514',
|
|
218
|
-
max_tokens: 1024,
|
|
219
|
-
messages: [{ role: 'user', content: 'List the files in the current directory' }],
|
|
220
|
-
tools: [{ type: 'bash_20250124', name: 'bash' }],
|
|
221
|
-
});
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
#### Computer Use Tool
|
|
225
|
-
|
|
226
|
-
```javascript
|
|
227
|
-
const response = await client.beta.messages.create({
|
|
228
|
-
model: 'claude-sonnet-4-20250514',
|
|
229
|
-
max_tokens: 1024,
|
|
230
|
-
messages: [{ role: 'user', content: 'Take a screenshot' }],
|
|
231
|
-
tools: [
|
|
232
|
-
{
|
|
233
|
-
type: 'computer_20250124',
|
|
234
|
-
name: 'computer',
|
|
235
|
-
display_width_px: 1920,
|
|
236
|
-
display_height_px: 1080,
|
|
237
|
-
},
|
|
238
|
-
],
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
#### Text Editor Tool
|
|
243
|
-
|
|
244
|
-
```javascript
|
|
245
|
-
const response = await client.beta.messages.create({
|
|
246
|
-
model: 'claude-sonnet-4-20250514',
|
|
247
|
-
max_tokens: 1024,
|
|
248
|
-
messages: [{ role: 'user', content: 'Create a Python script' }],
|
|
249
|
-
tools: [{ type: 'text_editor_20250124', name: 'str_replace_editor' }],
|
|
250
|
-
});
|
|
251
|
-
```
|
|
252
|
-
|
|
253
|
-
### Tool Choice Configuration
|
|
254
|
-
|
|
255
|
-
Control how Claude uses tools:
|
|
256
|
-
|
|
257
|
-
- `{ type: 'auto' }` - Claude decides when to use tools
|
|
258
|
-
- `{ type: 'any' }` - Claude must use a tool
|
|
259
|
-
- `{ type: 'tool', name: 'specific_tool' }` - Force a specific tool
|
|
260
|
-
- `{ disable_parallel_tool_use: true }` - Disable parallel tool execution
|
|
261
|
-
|
|
262
|
-
## Message Batches
|
|
263
|
-
|
|
264
|
-
The SDK supports the Message Batches API for processing multiple requests efficiently.
|
|
265
|
-
|
|
266
|
-
### Creating a Batch
|
|
267
|
-
|
|
268
|
-
```javascript
|
|
269
|
-
await client.messages.batches.create({
|
|
270
|
-
requests: [
|
|
271
|
-
{
|
|
272
|
-
custom_id: 'my-first-request',
|
|
273
|
-
params: {
|
|
274
|
-
model: 'claude-sonnet-4-20250514',
|
|
275
|
-
max_tokens: 1024,
|
|
276
|
-
messages: [{ role: 'user', content: 'Hello, world' }],
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
custom_id: 'my-second-request',
|
|
281
|
-
params: {
|
|
282
|
-
model: 'claude-sonnet-4-20250514',
|
|
283
|
-
max_tokens: 1024,
|
|
284
|
-
messages: [{ role: 'user', content: 'Hi again, friend' }],
|
|
285
|
-
},
|
|
286
|
-
},
|
|
287
|
-
],
|
|
288
|
-
});
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
### Getting Batch Results
|
|
292
|
-
|
|
293
|
-
```javascript
|
|
294
|
-
const results = await client.messages.batches.results(batch_id);
|
|
295
|
-
for await (const entry of results) {
|
|
296
|
-
if (entry.result.type === 'succeeded') {
|
|
297
|
-
console.log(entry.result.message.content);
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
```
|
|
301
|
-
|
|
302
|
-
## Additional Capabilities
|
|
303
|
-
|
|
304
|
-
### System Instructions
|
|
305
|
-
|
|
306
|
-
Guide Claude's behavior with system instructions:
|
|
307
|
-
|
|
308
|
-
```javascript
|
|
309
|
-
const response = await client.messages.create({
|
|
310
|
-
model: 'claude-sonnet-4-20250514',
|
|
311
|
-
max_tokens: 1024,
|
|
312
|
-
messages: [{ role: 'user', content: 'Hello' }],
|
|
313
|
-
system: [{ text: 'You are a helpful assistant that responds in a pirate voice.', type: 'text' }],
|
|
314
|
-
});
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### Thinking (Beta Feature)
|
|
318
|
-
|
|
319
|
-
Configure Claude's reasoning process:
|
|
320
|
-
|
|
321
|
-
```javascript
|
|
322
|
-
const response = await client.messages.create({
|
|
323
|
-
model: 'claude-sonnet-4-20250514',
|
|
324
|
-
max_tokens: 1024,
|
|
325
|
-
messages: [{ role: 'user', content: 'Solve this complex problem...' }],
|
|
326
|
-
thinking: { budget_tokens: 1024, type: 'enabled' },
|
|
327
|
-
});
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Temperature and Generation Parameters
|
|
331
|
-
|
|
332
|
-
Control randomness and output:
|
|
333
|
-
|
|
334
|
-
```javascript
|
|
335
|
-
const response = await client.messages.create({
|
|
336
|
-
model: 'claude-sonnet-4-20250514',
|
|
337
|
-
max_tokens: 1024,
|
|
338
|
-
messages: [{ role: 'user', content: 'Write a creative story' }],
|
|
339
|
-
temperature: 0.7,
|
|
340
|
-
top_k: 5,
|
|
341
|
-
top_p: 0.9,
|
|
342
|
-
});
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### Token Counting
|
|
346
|
-
|
|
347
|
-
Count tokens before making requests:
|
|
348
|
-
|
|
349
|
-
```javascript
|
|
350
|
-
const tokenCount = await client.messages.countTokens({
|
|
351
|
-
messages: [{ role: 'user', content: 'Hello, Claude' }],
|
|
352
|
-
model: 'claude-sonnet-4-20250514',
|
|
353
|
-
});
|
|
354
|
-
console.log(tokenCount); // { input_tokens: 25, output_tokens: 13 }
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
### Auto-pagination
|
|
358
|
-
|
|
359
|
-
Handle paginated responses automatically:
|
|
360
|
-
|
|
361
|
-
```javascript
|
|
362
|
-
async function fetchAllMessageBatches(params) {
|
|
363
|
-
const allMessageBatches = [];
|
|
364
|
-
// Automatically fetches more pages as needed.
|
|
365
|
-
for await (const messageBatch of client.messages.batches.list({ limit: 20 })) {
|
|
366
|
-
allMessageBatches.push(messageBatch);
|
|
367
|
-
}
|
|
368
|
-
return allMessageBatches;
|
|
369
|
-
}
|
|
370
|
-
```
|
|
371
|
-
|
|
372
|
-
## Error Handling
|
|
373
|
-
|
|
374
|
-
The SDK provides comprehensive error handling with specific error types:
|
|
375
|
-
|
|
376
|
-
```javascript
|
|
377
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
378
|
-
|
|
379
|
-
const client = new Anthropic();
|
|
380
|
-
|
|
381
|
-
try {
|
|
382
|
-
const message = await client.messages.create({
|
|
383
|
-
max_tokens: 1024,
|
|
384
|
-
messages: [{ role: 'user', content: 'Hello, Claude' }],
|
|
385
|
-
model: 'claude-sonnet-4-20250514',
|
|
386
|
-
});
|
|
387
|
-
} catch (err) {
|
|
388
|
-
if (err instanceof Anthropic.APIError) {
|
|
389
|
-
console.log(err.status); // 400
|
|
390
|
-
console.log(err.name); // BadRequestError
|
|
391
|
-
console.log(err.headers); // {server: 'nginx', ...}
|
|
392
|
-
console.log(err.requestID); // request id string
|
|
393
|
-
} else {
|
|
394
|
-
throw err;
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
```
|
|
398
|
-
|
|
399
|
-
### Error Types
|
|
400
|
-
|
|
401
|
-
| Status Code | Error Type |
|
|
402
|
-
| ----------- | -------------------------- |
|
|
403
|
-
| 400 | `BadRequestError` |
|
|
404
|
-
| 401 | `AuthenticationError` |
|
|
405
|
-
| 403 | `PermissionDeniedError` |
|
|
406
|
-
| 404 | `NotFoundError` |
|
|
407
|
-
| 422 | `UnprocessableEntityError` |
|
|
408
|
-
| 429 | `RateLimitError` |
|
|
409
|
-
| >=500 | `InternalServerError` |
|
|
410
|
-
| N/A | `APIConnectionError` |
|
|
411
|
-
|
|
412
|
-
All errors extend from `AnthropicError` which extends the standard `Error` class.
|
|
413
|
-
|
|
414
|
-
### Request IDs
|
|
415
|
-
|
|
416
|
-
All responses include a `_request_id` property for debugging:
|
|
417
|
-
|
|
418
|
-
```javascript
|
|
419
|
-
const message = await client.messages.create({
|
|
420
|
-
max_tokens: 1024,
|
|
421
|
-
messages: [{ role: 'user', content: 'Hello, Claude' }],
|
|
422
|
-
model: 'claude-sonnet-4-20250514',
|
|
423
|
-
});
|
|
424
|
-
console.log(message._request_id);
|
|
425
|
-
```
|
|
426
|
-
|
|
427
|
-
## Advanced Configuration
|
|
428
|
-
|
|
429
|
-
### Retries
|
|
430
|
-
|
|
431
|
-
Configure automatic retry behavior:
|
|
432
|
-
|
|
433
|
-
```javascript
|
|
434
|
-
// Configure default retries for all requests
|
|
435
|
-
const client = new Anthropic({
|
|
436
|
-
maxRetries: 3, // default is 2
|
|
437
|
-
});
|
|
438
|
-
|
|
439
|
-
// Or configure per-request
|
|
440
|
-
await client.messages.create(
|
|
441
|
-
{ max_tokens: 1024, messages: [{ role: 'user', content: 'Hello, Claude' }], model: 'claude-sonnet-4-20250514' },
|
|
442
|
-
{ maxRetries: 5 },
|
|
443
|
-
);
|
|
444
|
-
```
|
|
445
|
-
|
|
446
|
-
### Timeouts
|
|
447
|
-
|
|
448
|
-
Set custom timeout values:
|
|
449
|
-
|
|
450
|
-
```javascript
|
|
451
|
-
// Configure default timeout for all requests
|
|
452
|
-
const client = new Anthropic({
|
|
453
|
-
timeout: 20 * 1000, // 20 seconds (default is 10 minutes)
|
|
454
|
-
});
|
|
455
|
-
|
|
456
|
-
// Override per-request
|
|
457
|
-
await client.messages.create(
|
|
458
|
-
{ max_tokens: 1024, messages: [{ role: 'user', content: 'Hello, Claude' }], model: 'claude-sonnet-4-20250514' },
|
|
459
|
-
{ timeout: 5 * 1000 },
|
|
460
|
-
);
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
### Logging
|
|
464
|
-
|
|
465
|
-
Enable debug logging:
|
|
466
|
-
|
|
467
|
-
```javascript
|
|
468
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
469
|
-
|
|
470
|
-
const client = new Anthropic({
|
|
471
|
-
logLevel: 'debug', // Show all log messages
|
|
472
|
-
});
|
|
473
|
-
|
|
474
|
-
// Or use environment variable
|
|
475
|
-
// ANTHROPIC_LOG=debug
|
|
476
|
-
```
|
|
477
|
-
|
|
478
|
-
### Custom Fetch Options
|
|
479
|
-
|
|
480
|
-
Customize the underlying fetch behavior:
|
|
481
|
-
|
|
482
|
-
```javascript
|
|
483
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
484
|
-
|
|
485
|
-
const client = new Anthropic({
|
|
486
|
-
fetchOptions: {
|
|
487
|
-
// Custom RequestInit options
|
|
488
|
-
},
|
|
489
|
-
});
|
|
490
|
-
```
|
|
491
|
-
|
|
492
|
-
## Useful Links
|
|
493
|
-
|
|
494
|
-
- Documentation: https://docs.anthropic.com/
|
|
495
|
-
- API Reference: https://docs.anthropic.com/claude/reference/
|
|
496
|
-
- Models: https://docs.anthropic.com/claude/docs/models-overview
|
|
497
|
-
- API Pricing: https://www.anthropic.com/pricing
|
|
498
|
-
- Rate Limits: https://docs.anthropic.com/claude/reference/rate-limits
|
|
499
|
-
|