skrypt-ai 0.5.0 → 0.6.0
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/dist/auth/index.js +8 -1
- package/dist/autofix/index.d.ts +0 -4
- package/dist/autofix/index.js +0 -21
- package/dist/capture/browser.d.ts +11 -0
- package/dist/capture/browser.js +173 -0
- package/dist/capture/diff.d.ts +23 -0
- package/dist/capture/diff.js +52 -0
- package/dist/capture/index.d.ts +23 -0
- package/dist/capture/index.js +210 -0
- package/dist/capture/naming.d.ts +17 -0
- package/dist/capture/naming.js +45 -0
- package/dist/capture/parser.d.ts +15 -0
- package/dist/capture/parser.js +80 -0
- package/dist/capture/types.d.ts +57 -0
- package/dist/capture/types.js +1 -0
- package/dist/cli.js +4 -0
- package/dist/commands/autofix.js +136 -120
- package/dist/commands/cron.js +58 -47
- package/dist/commands/deploy.js +123 -102
- package/dist/commands/generate.js +88 -6
- package/dist/commands/heal.d.ts +10 -0
- package/dist/commands/heal.js +201 -0
- package/dist/commands/i18n.js +146 -111
- package/dist/commands/lint.js +50 -44
- package/dist/commands/llms-txt.js +59 -49
- package/dist/commands/login.js +61 -43
- package/dist/commands/mcp.js +6 -0
- package/dist/commands/monitor.js +13 -8
- package/dist/commands/qa.d.ts +2 -0
- package/dist/commands/qa.js +43 -0
- package/dist/commands/review-pr.js +108 -102
- package/dist/commands/sdk.js +128 -122
- package/dist/commands/security.js +86 -80
- package/dist/commands/test.js +91 -92
- package/dist/commands/version.js +104 -75
- package/dist/commands/watch.js +130 -114
- package/dist/config/types.js +2 -2
- package/dist/context-hub/index.d.ts +23 -0
- package/dist/context-hub/index.js +179 -0
- package/dist/context-hub/mappings.d.ts +8 -0
- package/dist/context-hub/mappings.js +55 -0
- package/dist/context-hub/types.d.ts +33 -0
- package/dist/context-hub/types.js +1 -0
- package/dist/generator/generator.js +39 -6
- package/dist/generator/types.d.ts +7 -0
- package/dist/generator/writer.d.ts +3 -1
- package/dist/generator/writer.js +24 -4
- package/dist/llm/anthropic-client.d.ts +1 -0
- package/dist/llm/anthropic-client.js +3 -1
- package/dist/llm/index.d.ts +6 -4
- package/dist/llm/index.js +76 -261
- package/dist/llm/openai-client.d.ts +1 -0
- package/dist/llm/openai-client.js +7 -2
- package/dist/qa/checks.d.ts +10 -0
- package/dist/qa/checks.js +492 -0
- package/dist/qa/fixes.d.ts +30 -0
- package/dist/qa/fixes.js +277 -0
- package/dist/qa/index.d.ts +29 -0
- package/dist/qa/index.js +187 -0
- package/dist/qa/types.d.ts +24 -0
- package/dist/qa/types.js +1 -0
- package/dist/scanner/csharp.d.ts +23 -0
- package/dist/scanner/csharp.js +421 -0
- package/dist/scanner/index.js +16 -2
- package/dist/scanner/java.d.ts +39 -0
- package/dist/scanner/java.js +318 -0
- package/dist/scanner/kotlin.d.ts +23 -0
- package/dist/scanner/kotlin.js +389 -0
- package/dist/scanner/php.d.ts +57 -0
- package/dist/scanner/php.js +351 -0
- package/dist/scanner/ruby.d.ts +36 -0
- package/dist/scanner/ruby.js +431 -0
- package/dist/scanner/swift.d.ts +25 -0
- package/dist/scanner/swift.js +392 -0
- package/dist/scanner/types.d.ts +1 -1
- package/dist/template/content/docs/_navigation.json +46 -0
- package/dist/template/content/docs/_sidebars.json +684 -0
- package/dist/template/content/docs/core.md +4544 -0
- package/dist/template/content/docs/index.mdx +89 -0
- package/dist/template/content/docs/integrations.md +1158 -0
- package/dist/template/content/docs/llms-full.md +403 -0
- package/dist/template/content/docs/llms.txt +4588 -0
- package/dist/template/content/docs/other.md +10379 -0
- package/dist/template/content/docs/tools.md +746 -0
- package/dist/template/content/docs/types.md +531 -0
- package/dist/template/docs.json +13 -11
- package/dist/template/mdx-components.tsx +27 -2
- package/dist/template/package.json +6 -0
- package/dist/template/public/search-index.json +1 -1
- package/dist/template/scripts/build-search-index.mjs +84 -6
- package/dist/template/src/app/api/chat/route.ts +83 -128
- package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
- package/dist/template/src/app/docs/llms-full.md +151 -4
- package/dist/template/src/app/docs/llms.txt +2464 -847
- package/dist/template/src/app/docs/page.mdx +48 -38
- package/dist/template/src/app/layout.tsx +3 -1
- package/dist/template/src/app/page.tsx +22 -8
- package/dist/template/src/components/ai-chat.tsx +73 -64
- package/dist/template/src/components/breadcrumbs.tsx +21 -23
- package/dist/template/src/components/copy-button.tsx +13 -9
- package/dist/template/src/components/copy-page-button.tsx +54 -0
- package/dist/template/src/components/docs-layout.tsx +37 -25
- package/dist/template/src/components/header.tsx +51 -10
- package/dist/template/src/components/mdx/card.tsx +17 -3
- package/dist/template/src/components/mdx/code-block.tsx +13 -9
- package/dist/template/src/components/mdx/code-group.tsx +13 -8
- package/dist/template/src/components/mdx/heading.tsx +15 -2
- package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
- package/dist/template/src/components/mdx/index.tsx +2 -0
- package/dist/template/src/components/mdx/mermaid.tsx +110 -0
- package/dist/template/src/components/mdx/screenshot.tsx +150 -0
- package/dist/template/src/components/scroll-to-hash.tsx +48 -0
- package/dist/template/src/components/sidebar.tsx +12 -18
- package/dist/template/src/components/table-of-contents.tsx +9 -0
- package/dist/template/src/lib/highlight.ts +3 -88
- package/dist/template/src/lib/navigation.ts +159 -0
- package/dist/template/src/styles/globals.css +17 -6
- package/dist/utils/validation.d.ts +0 -3
- package/dist/utils/validation.js +0 -26
- package/package.json +3 -2
|
@@ -0,0 +1,1158 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "Integrations"
|
|
3
|
+
description: "Third-party integrations"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
<CardGroup cols={2}>
|
|
7
|
+
<Card title="AnthropicClient" icon="cube" href="#anthropicclient">
|
|
8
|
+
Claude LLM client with retries
|
|
9
|
+
</Card>
|
|
10
|
+
<Card title="OpenAICompatibleClient" icon="cube" href="#openaicompatibleclient">
|
|
11
|
+
Universal OpenAI-compatible client
|
|
12
|
+
</Card>
|
|
13
|
+
<Card title="AnthropicClient.complete" icon="code" href="#anthropicclientcomplete">
|
|
14
|
+
Sends prompts to Claude models
|
|
15
|
+
</Card>
|
|
16
|
+
<Card title="OpenAICompatibleClient.complete" icon="code" href="#openaicompatibleclientcomplete">
|
|
17
|
+
Sends OpenAI chat completions
|
|
18
|
+
</Card>
|
|
19
|
+
<Card title="AnthropicClient.constructor" icon="code" href="#anthropicclientconstructor">
|
|
20
|
+
Creates Anthropic LLM client
|
|
21
|
+
</Card>
|
|
22
|
+
<Card title="OpenAICompatibleClient.constructor" icon="code" href="#openaicompatibleclientconstructor">
|
|
23
|
+
Creates OpenAI-compatible client
|
|
24
|
+
</Card>
|
|
25
|
+
<Card title="AnthropicClient.isConfigured" icon="code" href="#anthropicclientisconfigured">
|
|
26
|
+
Checks Anthropic client readiness
|
|
27
|
+
</Card>
|
|
28
|
+
<Card title="OpenAICompatibleClient.isConfigured" icon="code" href="#openaicompatibleclientisconfigured">
|
|
29
|
+
Checks OpenAI client readiness
|
|
30
|
+
</Card>
|
|
31
|
+
</CardGroup>
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
## `AnthropicClient`
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
class AnthropicClient implements LLMClient
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Use this to send prompts to Anthropic's Claude models and receive structured completions — with automatic retries built in.
|
|
41
|
+
|
|
42
|
+
`AnthropicClient` wraps the Anthropic SDK and implements a common `LLMClient` interface, making it easy to swap between LLM providers without changing your application logic.
|
|
43
|
+
|
|
44
|
+
## Constructor Parameters
|
|
45
|
+
|
|
46
|
+
| Name | Type | Required | Description |
|
|
47
|
+
|------|------|----------|-------------|
|
|
48
|
+
| `config.model` | `string` | Yes | The Claude model to use (e.g. `"claude-3-5-sonnet-20241022"`) |
|
|
49
|
+
| `config.apiKey` | `string` | Yes | Your Anthropic API key |
|
|
50
|
+
| `config.maxRetries` | `number` | No | Number of retry attempts on failure. Defaults to `3` |
|
|
51
|
+
|
|
52
|
+
## Properties
|
|
53
|
+
|
|
54
|
+
| Property | Type | Description |
|
|
55
|
+
|----------|------|-------------|
|
|
56
|
+
| `provider` | `'anthropic'` | Always `'anthropic'` — useful for provider-switching logic |
|
|
57
|
+
|
|
58
|
+
## Methods
|
|
59
|
+
|
|
60
|
+
### `complete(request: CompletionRequest): Promise<CompletionResponse>`
|
|
61
|
+
|
|
62
|
+
Sends a completion request to Claude and returns the model's response.
|
|
63
|
+
|
|
64
|
+
| Name | Type | Required | Description |
|
|
65
|
+
|------|------|----------|-------------|
|
|
66
|
+
| `request.messages` | `Array<{ role: 'user' \| 'assistant', content: string }>` | Yes | Conversation history to send |
|
|
67
|
+
| `request.systemPrompt` | `string` | No | System-level instruction prepended to the conversation |
|
|
68
|
+
| `request.maxTokens` | `number` | No | Maximum tokens in the response |
|
|
69
|
+
|
|
70
|
+
**Returns:** A `CompletionResponse` containing:
|
|
71
|
+
- `content` — the model's reply text
|
|
72
|
+
- `usage` — token counts (`inputTokens`, `outputTokens`)
|
|
73
|
+
- `model` — the model that generated the response
|
|
74
|
+
|
|
75
|
+
### Example
|
|
76
|
+
|
|
77
|
+
```typescript example.ts
|
|
78
|
+
// ── Inline types (no external imports needed) ──────────────────────────────
|
|
79
|
+
|
|
80
|
+
type LLMProvider = 'anthropic' | 'openai'
|
|
81
|
+
|
|
82
|
+
type LLMClientConfig = {
|
|
83
|
+
model: string
|
|
84
|
+
apiKey: string
|
|
85
|
+
maxRetries?: number
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
type CompletionRequest = {
|
|
89
|
+
messages: Array<{ role: 'user' | 'assistant'; content: string }>
|
|
90
|
+
systemPrompt?: string
|
|
91
|
+
maxTokens?: number
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type CompletionResponse = {
|
|
95
|
+
content: string
|
|
96
|
+
model: string
|
|
97
|
+
usage: { inputTokens: number; outputTokens: number }
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// ── Simulated AnthropicClient (mirrors real implementation) ────────────────
|
|
101
|
+
|
|
102
|
+
class AnthropicClient {
|
|
103
|
+
provider: LLMProvider = 'anthropic'
|
|
104
|
+
private model: string
|
|
105
|
+
private apiKey: string
|
|
106
|
+
private maxRetries: number
|
|
107
|
+
|
|
108
|
+
constructor(config: LLMClientConfig) {
|
|
109
|
+
this.model = config.model
|
|
110
|
+
this.apiKey = config.apiKey
|
|
111
|
+
this.maxRetries = config.maxRetries ?? 3
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
115
|
+
const body = {
|
|
116
|
+
model: this.model,
|
|
117
|
+
max_tokens: request.maxTokens ?? 1024,
|
|
118
|
+
system: request.systemPrompt,
|
|
119
|
+
messages: request.messages,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
let lastError: Error | undefined
|
|
123
|
+
|
|
124
|
+
for (let attempt = 1; attempt <= this.maxRetries; attempt++) {
|
|
125
|
+
try {
|
|
126
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
127
|
+
method: 'POST',
|
|
128
|
+
headers: {
|
|
129
|
+
'x-api-key': this.apiKey,
|
|
130
|
+
'anthropic-version': '2023-06-01',
|
|
131
|
+
'content-type': 'application/json',
|
|
132
|
+
},
|
|
133
|
+
body: JSON.stringify(body),
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
if (!response.ok) {
|
|
137
|
+
throw new Error(`Anthropic API error: ${response.status} ${response.statusText}`)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const data = await response.json() as {
|
|
141
|
+
content: Array<{ text: string }>
|
|
142
|
+
model: string
|
|
143
|
+
usage: { input_tokens: number; output_tokens: number }
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
content: data.content[0].text,
|
|
148
|
+
model: data.model,
|
|
149
|
+
usage: {
|
|
150
|
+
inputTokens: data.usage.input_tokens,
|
|
151
|
+
outputTokens: data.usage.output_tokens,
|
|
152
|
+
},
|
|
153
|
+
}
|
|
154
|
+
} catch (error) {
|
|
155
|
+
lastError = error instanceof Error ? error : new Error(String(error))
|
|
156
|
+
if (attempt < this.maxRetries) {
|
|
157
|
+
console.warn(`Attempt ${attempt} failed, retrying...`)
|
|
158
|
+
await new Promise(resolve => setTimeout(resolve, 500 * attempt))
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
throw lastError
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// ── Usage example ──────────────────────────────────────────────────────────
|
|
168
|
+
|
|
169
|
+
const client = new AnthropicClient({
|
|
170
|
+
apiKey: process.env.ANTHROPIC_API_KEY || 'your-anthropic-api-key',
|
|
171
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
172
|
+
maxRetries: 3,
|
|
173
|
+
})
|
|
174
|
+
|
|
175
|
+
async function main() {
|
|
176
|
+
try {
|
|
177
|
+
const response = await client.complete({
|
|
178
|
+
systemPrompt: 'You are a concise assistant. Reply in one sentence.',
|
|
179
|
+
messages: [
|
|
180
|
+
{ role: 'user', content: 'What is the capital of Japan?' },
|
|
181
|
+
],
|
|
182
|
+
maxTokens: 100,
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
console.log('Provider: ', client.provider)
|
|
186
|
+
console.log('Model: ', response.model)
|
|
187
|
+
console.log('Reply: ', response.content)
|
|
188
|
+
console.log('Tokens: ', response.usage)
|
|
189
|
+
// Expected output:
|
|
190
|
+
// Provider: anthropic
|
|
191
|
+
// Model: claude-3-5-sonnet-20241022
|
|
192
|
+
// Reply: The capital of Japan is Tokyo.
|
|
193
|
+
// Tokens: { inputTokens: 28, outputTokens: 10 }
|
|
194
|
+
} catch (error) {
|
|
195
|
+
console.error('Completion failed after all retries:', error)
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
main()
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Related
|
|
203
|
+
|
|
204
|
+
<CardGroup cols={3}>
|
|
205
|
+
<Card title="AnthropicClient.constructor" icon="link" href="#anthropicclientconstructor">
|
|
206
|
+
Uses
|
|
207
|
+
</Card>
|
|
208
|
+
</CardGroup>
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
## `OpenAICompatibleClient`
|
|
214
|
+
|
|
215
|
+
```typescript
|
|
216
|
+
class OpenAICompatibleClient implements LLMClient
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
Use this to connect to any OpenAI-compatible LLM provider — including OpenAI, DeepSeek, Ollama, OpenRouter, and Google Gemini — through a single unified client interface.
|
|
220
|
+
|
|
221
|
+
`OpenAICompatibleClient` normalizes provider differences (base URLs, auth headers, retry logic) so you can swap providers without changing your application code.
|
|
222
|
+
|
|
223
|
+
## Constructor Config
|
|
224
|
+
|
|
225
|
+
| Name | Type | Required | Description |
|
|
226
|
+
|------|------|----------|-------------|
|
|
227
|
+
| `provider` | `LLMProvider` | ✅ | Provider identifier (e.g. `'openai'`, `'deepseek'`, `'ollama'`, `'openrouter'`, `'gemini'`) |
|
|
228
|
+
| `model` | `string` | ✅ | Model name to use (e.g. `'gpt-4o'`, `'deepseek-chat'`, `'llama3'`) |
|
|
229
|
+
| `apiKey` | `string` | ✅ | API key for the provider (use `'ollama'` or any placeholder for local providers) |
|
|
230
|
+
| `maxRetries` | `number` | ❌ | Number of retry attempts on failure. Defaults to `3` |
|
|
231
|
+
|
|
232
|
+
## Properties
|
|
233
|
+
|
|
234
|
+
| Name | Type | Description |
|
|
235
|
+
|------|------|-------------|
|
|
236
|
+
| `provider` | `LLMProvider` | The configured provider for this client instance |
|
|
237
|
+
|
|
238
|
+
## Methods
|
|
239
|
+
|
|
240
|
+
### `complete(request: CompletionRequest): Promise<CompletionResponse>`
|
|
241
|
+
|
|
242
|
+
Sends a completion request to the configured provider and returns the model's response.
|
|
243
|
+
|
|
244
|
+
| Name | Type | Required | Description |
|
|
245
|
+
|------|------|----------|-------------|
|
|
246
|
+
| `request.messages` | `Message[]` | ✅ | Array of `{ role: 'system' \| 'user' \| 'assistant', content: string }` |
|
|
247
|
+
| `request.temperature` | `number` | ❌ | Sampling temperature (0–2). Lower = more deterministic |
|
|
248
|
+
| `request.maxTokens` | `number` | ❌ | Maximum tokens in the response |
|
|
249
|
+
|
|
250
|
+
**Returns:** `Promise<CompletionResponse>` — resolves with `{ content: string, usage?: { promptTokens, completionTokens, totalTokens } }`
|
|
251
|
+
|
|
252
|
+
## Supported Providers
|
|
253
|
+
|
|
254
|
+
| Provider | `provider` value | Notes |
|
|
255
|
+
|----------|-----------------|-------|
|
|
256
|
+
| OpenAI | `'openai'` | Requires OpenAI API key |
|
|
257
|
+
| DeepSeek | `'deepseek'` | Requires DeepSeek API key |
|
|
258
|
+
| Ollama | `'ollama'` | Local — no API key needed |
|
|
259
|
+
| OpenRouter | `'openrouter'` | Routes to many models |
|
|
260
|
+
| Google Gemini | `'gemini'` | Requires Google API key |
|
|
261
|
+
|
|
262
|
+
### Related
|
|
263
|
+
|
|
264
|
+
<CardGroup cols={3}>
|
|
265
|
+
<Card title="OpenAICompatibleClient.constructor" icon="link" href="#openaicompatibleclientconstructor">
|
|
266
|
+
Uses
|
|
267
|
+
</Card>
|
|
268
|
+
</CardGroup>
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
## `AnthropicClient.complete`
|
|
274
|
+
|
|
275
|
+
```typescript
|
|
276
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse>
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
Use this to send a conversation to Anthropic's Claude models and receive a completion response, handling system prompts and multi-turn conversations automatically.
|
|
280
|
+
|
|
281
|
+
This method separates system messages from conversation messages internally, so you can pass a unified message array without pre-processing. It wraps Anthropic's SDK and returns a normalized `CompletionResponse` regardless of which Claude model you target.
|
|
282
|
+
|
|
283
|
+
## Parameters
|
|
284
|
+
|
|
285
|
+
| Name | Type | Required | Description |
|
|
286
|
+
|------|------|----------|-------------|
|
|
287
|
+
| `request` | `CompletionRequest` | Yes | The completion request object containing messages, model, and generation settings |
|
|
288
|
+
| `request.messages` | `Message[]` | Yes | Array of messages with `role` (`"system"`, `"user"`, `"assistant"`) and `content` string |
|
|
289
|
+
| `request.model` | `string` | No | Claude model ID (e.g. `"claude-3-5-sonnet-20241022"`). Falls back to the client's default model if omitted |
|
|
290
|
+
| `request.maxTokens` | `number` | No | Maximum tokens to generate in the response |
|
|
291
|
+
| `request.temperature` | `number` | No | Sampling temperature between `0` and `1`. Lower = more deterministic |
|
|
292
|
+
| `request.stopSequences` | `string[]` | No | Sequences that will halt generation when encountered |
|
|
293
|
+
|
|
294
|
+
## Returns
|
|
295
|
+
|
|
296
|
+
Returns a `Promise<CompletionResponse>` that resolves with:
|
|
297
|
+
|
|
298
|
+
| Field | Type | Description |
|
|
299
|
+
|-------|------|-------------|
|
|
300
|
+
| `content` | `string` | The generated text from Claude |
|
|
301
|
+
| `model` | `string` | The model ID that produced the response |
|
|
302
|
+
| `usage.inputTokens` | `number` | Number of tokens in the prompt |
|
|
303
|
+
| `usage.outputTokens` | `number` | Number of tokens in the completion |
|
|
304
|
+
| `stopReason` | `string` | Why generation stopped (e.g. `"end_turn"`, `"max_tokens"`) |
|
|
305
|
+
|
|
306
|
+
Rejects with an error if the API key is invalid, the model ID is unrecognized, or the request exceeds context limits.
|
|
307
|
+
|
|
308
|
+
### Example
|
|
309
|
+
|
|
310
|
+
```typescript example.ts
|
|
311
|
+
// ── Inline types (no external imports needed) ──────────────────────────────
|
|
312
|
+
|
|
313
|
+
type MessageRole = 'system' | 'user' | 'assistant'
|
|
314
|
+
|
|
315
|
+
interface Message {
|
|
316
|
+
role: MessageRole
|
|
317
|
+
content: string
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
interface CompletionRequest {
|
|
321
|
+
messages: Message[]
|
|
322
|
+
model?: string
|
|
323
|
+
maxTokens?: number
|
|
324
|
+
temperature?: number
|
|
325
|
+
stopSequences?: string[]
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
interface CompletionResponse {
|
|
329
|
+
content: string
|
|
330
|
+
model: string
|
|
331
|
+
usage: {
|
|
332
|
+
inputTokens: number
|
|
333
|
+
outputTokens: number
|
|
334
|
+
}
|
|
335
|
+
stopReason: string
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// ── Simulated AnthropicClient.complete implementation ──────────────────────
|
|
339
|
+
|
|
340
|
+
class AnthropicClient {
|
|
341
|
+
private model: string
|
|
342
|
+
private apiKey: string
|
|
343
|
+
|
|
344
|
+
constructor(config: { apiKey: string; model?: string }) {
|
|
345
|
+
this.apiKey = config.apiKey
|
|
346
|
+
this.model = config.model || 'claude-3-5-sonnet-20241022'
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
isConfigured(): boolean {
|
|
350
|
+
return true
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
354
|
+
const model = request.model || this.model
|
|
355
|
+
|
|
356
|
+
// Separate system message from conversation (mirrors real implementation)
|
|
357
|
+
const systemMessage = request.messages.find(m => m.role === 'system')
|
|
358
|
+
const conversationMessages = request.messages.filter(m => m.role !== 'system')
|
|
359
|
+
|
|
360
|
+
// Build the Anthropic API payload
|
|
361
|
+
const payload = {
|
|
362
|
+
model,
|
|
363
|
+
max_tokens: request.maxTokens ?? 1024,
|
|
364
|
+
temperature: request.temperature ?? 0.7,
|
|
365
|
+
...(systemMessage && { system: systemMessage.content }),
|
|
366
|
+
messages: conversationMessages.map(m => ({
|
|
367
|
+
role: m.role,
|
|
368
|
+
content: m.content,
|
|
369
|
+
})),
|
|
370
|
+
...(request.stopSequences && { stop_sequences: request.stopSequences }),
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const response = await fetch('https://api.anthropic.com/v1/messages', {
|
|
374
|
+
method: 'POST',
|
|
375
|
+
headers: {
|
|
376
|
+
'x-api-key': this.apiKey,
|
|
377
|
+
'anthropic-version': '2023-06-01',
|
|
378
|
+
'content-type': 'application/json',
|
|
379
|
+
},
|
|
380
|
+
body: JSON.stringify(payload),
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
if (!response.ok) {
|
|
384
|
+
const error = await response.json().catch(() => ({}))
|
|
385
|
+
throw new Error(
|
|
386
|
+
`Anthropic API error ${response.status}: ${(error as any).error?.message ?? response.statusText}`
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
const data = await response.json() as any
|
|
391
|
+
|
|
392
|
+
return {
|
|
393
|
+
content: data.content[0]?.text ?? '',
|
|
394
|
+
model: data.model,
|
|
395
|
+
usage: {
|
|
396
|
+
inputTokens: data.usage.input_tokens,
|
|
397
|
+
outputTokens: data.usage.output_tokens,
|
|
398
|
+
},
|
|
399
|
+
stopReason: data.stop_reason,
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// ── Usage example ──────────────────────────────────────────────────────────
|
|
405
|
+
|
|
406
|
+
const client = new AnthropicClient({
|
|
407
|
+
apiKey: process.env.ANTHROPIC_API_KEY || 'your-anthropic-api-key',
|
|
408
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
409
|
+
})
|
|
410
|
+
|
|
411
|
+
async function main() {
|
|
412
|
+
try {
|
|
413
|
+
const response = await client.complete({
|
|
414
|
+
messages: [
|
|
415
|
+
{
|
|
416
|
+
role: 'system',
|
|
417
|
+
content: 'You are a concise assistant. Reply in one sentence.',
|
|
418
|
+
},
|
|
419
|
+
{
|
|
420
|
+
role: 'user',
|
|
421
|
+
content: 'What is the capital of Japan?',
|
|
422
|
+
},
|
|
423
|
+
],
|
|
424
|
+
maxTokens: 256,
|
|
425
|
+
temperature: 0.3,
|
|
426
|
+
})
|
|
427
|
+
|
|
428
|
+
console.log('Reply: ', response.content)
|
|
429
|
+
console.log('Model: ', response.model)
|
|
430
|
+
console.log('Stop reason:', response.stopReason)
|
|
431
|
+
console.log('Tokens used:', response.usage)
|
|
432
|
+
|
|
433
|
+
// Expected output:
|
|
434
|
+
// Reply: The capital of Japan is Tokyo.
|
|
435
|
+
// Model: claude-3-5-sonnet-20241022
|
|
436
|
+
// Stop reason: end_turn
|
|
437
|
+
// Tokens used: { inputTokens: 32, outputTokens: 9 }
|
|
438
|
+
} catch (error) {
|
|
439
|
+
console.error('Completion failed:', error instanceof Error ? error.message : error)
|
|
440
|
+
process.exit(1)
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
main()
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Related
|
|
448
|
+
|
|
449
|
+
<CardGroup cols={3}>
|
|
450
|
+
<Card title="AnthropicClient.isConfigured" icon="link" href="#anthropicclientisconfigured">
|
|
451
|
+
Uses
|
|
452
|
+
</Card>
|
|
453
|
+
<Card title="OpenAICompatibleClient.isConfigured" icon="link" href="#openaicompatibleclientisconfigured">
|
|
454
|
+
Uses
|
|
455
|
+
</Card>
|
|
456
|
+
<Card title="AnthropicClient.isConfigured" icon="link" href="#anthropicclientisconfigured">
|
|
457
|
+
Used by
|
|
458
|
+
</Card>
|
|
459
|
+
<Card title="OpenAICompatibleClient.isConfigured" icon="link" href="#openaicompatibleclientisconfigured">
|
|
460
|
+
Used by
|
|
461
|
+
</Card>
|
|
462
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
463
|
+
Related
|
|
464
|
+
</Card>
|
|
465
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
466
|
+
Related
|
|
467
|
+
</Card>
|
|
468
|
+
</CardGroup>
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
|
|
473
|
+
## `OpenAICompatibleClient.complete`
|
|
474
|
+
|
|
475
|
+
```typescript
|
|
476
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse>
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
Use this to send a chat completion request to any OpenAI-compatible API endpoint (OpenAI, Azure, Groq, Together AI, etc.) and receive a structured response with the generated text and token usage.
|
|
480
|
+
|
|
481
|
+
## Parameters
|
|
482
|
+
|
|
483
|
+
| Name | Type | Required | Description |
|
|
484
|
+
|------|------|----------|-------------|
|
|
485
|
+
| `request` | `CompletionRequest` | Yes | The completion request object containing messages, model, and generation settings |
|
|
486
|
+
| `request.messages` | `Array<{role: string, content: string}>` | Yes | Conversation history as an array of role/content message objects |
|
|
487
|
+
| `request.model` | `string` | No | Model identifier to use (e.g. `"gpt-4o"`, `"llama-3-8b"`). Falls back to the client's default model if omitted |
|
|
488
|
+
| `request.temperature` | `number` | No | Sampling temperature between 0–2. Lower = more deterministic, higher = more creative |
|
|
489
|
+
| `request.maxTokens` | `number` | No | Maximum number of tokens to generate in the response |
|
|
490
|
+
| `request.systemPrompt` | `string` | No | System-level instruction prepended to the conversation |
|
|
491
|
+
|
|
492
|
+
## Returns
|
|
493
|
+
|
|
494
|
+
Returns a `Promise<CompletionResponse>` that resolves with:
|
|
495
|
+
|
|
496
|
+
| Field | Type | Description |
|
|
497
|
+
|-------|------|-------------|
|
|
498
|
+
| `content` | `string` | The generated text from the model |
|
|
499
|
+
| `model` | `string` | The model that was actually used to generate the response |
|
|
500
|
+
| `usage.promptTokens` | `number` | Number of tokens consumed by the input messages |
|
|
501
|
+
| `usage.completionTokens` | `number` | Number of tokens in the generated response |
|
|
502
|
+
| `usage.totalTokens` | `number` | Total tokens used (prompt + completion) |
|
|
503
|
+
|
|
504
|
+
Throws an error if the API request fails, the model is unavailable, or the API key is invalid.
|
|
505
|
+
|
|
506
|
+
### Example
|
|
507
|
+
|
|
508
|
+
```typescript example.ts
|
|
509
|
+
import OpenAI from 'openai'
|
|
510
|
+
|
|
511
|
+
// --- Inline types (do not import from library) ---
|
|
512
|
+
interface Message {
|
|
513
|
+
role: 'system' | 'user' | 'assistant'
|
|
514
|
+
content: string
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
interface CompletionRequest {
|
|
518
|
+
messages: Message[]
|
|
519
|
+
model?: string
|
|
520
|
+
temperature?: number
|
|
521
|
+
maxTokens?: number
|
|
522
|
+
systemPrompt?: string
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
interface CompletionResponse {
|
|
526
|
+
content: string
|
|
527
|
+
model: string
|
|
528
|
+
usage: {
|
|
529
|
+
promptTokens: number
|
|
530
|
+
completionTokens: number
|
|
531
|
+
totalTokens: number
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// --- Inline OpenAI-compatible client implementation ---
|
|
536
|
+
class OpenAICompatibleClient {
|
|
537
|
+
private client: OpenAI
|
|
538
|
+
private model: string
|
|
539
|
+
|
|
540
|
+
constructor(config: { apiKey: string; baseURL?: string; defaultModel?: string }) {
|
|
541
|
+
this.client = new OpenAI({
|
|
542
|
+
apiKey: config.apiKey,
|
|
543
|
+
baseURL: config.baseURL,
|
|
544
|
+
})
|
|
545
|
+
this.model = config.defaultModel || 'gpt-4o-mini'
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
549
|
+
const model = request.model || this.model
|
|
550
|
+
|
|
551
|
+
const messages: Message[] = []
|
|
552
|
+
|
|
553
|
+
if (request.systemPrompt) {
|
|
554
|
+
messages.push({ role: 'system', content: request.systemPrompt })
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
messages.push(...request.messages)
|
|
558
|
+
|
|
559
|
+
const response = await this.client.chat.completions.create({
|
|
560
|
+
model,
|
|
561
|
+
messages,
|
|
562
|
+
temperature: request.temperature ?? 0.7,
|
|
563
|
+
max_tokens: request.maxTokens,
|
|
564
|
+
})
|
|
565
|
+
|
|
566
|
+
const choice = response.choices[0]
|
|
567
|
+
|
|
568
|
+
return {
|
|
569
|
+
content: choice.message.content ?? '',
|
|
570
|
+
model: response.model,
|
|
571
|
+
usage: {
|
|
572
|
+
promptTokens: response.usage?.prompt_tokens ?? 0,
|
|
573
|
+
completionTokens: response.usage?.completion_tokens ?? 0,
|
|
574
|
+
totalTokens: response.usage?.total_tokens ?? 0,
|
|
575
|
+
},
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
// --- Usage example ---
|
|
581
|
+
const client = new OpenAICompatibleClient({
|
|
582
|
+
apiKey: process.env.OPENAI_API_KEY || 'sk-your-api-key-here',
|
|
583
|
+
defaultModel: 'gpt-4o-mini',
|
|
584
|
+
// Swap baseURL to use Groq, Together AI, etc.:
|
|
585
|
+
// baseURL: 'https://api.groq.com/openai/v1'
|
|
586
|
+
})
|
|
587
|
+
|
|
588
|
+
async function main() {
|
|
589
|
+
try {
|
|
590
|
+
const response = await client.complete({
|
|
591
|
+
systemPrompt: 'You are a concise assistant. Reply in one sentence.',
|
|
592
|
+
messages: [
|
|
593
|
+
{ role: 'user', content: 'What is the capital of Japan?' },
|
|
594
|
+
],
|
|
595
|
+
temperature: 0.3,
|
|
596
|
+
maxTokens: 60,
|
|
597
|
+
})
|
|
598
|
+
|
|
599
|
+
console.log('Generated text:', response.content)
|
|
600
|
+
// Output: "The capital of Japan is Tokyo."
|
|
601
|
+
|
|
602
|
+
console.log('Model used:', response.model)
|
|
603
|
+
// Output: "gpt-4o-mini"
|
|
604
|
+
|
|
605
|
+
console.log('Token usage:', response.usage)
|
|
606
|
+
// Output: { promptTokens: 28, completionTokens: 10, totalTokens: 38 }
|
|
607
|
+
} catch (error) {
|
|
608
|
+
if (error instanceof Error) {
|
|
609
|
+
console.error('Completion failed:', error.message)
|
|
610
|
+
// Common causes: invalid API key, unknown model name, rate limit exceeded
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
main()
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Related
|
|
619
|
+
|
|
620
|
+
<CardGroup cols={3}>
|
|
621
|
+
<Card title="AnthropicClient.isConfigured" icon="link" href="#anthropicclientisconfigured">
|
|
622
|
+
Uses
|
|
623
|
+
</Card>
|
|
624
|
+
<Card title="OpenAICompatibleClient.isConfigured" icon="link" href="#openaicompatibleclientisconfigured">
|
|
625
|
+
Uses
|
|
626
|
+
</Card>
|
|
627
|
+
<Card title="AnthropicClient.isConfigured" icon="link" href="#anthropicclientisconfigured">
|
|
628
|
+
Used by
|
|
629
|
+
</Card>
|
|
630
|
+
<Card title="OpenAICompatibleClient.isConfigured" icon="link" href="#openaicompatibleclientisconfigured">
|
|
631
|
+
Used by
|
|
632
|
+
</Card>
|
|
633
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
634
|
+
Related
|
|
635
|
+
</Card>
|
|
636
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
637
|
+
Related
|
|
638
|
+
</Card>
|
|
639
|
+
</CardGroup>
|
|
640
|
+
|
|
641
|
+
---
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
## `AnthropicClient.constructor`
|
|
645
|
+
|
|
646
|
+
```typescript
|
|
647
|
+
constructor(config: LLMClientConfig)
|
|
648
|
+
```
|
|
649
|
+
|
|
650
|
+
Use this to create an Anthropic-backed LLM client that handles retries and model configuration for sending completion requests.
|
|
651
|
+
|
|
652
|
+
The `AnthropicClient` constructor initializes a client instance configured with your Anthropic API key, target model, and retry behavior. It wraps the Anthropic SDK to provide a consistent interface for making LLM calls.
|
|
653
|
+
|
|
654
|
+
### Parameters
|
|
655
|
+
|
|
656
|
+
| Name | Type | Required | Description |
|
|
657
|
+
|------|------|----------|-------------|
|
|
658
|
+
| `config.apiKey` | `string` | Yes | Your Anthropic API key used to authenticate requests |
|
|
659
|
+
| `config.model` | `string` | Yes | The Anthropic model to use (e.g., `claude-3-5-sonnet-20241022`) |
|
|
660
|
+
| `config.maxRetries` | `number` | No | Number of times to retry failed requests. Defaults to `3` |
|
|
661
|
+
|
|
662
|
+
### Returns
|
|
663
|
+
|
|
664
|
+
Returns an `AnthropicClient` instance with:
|
|
665
|
+
- `provider` — always `'anthropic'`
|
|
666
|
+
- Access to completion methods for sending prompts to the configured model
|
|
667
|
+
|
|
668
|
+
### When to use
|
|
669
|
+
|
|
670
|
+
- You need a reusable client scoped to a specific Anthropic model
|
|
671
|
+
- You want automatic retry logic on transient API failures
|
|
672
|
+
- You are building a multi-provider LLM system and need an Anthropic-compatible implementation
|
|
673
|
+
|
|
674
|
+
### Example
|
|
675
|
+
|
|
676
|
+
```typescript example.ts
|
|
677
|
+
// Inline type definitions (do not import from autodocs)
|
|
678
|
+
type LLMProvider = 'anthropic' | 'openai'
|
|
679
|
+
|
|
680
|
+
interface LLMClientConfig {
|
|
681
|
+
apiKey: string
|
|
682
|
+
model: string
|
|
683
|
+
maxRetries?: number
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
interface CompletionRequest {
|
|
687
|
+
prompt: string
|
|
688
|
+
maxTokens?: number
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
interface CompletionResponse {
|
|
692
|
+
text: string
|
|
693
|
+
usage?: { inputTokens: number; outputTokens: number }
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
// Simulated AnthropicClient (mirrors the real implementation)
|
|
697
|
+
class AnthropicClient {
|
|
698
|
+
provider: LLMProvider = 'anthropic'
|
|
699
|
+
private model: string
|
|
700
|
+
private maxRetries: number
|
|
701
|
+
private apiKey: string
|
|
702
|
+
|
|
703
|
+
constructor(config: LLMClientConfig) {
|
|
704
|
+
if (!config.apiKey) throw new Error('apiKey is required')
|
|
705
|
+
if (!config.model) throw new Error('model is required')
|
|
706
|
+
|
|
707
|
+
this.apiKey = config.apiKey
|
|
708
|
+
this.model = config.model
|
|
709
|
+
this.maxRetries = config.maxRetries ?? 3
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
// Simulated completion method
|
|
713
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
714
|
+
console.log(`[${this.provider}] Sending request to model: ${this.model}`)
|
|
715
|
+
console.log(`[${this.provider}] Max retries configured: ${this.maxRetries}`)
|
|
716
|
+
console.log(`[${this.provider}] Prompt: "${request.prompt}"`)
|
|
717
|
+
|
|
718
|
+
// Simulated response (real client would call Anthropic API here)
|
|
719
|
+
return {
|
|
720
|
+
text: `Simulated response from ${this.model}`,
|
|
721
|
+
usage: { inputTokens: 12, outputTokens: 8 },
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
// --- Usage Example ---
|
|
727
|
+
|
|
728
|
+
async function main() {
|
|
729
|
+
try {
|
|
730
|
+
// Initialize the client with your Anthropic credentials
|
|
731
|
+
const client = new AnthropicClient({
|
|
732
|
+
apiKey: process.env.ANTHROPIC_API_KEY || 'sk-ant-your-api-key-here',
|
|
733
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
734
|
+
maxRetries: 5, // optional, defaults to 3
|
|
735
|
+
})
|
|
736
|
+
|
|
737
|
+
console.log('Provider:', client.provider)
|
|
738
|
+
// Output: Provider: anthropic
|
|
739
|
+
|
|
740
|
+
const response = await client.complete({
|
|
741
|
+
prompt: 'Explain recursion in one sentence.',
|
|
742
|
+
maxTokens: 100,
|
|
743
|
+
})
|
|
744
|
+
|
|
745
|
+
console.log('Response:', response.text)
|
|
746
|
+
// Output: Response: Simulated response from claude-3-5-sonnet-20241022
|
|
747
|
+
|
|
748
|
+
console.log('Token usage:', response.usage)
|
|
749
|
+
// Output: Token usage: { inputTokens: 12, outputTokens: 8 }
|
|
750
|
+
} catch (error) {
|
|
751
|
+
if (error instanceof Error) {
|
|
752
|
+
console.error('Failed to initialize AnthropicClient:', error.message)
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
main()
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Related
|
|
761
|
+
|
|
762
|
+
<CardGroup cols={3}>
|
|
763
|
+
<Card title="PluginManager" icon="link" href="/docs/core#pluginmanager">
|
|
764
|
+
Uses
|
|
765
|
+
</Card>
|
|
766
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
767
|
+
Used by
|
|
768
|
+
</Card>
|
|
769
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
770
|
+
Used by
|
|
771
|
+
</Card>
|
|
772
|
+
<Card title="PluginManager" icon="link" href="/docs/core#pluginmanager">
|
|
773
|
+
Used by
|
|
774
|
+
</Card>
|
|
775
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
776
|
+
Related
|
|
777
|
+
</Card>
|
|
778
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
779
|
+
Related
|
|
780
|
+
</Card>
|
|
781
|
+
</CardGroup>
|
|
782
|
+
|
|
783
|
+
---
|
|
784
|
+
|
|
785
|
+
|
|
786
|
+
## `OpenAICompatibleClient.constructor`
|
|
787
|
+
|
|
788
|
+
```typescript
|
|
789
|
+
constructor(config: LLMClientConfig)
|
|
790
|
+
```
|
|
791
|
+
|
|
792
|
+
Use this to create an LLM client that connects to any OpenAI-compatible API provider (OpenAI, Azure, Anthropic, local models, etc.) with automatic retry logic and provider-specific configuration.
|
|
793
|
+
|
|
794
|
+
## Parameters
|
|
795
|
+
|
|
796
|
+
| Name | Type | Required | Description |
|
|
797
|
+
|------|------|----------|-------------|
|
|
798
|
+
| `config` | `LLMClientConfig` | ✅ | Configuration object for the LLM client |
|
|
799
|
+
| `config.provider` | `LLMProvider` | ✅ | The LLM provider identifier (e.g., `'openai'`, `'anthropic'`, `'azure'`) |
|
|
800
|
+
| `config.model` | `string` | ✅ | The model name to use for completions (e.g., `'gpt-4o'`, `'claude-3-5-sonnet'`) |
|
|
801
|
+
| `config.apiKey` | `string` | ✅ | API key for authenticating with the provider |
|
|
802
|
+
| `config.baseUrl` | `string` | ❌ | Override the default base URL for the provider. Useful for local models or custom endpoints |
|
|
803
|
+
| `config.maxRetries` | `number` | ❌ | Number of times to retry failed requests. Defaults to `3` |
|
|
804
|
+
|
|
805
|
+
## Returns
|
|
806
|
+
|
|
807
|
+
An `OpenAICompatibleClient` instance with:
|
|
808
|
+
- `provider` — the resolved provider set on the instance
|
|
809
|
+
- `complete()` — method to send completion requests
|
|
810
|
+
- Automatic retry handling on transient failures
|
|
811
|
+
|
|
812
|
+
## Notes
|
|
813
|
+
|
|
814
|
+
- If `baseUrl` is omitted, the client falls back to a built-in map of known provider URLs (`PROVIDER_BASE_URLS`)
|
|
815
|
+
- `maxRetries` defaults to `3` if not specified
|
|
816
|
+
- The underlying HTTP client is an `OpenAI` SDK instance, making this compatible with any API that follows the OpenAI REST spec
|
|
817
|
+
|
|
818
|
+
### Example
|
|
819
|
+
|
|
820
|
+
```typescript example.ts
|
|
821
|
+
// ── Inline types (no external imports needed) ──────────────────────────────
|
|
822
|
+
|
|
823
|
+
type LLMProvider = 'openai' | 'anthropic' | 'azure' | 'ollama' | string
|
|
824
|
+
|
|
825
|
+
interface LLMClientConfig {
|
|
826
|
+
provider: LLMProvider
|
|
827
|
+
model: string
|
|
828
|
+
apiKey: string
|
|
829
|
+
baseUrl?: string
|
|
830
|
+
maxRetries?: number
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
interface CompletionRequest {
|
|
834
|
+
messages: { role: 'system' | 'user' | 'assistant'; content: string }[]
|
|
835
|
+
temperature?: number
|
|
836
|
+
maxTokens?: number
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
interface CompletionResponse {
|
|
840
|
+
content: string
|
|
841
|
+
usage?: { promptTokens: number; completionTokens: number }
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// ── Provider default URLs (mirrors PROVIDER_BASE_URLS) ─────────────────────
|
|
845
|
+
|
|
846
|
+
const PROVIDER_BASE_URLS: Record<string, string> = {
|
|
847
|
+
openai: 'https://api.openai.com/v1',
|
|
848
|
+
anthropic: 'https://api.anthropic.com/v1',
|
|
849
|
+
ollama: 'http://localhost:11434/v1',
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
// ── Simulated OpenAICompatibleClient ──────────────────────────────────────
|
|
853
|
+
|
|
854
|
+
class OpenAICompatibleClient {
|
|
855
|
+
provider: LLMProvider
|
|
856
|
+
private model: string
|
|
857
|
+
private maxRetries: number
|
|
858
|
+
private baseUrl: string
|
|
859
|
+
private apiKey: string
|
|
860
|
+
|
|
861
|
+
constructor(config: LLMClientConfig) {
|
|
862
|
+
this.provider = config.provider
|
|
863
|
+
this.model = config.model
|
|
864
|
+
this.maxRetries = config.maxRetries ?? 3
|
|
865
|
+
this.apiKey = config.apiKey
|
|
866
|
+
this.baseUrl = config.baseUrl || PROVIDER_BASE_URLS[config.provider] || ''
|
|
867
|
+
|
|
868
|
+
console.log(`[OpenAICompatibleClient] Initialized`)
|
|
869
|
+
console.log(` Provider : ${this.provider}`)
|
|
870
|
+
console.log(` Model : ${this.model}`)
|
|
871
|
+
console.log(` Base URL : ${this.baseUrl}`)
|
|
872
|
+
console.log(` Retries : ${this.maxRetries}`)
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
876
|
+
// Simulated response — replace with real OpenAI SDK call in production
|
|
877
|
+
const lastMessage = request.messages.at(-1)?.content ?? ''
|
|
878
|
+
return {
|
|
879
|
+
content: `[Simulated response to: "${lastMessage}"]`,
|
|
880
|
+
usage: { promptTokens: 12, completionTokens: 20 },
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
// ── Example 1: Standard OpenAI setup ──────────────────────────────────────
|
|
886
|
+
|
|
887
|
+
async function main() {
|
|
888
|
+
try {
|
|
889
|
+
const client = new OpenAICompatibleClient({
|
|
890
|
+
provider: 'openai',
|
|
891
|
+
model: 'gpt-4o',
|
|
892
|
+
apiKey: process.env.OPENAI_API_KEY || 'sk-your-api-key-here',
|
|
893
|
+
maxRetries: 3,
|
|
894
|
+
})
|
|
895
|
+
|
|
896
|
+
const response = await client.complete({
|
|
897
|
+
messages: [
|
|
898
|
+
{ role: 'system', content: 'You are a helpful assistant.' },
|
|
899
|
+
{ role: 'user', content: 'What is the capital of France?' },
|
|
900
|
+
],
|
|
901
|
+
temperature: 0.7,
|
|
902
|
+
})
|
|
903
|
+
|
|
904
|
+
console.log('\n[Response]', response.content)
|
|
905
|
+
console.log('[Usage]', response.usage)
|
|
906
|
+
// Output: [Response] [Simulated response to: "What is the capital of France?"]
|
|
907
|
+
// Output: [Usage] { promptTokens: 12, completionTokens: 20 }
|
|
908
|
+
|
|
909
|
+
// ── Example 2: Local Ollama model with custom base URL ─────────────────
|
|
910
|
+
|
|
911
|
+
const localClient = new OpenAICompatibleClient({
|
|
912
|
+
provider: 'ollama',
|
|
913
|
+
model: 'llama3.2',
|
|
914
|
+
apiKey: 'ollama', // Ollama doesn't require a real key
|
|
915
|
+
baseUrl: 'http://localhost:11434/v1', // explicit override
|
|
916
|
+
maxRetries: 1,
|
|
917
|
+
})
|
|
918
|
+
|
|
919
|
+
console.log('\n[Local provider]', localClient.provider)
|
|
920
|
+
// Output: [Local provider] ollama
|
|
921
|
+
|
|
922
|
+
} catch (error) {
|
|
923
|
+
console.error('Failed to initialize or call client:', error)
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
main()
|
|
928
|
+
```
|
|
929
|
+
|
|
930
|
+
### Related
|
|
931
|
+
|
|
932
|
+
<CardGroup cols={3}>
|
|
933
|
+
<Card title="PluginManager" icon="link" href="/docs/core#pluginmanager">
|
|
934
|
+
Uses
|
|
935
|
+
</Card>
|
|
936
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
937
|
+
Used by
|
|
938
|
+
</Card>
|
|
939
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
940
|
+
Used by
|
|
941
|
+
</Card>
|
|
942
|
+
<Card title="PluginManager" icon="link" href="/docs/core#pluginmanager">
|
|
943
|
+
Used by
|
|
944
|
+
</Card>
|
|
945
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
946
|
+
Related
|
|
947
|
+
</Card>
|
|
948
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
949
|
+
Related
|
|
950
|
+
</Card>
|
|
951
|
+
</CardGroup>
|
|
952
|
+
|
|
953
|
+
---
|
|
954
|
+
|
|
955
|
+
|
|
956
|
+
## `AnthropicClient.isConfigured`
|
|
957
|
+
|
|
958
|
+
```typescript
|
|
959
|
+
isConfigured(): boolean
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
Use this to verify that an `AnthropicClient` instance is ready to make API calls before attempting completions.
|
|
963
|
+
|
|
964
|
+
This method acts as a readiness check — it confirms the client has been initialized and the underlying Anthropic SDK has taken responsibility for credential validation. Call it as a guard before executing requests in conditional flows or health checks.
|
|
965
|
+
|
|
966
|
+
**Returns**
|
|
967
|
+
|
|
968
|
+
| Value | Condition |
|
|
969
|
+
|-------|-----------|
|
|
970
|
+
| `true` | Always — the client is initialized and the Anthropic SDK handles API key validation internally |
|
|
971
|
+
|
|
972
|
+
> **Note:** A `true` return does **not** guarantee the API key is valid or that the network is reachable. It confirms the client object is properly constructed. Actual credential errors surface when calling `complete()`.
|
|
973
|
+
|
|
974
|
+
### Example
|
|
975
|
+
|
|
976
|
+
```typescript example.ts
|
|
977
|
+
// Inline types to simulate AnthropicClient behavior
|
|
978
|
+
interface LLMClientConfig {
|
|
979
|
+
apiKey: string
|
|
980
|
+
model?: string
|
|
981
|
+
timeout?: number
|
|
982
|
+
maxRetries?: number
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
// Simulated AnthropicClient class (self-contained, no external imports)
|
|
986
|
+
class AnthropicClient {
|
|
987
|
+
private apiKey: string
|
|
988
|
+
private model: string
|
|
989
|
+
private timeout: number
|
|
990
|
+
private maxRetries: number
|
|
991
|
+
|
|
992
|
+
constructor(config: LLMClientConfig) {
|
|
993
|
+
this.apiKey = config.apiKey
|
|
994
|
+
this.model = config.model ?? 'claude-3-5-sonnet-20241022'
|
|
995
|
+
this.timeout = config.timeout ?? 60000
|
|
996
|
+
this.maxRetries = config.maxRetries ?? 2
|
|
997
|
+
}
|
|
998
|
+
|
|
999
|
+
isConfigured(): boolean {
|
|
1000
|
+
return true // Anthropic SDK handles validation
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
|
|
1004
|
+
// --- Usage Example ---
|
|
1005
|
+
|
|
1006
|
+
const client = new AnthropicClient({
|
|
1007
|
+
apiKey: process.env.ANTHROPIC_API_KEY || 'sk-ant-your-api-key-here',
|
|
1008
|
+
model: 'claude-3-5-sonnet-20241022',
|
|
1009
|
+
timeout: 30000,
|
|
1010
|
+
})
|
|
1011
|
+
|
|
1012
|
+
async function runCompletion() {
|
|
1013
|
+
try {
|
|
1014
|
+
// Guard against unconfigured clients before making requests
|
|
1015
|
+
if (!client.isConfigured()) {
|
|
1016
|
+
throw new Error('AnthropicClient is not configured. Check your API key and settings.')
|
|
1017
|
+
}
|
|
1018
|
+
|
|
1019
|
+
console.log('Client configured:', client.isConfigured())
|
|
1020
|
+
// Output: Client configured: true
|
|
1021
|
+
|
|
1022
|
+
console.log('Proceeding with API request...')
|
|
1023
|
+
// In real usage, you would call client.complete({ prompt: '...' }) here
|
|
1024
|
+
|
|
1025
|
+
} catch (error) {
|
|
1026
|
+
console.error('Client setup error:', error instanceof Error ? error.message : error)
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
|
|
1030
|
+
runCompletion()
|
|
1031
|
+
```
|
|
1032
|
+
|
|
1033
|
+
### Related
|
|
1034
|
+
|
|
1035
|
+
<CardGroup cols={3}>
|
|
1036
|
+
<Card title="AnthropicClient.complete" icon="link" href="#anthropicclientcomplete">
|
|
1037
|
+
Uses
|
|
1038
|
+
</Card>
|
|
1039
|
+
<Card title="OpenAICompatibleClient.complete" icon="link" href="#openaicompatibleclientcomplete">
|
|
1040
|
+
Uses
|
|
1041
|
+
</Card>
|
|
1042
|
+
<Card title="AnthropicClient.complete" icon="link" href="#anthropicclientcomplete">
|
|
1043
|
+
Used by
|
|
1044
|
+
</Card>
|
|
1045
|
+
<Card title="OpenAICompatibleClient.complete" icon="link" href="#openaicompatibleclientcomplete">
|
|
1046
|
+
Used by
|
|
1047
|
+
</Card>
|
|
1048
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
1049
|
+
Related
|
|
1050
|
+
</Card>
|
|
1051
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
1052
|
+
Related
|
|
1053
|
+
</Card>
|
|
1054
|
+
</CardGroup>
|
|
1055
|
+
|
|
1056
|
+
---
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
## `OpenAICompatibleClient.isConfigured`
|
|
1060
|
+
|
|
1061
|
+
```typescript
|
|
1062
|
+
isConfigured(): boolean
|
|
1063
|
+
```
|
|
1064
|
+
|
|
1065
|
+
Use this to verify that an `OpenAICompatibleClient` instance is ready to make API calls before attempting completions.
|
|
1066
|
+
|
|
1067
|
+
This method acts as a readiness check — it always returns `true` because the underlying OpenAI SDK handles API key validation and configuration errors at request time rather than at initialization. Use it in guard clauses or health checks to conform to a standard client interface without worrying about pre-flight validation logic.
|
|
1068
|
+
|
|
1069
|
+
### Returns
|
|
1070
|
+
|
|
1071
|
+
| Condition | Value |
|
|
1072
|
+
|-----------|-------|
|
|
1073
|
+
| Always | `true` — the OpenAI SDK manages its own configuration validation |
|
|
1074
|
+
|
|
1075
|
+
### Parameters
|
|
1076
|
+
|
|
1077
|
+
None.
|
|
1078
|
+
|
|
1079
|
+
### Example
|
|
1080
|
+
|
|
1081
|
+
```typescript example.ts
|
|
1082
|
+
// Inline the minimal interface and class needed to demonstrate isConfigured()
|
|
1083
|
+
interface LLMClientConfig {
|
|
1084
|
+
apiKey: string
|
|
1085
|
+
model?: string
|
|
1086
|
+
baseURL?: string
|
|
1087
|
+
maxRetries?: number
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// Simulated OpenAICompatibleClient with isConfigured behavior
|
|
1091
|
+
class OpenAICompatibleClient {
|
|
1092
|
+
private apiKey: string
|
|
1093
|
+
private model: string
|
|
1094
|
+
private baseURL?: string
|
|
1095
|
+
private maxRetries: number
|
|
1096
|
+
|
|
1097
|
+
constructor(config: LLMClientConfig) {
|
|
1098
|
+
this.apiKey = config.apiKey
|
|
1099
|
+
this.model = config.model || 'gpt-4o'
|
|
1100
|
+
this.baseURL = config.baseURL
|
|
1101
|
+
this.maxRetries = config.maxRetries ?? 3
|
|
1102
|
+
}
|
|
1103
|
+
|
|
1104
|
+
// Always returns true — OpenAI SDK handles validation internally
|
|
1105
|
+
isConfigured(): boolean {
|
|
1106
|
+
return true
|
|
1107
|
+
}
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
// --- Usage Example ---
|
|
1111
|
+
|
|
1112
|
+
const client = new OpenAICompatibleClient({
|
|
1113
|
+
apiKey: process.env.OPENAI_API_KEY || 'sk-your-api-key-here',
|
|
1114
|
+
model: 'gpt-4o',
|
|
1115
|
+
maxRetries: 2
|
|
1116
|
+
})
|
|
1117
|
+
|
|
1118
|
+
try {
|
|
1119
|
+
// Guard clause: check before attempting any completions
|
|
1120
|
+
if (!client.isConfigured()) {
|
|
1121
|
+
throw new Error('LLM client is not configured — cannot proceed.')
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
console.log('Client configured:', client.isConfigured())
|
|
1125
|
+
// Output: Client configured: true
|
|
1126
|
+
|
|
1127
|
+
console.log('Proceeding to make completion requests...')
|
|
1128
|
+
// Output: Proceeding to make completion requests...
|
|
1129
|
+
} catch (error) {
|
|
1130
|
+
console.error('Configuration check failed:', error)
|
|
1131
|
+
}
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
### Related
|
|
1135
|
+
|
|
1136
|
+
<CardGroup cols={3}>
|
|
1137
|
+
<Card title="AnthropicClient.complete" icon="link" href="#anthropicclientcomplete">
|
|
1138
|
+
Uses
|
|
1139
|
+
</Card>
|
|
1140
|
+
<Card title="OpenAICompatibleClient.complete" icon="link" href="#openaicompatibleclientcomplete">
|
|
1141
|
+
Uses
|
|
1142
|
+
</Card>
|
|
1143
|
+
<Card title="AnthropicClient.complete" icon="link" href="#anthropicclientcomplete">
|
|
1144
|
+
Used by
|
|
1145
|
+
</Card>
|
|
1146
|
+
<Card title="OpenAICompatibleClient.complete" icon="link" href="#openaicompatibleclientcomplete">
|
|
1147
|
+
Used by
|
|
1148
|
+
</Card>
|
|
1149
|
+
<Card title="AnthropicClient" icon="link" href="#anthropicclient">
|
|
1150
|
+
Related
|
|
1151
|
+
</Card>
|
|
1152
|
+
<Card title="OpenAICompatibleClient" icon="link" href="#openaicompatibleclient">
|
|
1153
|
+
Related
|
|
1154
|
+
</Card>
|
|
1155
|
+
</CardGroup>
|
|
1156
|
+
|
|
1157
|
+
---
|
|
1158
|
+
|