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.
Files changed (120) hide show
  1. package/dist/auth/index.js +8 -1
  2. package/dist/autofix/index.d.ts +0 -4
  3. package/dist/autofix/index.js +0 -21
  4. package/dist/capture/browser.d.ts +11 -0
  5. package/dist/capture/browser.js +173 -0
  6. package/dist/capture/diff.d.ts +23 -0
  7. package/dist/capture/diff.js +52 -0
  8. package/dist/capture/index.d.ts +23 -0
  9. package/dist/capture/index.js +210 -0
  10. package/dist/capture/naming.d.ts +17 -0
  11. package/dist/capture/naming.js +45 -0
  12. package/dist/capture/parser.d.ts +15 -0
  13. package/dist/capture/parser.js +80 -0
  14. package/dist/capture/types.d.ts +57 -0
  15. package/dist/capture/types.js +1 -0
  16. package/dist/cli.js +4 -0
  17. package/dist/commands/autofix.js +136 -120
  18. package/dist/commands/cron.js +58 -47
  19. package/dist/commands/deploy.js +123 -102
  20. package/dist/commands/generate.js +88 -6
  21. package/dist/commands/heal.d.ts +10 -0
  22. package/dist/commands/heal.js +201 -0
  23. package/dist/commands/i18n.js +146 -111
  24. package/dist/commands/lint.js +50 -44
  25. package/dist/commands/llms-txt.js +59 -49
  26. package/dist/commands/login.js +61 -43
  27. package/dist/commands/mcp.js +6 -0
  28. package/dist/commands/monitor.js +13 -8
  29. package/dist/commands/qa.d.ts +2 -0
  30. package/dist/commands/qa.js +43 -0
  31. package/dist/commands/review-pr.js +108 -102
  32. package/dist/commands/sdk.js +128 -122
  33. package/dist/commands/security.js +86 -80
  34. package/dist/commands/test.js +91 -92
  35. package/dist/commands/version.js +104 -75
  36. package/dist/commands/watch.js +130 -114
  37. package/dist/config/types.js +2 -2
  38. package/dist/context-hub/index.d.ts +23 -0
  39. package/dist/context-hub/index.js +179 -0
  40. package/dist/context-hub/mappings.d.ts +8 -0
  41. package/dist/context-hub/mappings.js +55 -0
  42. package/dist/context-hub/types.d.ts +33 -0
  43. package/dist/context-hub/types.js +1 -0
  44. package/dist/generator/generator.js +39 -6
  45. package/dist/generator/types.d.ts +7 -0
  46. package/dist/generator/writer.d.ts +3 -1
  47. package/dist/generator/writer.js +24 -4
  48. package/dist/llm/anthropic-client.d.ts +1 -0
  49. package/dist/llm/anthropic-client.js +3 -1
  50. package/dist/llm/index.d.ts +6 -4
  51. package/dist/llm/index.js +76 -261
  52. package/dist/llm/openai-client.d.ts +1 -0
  53. package/dist/llm/openai-client.js +7 -2
  54. package/dist/qa/checks.d.ts +10 -0
  55. package/dist/qa/checks.js +492 -0
  56. package/dist/qa/fixes.d.ts +30 -0
  57. package/dist/qa/fixes.js +277 -0
  58. package/dist/qa/index.d.ts +29 -0
  59. package/dist/qa/index.js +187 -0
  60. package/dist/qa/types.d.ts +24 -0
  61. package/dist/qa/types.js +1 -0
  62. package/dist/scanner/csharp.d.ts +23 -0
  63. package/dist/scanner/csharp.js +421 -0
  64. package/dist/scanner/index.js +16 -2
  65. package/dist/scanner/java.d.ts +39 -0
  66. package/dist/scanner/java.js +318 -0
  67. package/dist/scanner/kotlin.d.ts +23 -0
  68. package/dist/scanner/kotlin.js +389 -0
  69. package/dist/scanner/php.d.ts +57 -0
  70. package/dist/scanner/php.js +351 -0
  71. package/dist/scanner/ruby.d.ts +36 -0
  72. package/dist/scanner/ruby.js +431 -0
  73. package/dist/scanner/swift.d.ts +25 -0
  74. package/dist/scanner/swift.js +392 -0
  75. package/dist/scanner/types.d.ts +1 -1
  76. package/dist/template/content/docs/_navigation.json +46 -0
  77. package/dist/template/content/docs/_sidebars.json +684 -0
  78. package/dist/template/content/docs/core.md +4544 -0
  79. package/dist/template/content/docs/index.mdx +89 -0
  80. package/dist/template/content/docs/integrations.md +1158 -0
  81. package/dist/template/content/docs/llms-full.md +403 -0
  82. package/dist/template/content/docs/llms.txt +4588 -0
  83. package/dist/template/content/docs/other.md +10379 -0
  84. package/dist/template/content/docs/tools.md +746 -0
  85. package/dist/template/content/docs/types.md +531 -0
  86. package/dist/template/docs.json +13 -11
  87. package/dist/template/mdx-components.tsx +27 -2
  88. package/dist/template/package.json +6 -0
  89. package/dist/template/public/search-index.json +1 -1
  90. package/dist/template/scripts/build-search-index.mjs +84 -6
  91. package/dist/template/src/app/api/chat/route.ts +83 -128
  92. package/dist/template/src/app/docs/[...slug]/page.tsx +75 -20
  93. package/dist/template/src/app/docs/llms-full.md +151 -4
  94. package/dist/template/src/app/docs/llms.txt +2464 -847
  95. package/dist/template/src/app/docs/page.mdx +48 -38
  96. package/dist/template/src/app/layout.tsx +3 -1
  97. package/dist/template/src/app/page.tsx +22 -8
  98. package/dist/template/src/components/ai-chat.tsx +73 -64
  99. package/dist/template/src/components/breadcrumbs.tsx +21 -23
  100. package/dist/template/src/components/copy-button.tsx +13 -9
  101. package/dist/template/src/components/copy-page-button.tsx +54 -0
  102. package/dist/template/src/components/docs-layout.tsx +37 -25
  103. package/dist/template/src/components/header.tsx +51 -10
  104. package/dist/template/src/components/mdx/card.tsx +17 -3
  105. package/dist/template/src/components/mdx/code-block.tsx +13 -9
  106. package/dist/template/src/components/mdx/code-group.tsx +13 -8
  107. package/dist/template/src/components/mdx/heading.tsx +15 -2
  108. package/dist/template/src/components/mdx/highlighted-code.tsx +13 -8
  109. package/dist/template/src/components/mdx/index.tsx +2 -0
  110. package/dist/template/src/components/mdx/mermaid.tsx +110 -0
  111. package/dist/template/src/components/mdx/screenshot.tsx +150 -0
  112. package/dist/template/src/components/scroll-to-hash.tsx +48 -0
  113. package/dist/template/src/components/sidebar.tsx +12 -18
  114. package/dist/template/src/components/table-of-contents.tsx +9 -0
  115. package/dist/template/src/lib/highlight.ts +3 -88
  116. package/dist/template/src/lib/navigation.ts +159 -0
  117. package/dist/template/src/styles/globals.css +17 -6
  118. package/dist/utils/validation.d.ts +0 -3
  119. package/dist/utils/validation.js +0 -26
  120. 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
+