skrypt-ai 0.7.0 → 0.8.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 +3 -3
- package/dist/cli.js +1 -1
- package/dist/commands/cron.js +0 -4
- package/dist/commands/generate/index.d.ts +3 -0
- package/dist/commands/generate/index.js +393 -0
- package/dist/commands/generate/scan.d.ts +41 -0
- package/dist/commands/generate/scan.js +256 -0
- package/dist/commands/generate/verify.d.ts +14 -0
- package/dist/commands/generate/verify.js +122 -0
- package/dist/commands/generate/write.d.ts +25 -0
- package/dist/commands/generate/write.js +120 -0
- package/dist/commands/import.js +4 -1
- package/dist/commands/llms-txt.js +6 -4
- package/dist/config/loader.d.ts +0 -1
- package/dist/config/loader.js +1 -1
- package/dist/generator/agents-md.d.ts +25 -0
- package/dist/generator/agents-md.js +122 -0
- package/dist/generator/index.d.ts +2 -0
- package/dist/generator/index.js +2 -0
- package/dist/generator/mdx-serializer.d.ts +11 -0
- package/dist/generator/mdx-serializer.js +135 -0
- package/dist/generator/organizer.d.ts +1 -16
- package/dist/generator/organizer.js +0 -38
- package/dist/generator/writer.js +5 -4
- package/dist/llm/proxy-client.d.ts +32 -0
- package/dist/llm/proxy-client.js +103 -0
- package/dist/scanner/csharp.d.ts +0 -4
- package/dist/scanner/csharp.js +9 -49
- package/dist/scanner/go.d.ts +0 -3
- package/dist/scanner/go.js +8 -35
- package/dist/scanner/java.d.ts +0 -4
- package/dist/scanner/java.js +9 -49
- package/dist/scanner/kotlin.d.ts +0 -3
- package/dist/scanner/kotlin.js +6 -33
- package/dist/scanner/php.d.ts +0 -10
- package/dist/scanner/php.js +11 -55
- package/dist/scanner/ruby.d.ts +0 -3
- package/dist/scanner/ruby.js +8 -38
- package/dist/scanner/rust.d.ts +0 -3
- package/dist/scanner/rust.js +10 -37
- package/dist/scanner/swift.d.ts +0 -3
- package/dist/scanner/swift.js +8 -35
- package/dist/scanner/utils.d.ts +41 -0
- package/dist/scanner/utils.js +97 -0
- package/dist/template/docs.json +5 -2
- package/dist/template/next.config.mjs +31 -0
- package/dist/template/package.json +5 -3
- package/dist/template/src/app/layout.tsx +13 -13
- package/dist/template/src/app/llms-full.md/route.ts +29 -0
- package/dist/template/src/app/llms.txt/route.ts +29 -0
- package/dist/template/src/app/md/[...slug]/route.ts +174 -0
- package/dist/template/src/app/reference/route.ts +22 -18
- package/dist/template/src/app/sitemap.ts +1 -1
- package/dist/template/src/components/ai-chat-impl.tsx +206 -0
- package/dist/template/src/components/ai-chat.tsx +20 -193
- package/dist/template/src/components/mdx/index.tsx +27 -4
- package/dist/template/src/lib/fonts.ts +135 -0
- package/dist/template/src/middleware.ts +101 -0
- package/dist/template/src/styles/globals.css +28 -20
- package/dist/utils/files.d.ts +0 -8
- package/dist/utils/files.js +0 -33
- package/package.json +1 -1
- package/dist/autofix/autofix.test.d.ts +0 -1
- package/dist/autofix/autofix.test.js +0 -487
- package/dist/commands/generate.d.ts +0 -9
- package/dist/commands/generate.js +0 -739
- package/dist/generator/generator.test.d.ts +0 -1
- package/dist/generator/generator.test.js +0 -259
- package/dist/generator/writer.test.d.ts +0 -1
- package/dist/generator/writer.test.js +0 -411
- package/dist/llm/llm.manual-test.d.ts +0 -1
- package/dist/llm/llm.manual-test.js +0 -112
- package/dist/llm/llm.mock-test.d.ts +0 -4
- package/dist/llm/llm.mock-test.js +0 -79
- package/dist/plugins/index.d.ts +0 -47
- package/dist/plugins/index.js +0 -181
- package/dist/scanner/content-type.test.d.ts +0 -1
- package/dist/scanner/content-type.test.js +0 -231
- package/dist/scanner/integration.test.d.ts +0 -4
- package/dist/scanner/integration.test.js +0 -180
- package/dist/scanner/scanner.test.d.ts +0 -1
- package/dist/scanner/scanner.test.js +0 -210
- package/dist/scanner/typescript.manual-test.d.ts +0 -1
- package/dist/scanner/typescript.manual-test.js +0 -112
- package/dist/template/src/app/docs/auth/page.mdx +0 -589
- package/dist/template/src/app/docs/autofix/page.mdx +0 -624
- package/dist/template/src/app/docs/cli/page.mdx +0 -217
- package/dist/template/src/app/docs/config/page.mdx +0 -428
- package/dist/template/src/app/docs/configuration/page.mdx +0 -86
- package/dist/template/src/app/docs/deployment/page.mdx +0 -112
- package/dist/template/src/app/docs/generator/generator.md +0 -504
- package/dist/template/src/app/docs/generator/organizer.md +0 -779
- package/dist/template/src/app/docs/generator/page.mdx +0 -613
- package/dist/template/src/app/docs/github/page.mdx +0 -502
- package/dist/template/src/app/docs/llm/anthropic-client.md +0 -549
- package/dist/template/src/app/docs/llm/index.md +0 -471
- package/dist/template/src/app/docs/llm/page.mdx +0 -428
- package/dist/template/src/app/docs/plugins/page.mdx +0 -1793
- package/dist/template/src/app/docs/pro/page.mdx +0 -121
- package/dist/template/src/app/docs/quickstart/page.mdx +0 -93
- package/dist/template/src/app/docs/scanner/content-type.md +0 -599
- package/dist/template/src/app/docs/scanner/index.md +0 -212
- package/dist/template/src/app/docs/scanner/page.mdx +0 -307
- package/dist/template/src/app/docs/scanner/python.md +0 -469
- package/dist/template/src/app/docs/scanner/python_parser.md +0 -1056
- package/dist/template/src/app/docs/scanner/rust.md +0 -325
- package/dist/template/src/app/docs/scanner/typescript.md +0 -201
- package/dist/template/src/app/icon.tsx +0 -29
- package/dist/utils/validation.d.ts +0 -1
- package/dist/utils/validation.js +0 -12
|
@@ -1,428 +0,0 @@
|
|
|
1
|
-
## Classes
|
|
2
|
-
|
|
3
|
-
### `OpenAICompatibleClient`
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
class OpenAICompatibleClient implements LLMClient
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
Use this to connect to any OpenAI-compatible LLM provider — including OpenAI, DeepSeek, Ollama, OpenRouter, and Google Gemini — through a single unified client interface.
|
|
10
|
-
|
|
11
|
-
`OpenAICompatibleClient` normalizes provider differences (base URLs, auth headers, retry logic) so you can swap providers without changing your application code.
|
|
12
|
-
|
|
13
|
-
## Constructor Config
|
|
14
|
-
|
|
15
|
-
| Name | Type | Required | Description |
|
|
16
|
-
|------|------|----------|-------------|
|
|
17
|
-
| `provider` | `LLMProvider` | ✅ | Provider identifier (e.g. `'openai'`, `'deepseek'`, `'ollama'`, `'openrouter'`, `'gemini'`) |
|
|
18
|
-
| `model` | `string` | ✅ | Model name to use (e.g. `'gpt-4o'`, `'deepseek-chat'`, `'llama3'`) |
|
|
19
|
-
| `apiKey` | `string` | ✅ | API key for the provider (use `'ollama'` or any placeholder for local providers) |
|
|
20
|
-
| `maxRetries` | `number` | ❌ | Number of retry attempts on failure. Defaults to `3` |
|
|
21
|
-
|
|
22
|
-
## Methods
|
|
23
|
-
|
|
24
|
-
### `complete(request: CompletionRequest): Promise<CompletionResponse>`
|
|
25
|
-
|
|
26
|
-
Sends a completion request to the configured provider.
|
|
27
|
-
|
|
28
|
-
| Name | Type | Required | Description |
|
|
29
|
-
|------|------|----------|-------------|
|
|
30
|
-
| `request.messages` | `Message[]` | ✅ | Array of `{ role: 'system' \| 'user' \| 'assistant', content: string }` |
|
|
31
|
-
| `request.temperature` | `number` | ❌ | Sampling temperature (0–2). Lower = more deterministic |
|
|
32
|
-
| `request.maxTokens` | `number` | ❌ | Maximum tokens in the response |
|
|
33
|
-
| `request.stream` | `boolean` | ❌ | Enable streaming responses |
|
|
34
|
-
|
|
35
|
-
#### Returns
|
|
36
|
-
|
|
37
|
-
A `CompletionResponse` object:
|
|
38
|
-
|
|
39
|
-
| Field | Type | Description |
|
|
40
|
-
|-------|------|-------------|
|
|
41
|
-
| `content` | `string` | The generated text response |
|
|
42
|
-
| `usage.promptTokens` | `number` | Tokens consumed by the input |
|
|
43
|
-
| `usage.completionTokens` | `number` | Tokens consumed by the output |
|
|
44
|
-
| `usage.totalTokens` | `number` | Total tokens used |
|
|
45
|
-
|
|
46
|
-
## Provider Quick Reference
|
|
47
|
-
|
|
48
|
-
| Provider | `provider` value | Notes |
|
|
49
|
-
|----------|-----------------|-------|
|
|
50
|
-
| OpenAI | `'openai'` | Requires OpenAI API key |
|
|
51
|
-
| DeepSeek | `'deepseek'` | Requires DeepSeek API key |
|
|
52
|
-
| Ollama | `'ollama'` | Local — no API key needed |
|
|
53
|
-
| OpenRouter | `'openrouter'` | Routes to many models |
|
|
54
|
-
| Google Gemini | `'gemini'` | Requires Google API key |
|
|
55
|
-
|
|
56
|
-
### Methods
|
|
57
|
-
|
|
58
|
-
#### `constructor`
|
|
59
|
-
|
|
60
|
-
```typescript
|
|
61
|
-
constructor(config: LLMClientConfig)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
Use this to create a unified LLM client that connects to any OpenAI-compatible API provider (OpenAI, Anthropic, Mistral, local models, etc.) with automatic retry logic and provider-specific configuration.
|
|
65
|
-
|
|
66
|
-
#### Parameters
|
|
67
|
-
|
|
68
|
-
| Name | Type | Required | Description |
|
|
69
|
-
|------|------|----------|-------------|
|
|
70
|
-
| `config` | `LLMClientConfig` | Yes | Configuration object for the LLM client |
|
|
71
|
-
| `config.provider` | `LLMProvider` | Yes | The LLM provider identifier (e.g., `'openai'`, `'mistral'`, `'anthropic'`) |
|
|
72
|
-
| `config.model` | `string` | Yes | The model name to use for completions (e.g., `'gpt-4o'`, `'mistral-large'`) |
|
|
73
|
-
| `config.baseUrl` | `string` | No | Override the default base URL for the provider's API endpoint |
|
|
74
|
-
| `config.maxRetries` | `number` | No | Number of retry attempts on failure. Defaults to `3` |
|
|
75
|
-
| `config.apiKey` | `string` | Yes | API key for authenticating with the provider |
|
|
76
|
-
|
|
77
|
-
#### Returns
|
|
78
|
-
|
|
79
|
-
An `OpenAICompatibleClient` instance with:
|
|
80
|
-
- `provider` — the configured provider identifier (publicly accessible)
|
|
81
|
-
- Access to completion methods using the specified model and retry settings
|
|
82
|
-
|
|
83
|
-
## Notes
|
|
84
|
-
|
|
85
|
-
- If `config.baseUrl` is omitted, the client automatically resolves the correct endpoint from a built-in provider URL map
|
|
86
|
-
- If `config.maxRetries` is omitted, it defaults to `3`
|
|
87
|
-
- The underlying HTTP client is an `OpenAI` SDK instance, making this compatible with any provider that follows the OpenAI API spec
|
|
88
|
-
|
|
89
|
-
**Example:**
|
|
90
|
-
|
|
91
|
-
```typescript example.ts
|
|
92
|
-
// ── Inline types (no external imports needed) ──────────────────────────────
|
|
93
|
-
|
|
94
|
-
type LLMProvider = 'openai' | 'mistral' | 'anthropic' | 'local'
|
|
95
|
-
|
|
96
|
-
interface LLMClientConfig {
|
|
97
|
-
provider: LLMProvider
|
|
98
|
-
model: string
|
|
99
|
-
apiKey: string
|
|
100
|
-
baseUrl?: string
|
|
101
|
-
maxRetries?: number
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
const PROVIDER_BASE_URLS: Record<LLMProvider, string> = {
|
|
105
|
-
openai: 'https://api.openai.com/v1',
|
|
106
|
-
mistral: 'https://api.mistral.ai/v1',
|
|
107
|
-
anthropic: 'https://api.anthropic.com/v1',
|
|
108
|
-
local: 'http://localhost:11434/v1',
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// ── Simulated OpenAICompatibleClient class ─────────────────────────────────
|
|
112
|
-
|
|
113
|
-
class OpenAICompatibleClient {
|
|
114
|
-
provider: LLMProvider
|
|
115
|
-
private model: string
|
|
116
|
-
private maxRetries: number
|
|
117
|
-
private baseUrl: string
|
|
118
|
-
private apiKey: string
|
|
119
|
-
|
|
120
|
-
constructor(config: LLMClientConfig) {
|
|
121
|
-
this.provider = config.provider
|
|
122
|
-
this.model = config.model
|
|
123
|
-
this.maxRetries = config.maxRetries ?? 3
|
|
124
|
-
this.baseUrl = config.baseUrl || PROVIDER_BASE_URLS[config.provider]
|
|
125
|
-
this.apiKey = config.apiKey
|
|
126
|
-
|
|
127
|
-
console.log(`[OpenAICompatibleClient] Initialized`)
|
|
128
|
-
console.log(` Provider : ${this.provider}`)
|
|
129
|
-
console.log(` Model : ${this.model}`)
|
|
130
|
-
console.log(` Base URL : ${this.baseUrl}`)
|
|
131
|
-
console.log(` MaxRetries: ${this.maxRetries}`)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
async complete(prompt: string): Promise<{ text: string; model: string }> {
|
|
135
|
-
console.log(`\n[OpenAICompatibleClient] Sending prompt to ${this.provider}...`)
|
|
136
|
-
// Simulated response — replace with real HTTP call in production
|
|
137
|
-
return {
|
|
138
|
-
text: `Echo from ${this.model}: "${prompt}"`,
|
|
139
|
-
model: this.model,
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// ── Usage examples ─────────────────────────────────────────────────────────
|
|
145
|
-
|
|
146
|
-
async function main() {
|
|
147
|
-
try {
|
|
148
|
-
// Example 1: Connect to OpenAI with default settings
|
|
149
|
-
const openaiClient = new OpenAICompatibleClient({
|
|
150
|
-
provider: 'openai',
|
|
151
|
-
model: 'gpt-4o',
|
|
152
|
-
apiKey: process.env.OPENAI_API_KEY || 'sk-your-openai-key-here',
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
const openaiResult = await openaiClient.complete('Summarize the water cycle.')
|
|
156
|
-
console.log('\nOpenAI result:', openaiResult)
|
|
157
|
-
// Output: { text: 'Echo from gpt-4o: "Summarize the water cycle."', model: 'gpt-4o' }
|
|
158
|
-
|
|
159
|
-
// Example 2: Connect to a local Ollama instance with custom base URL
|
|
160
|
-
const localClient = new OpenAICompatibleClient({
|
|
161
|
-
provider: 'local',
|
|
162
|
-
model: 'llama3',
|
|
163
|
-
apiKey: 'not-required-for-local',
|
|
164
|
-
baseUrl: 'http://localhost:11434/v1', // override default
|
|
165
|
-
maxRetries: 1, // fewer retries for local dev
|
|
166
|
-
})
|
|
167
|
-
|
|
168
|
-
const localResult = await localClient.complete('What is 2 + 2?')
|
|
169
|
-
console.log('\nLocal model result:', localResult)
|
|
170
|
-
// Output: { text: 'Echo from llama3: "What is 2 + 2?"', model: 'llama3' }
|
|
171
|
-
|
|
172
|
-
// Example 3: Connect to Mistral with default retry count (3)
|
|
173
|
-
const mistralClient = new OpenAICompatibleClient({
|
|
174
|
-
provider: 'mistral',
|
|
175
|
-
model: 'mistral-large-latest',
|
|
176
|
-
apiKey: process.env.MISTRAL_API_KEY || 'your-mistral-key-here',
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
console.log(`\nMistral provider: ${mistralClient.provider}`)
|
|
180
|
-
// Output: Mistral provider: mistral
|
|
181
|
-
|
|
182
|
-
} catch (error) {
|
|
183
|
-
console.error('Failed to initialize or call LLM client:', error)
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
main()
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
#### `isConfigured`
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
isConfigured(): boolean
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
Use this to verify that an `OpenAICompatibleClient` instance is ready to make API calls before attempting completions.
|
|
197
|
-
|
|
198
|
-
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 follow a consistent "is configured?" pattern across multiple LLM client types.
|
|
199
|
-
|
|
200
|
-
#### Returns
|
|
201
|
-
|
|
202
|
-
| Condition | Value |
|
|
203
|
-
|-----------|-------|
|
|
204
|
-
| Always | `true` — configuration validation is delegated to the OpenAI SDK |
|
|
205
|
-
|
|
206
|
-
> **Note:** A `true` return does **not** guarantee the API key is valid or that the endpoint is reachable. It only confirms the client object was constructed. Actual credential errors surface when calling `complete()`.
|
|
207
|
-
|
|
208
|
-
**Example:**
|
|
209
|
-
|
|
210
|
-
```typescript example.ts
|
|
211
|
-
// Inline types to simulate the OpenAICompatibleClient behavior
|
|
212
|
-
type LLMProvider = 'openai' | 'azure' | 'groq' | 'custom'
|
|
213
|
-
|
|
214
|
-
interface LLMClientConfig {
|
|
215
|
-
apiKey: string
|
|
216
|
-
provider: LLMProvider
|
|
217
|
-
model?: string
|
|
218
|
-
baseURL?: string
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Simulated OpenAICompatibleClient
|
|
222
|
-
class OpenAICompatibleClient {
|
|
223
|
-
private apiKey: string
|
|
224
|
-
private provider: LLMProvider
|
|
225
|
-
private model: string
|
|
226
|
-
|
|
227
|
-
constructor(config: LLMClientConfig) {
|
|
228
|
-
this.apiKey = config.apiKey
|
|
229
|
-
this.provider = config.provider
|
|
230
|
-
this.model = config.model || 'gpt-4o'
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
// OpenAI SDK handles validation — always returns true
|
|
234
|
-
isConfigured(): boolean {
|
|
235
|
-
return true
|
|
236
|
-
}
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
// --- Usage Example ---
|
|
240
|
-
|
|
241
|
-
const client = new OpenAICompatibleClient({
|
|
242
|
-
apiKey: process.env.OPENAI_API_KEY || 'sk-proj-abc123xyz',
|
|
243
|
-
provider: 'openai',
|
|
244
|
-
model: 'gpt-4o',
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
// Guard clause pattern: check before proceeding
|
|
248
|
-
function runCompletion(client: OpenAICompatibleClient, prompt: string) {
|
|
249
|
-
if (!client.isConfigured()) {
|
|
250
|
-
console.error('Client is not configured. Aborting.')
|
|
251
|
-
return
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
console.log(`Client is configured: ${client.isConfigured()}`)
|
|
255
|
-
// Output: Client is configured: true
|
|
256
|
-
|
|
257
|
-
console.log(`Proceeding with prompt: "${prompt}"`)
|
|
258
|
-
// In real usage, you would call: await client.complete({ prompt })
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
runCompletion(client, 'Summarize the latest AI research trends.')
|
|
262
|
-
|
|
263
|
-
// Multi-client health check pattern
|
|
264
|
-
const clients = [
|
|
265
|
-
new OpenAICompatibleClient({ apiKey: 'sk-groq-key-001', provider: 'groq', model: 'llama3-8b-8192' }),
|
|
266
|
-
new OpenAICompatibleClient({ apiKey: 'sk-azure-key-002', provider: 'azure', model: 'gpt-4' }),
|
|
267
|
-
]
|
|
268
|
-
|
|
269
|
-
const allReady = clients.every(c => c.isConfigured())
|
|
270
|
-
console.log(`All clients ready: ${allReady}`)
|
|
271
|
-
// Output: All clients ready: true
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
#### `complete`
|
|
275
|
-
|
|
276
|
-
```typescript
|
|
277
|
-
async complete(request: CompletionRequest): Promise<CompletionResponse>
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
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.
|
|
281
|
-
|
|
282
|
-
#### Parameters
|
|
283
|
-
|
|
284
|
-
| Name | Type | Required | Description |
|
|
285
|
-
|------|------|----------|-------------|
|
|
286
|
-
| `request` | `CompletionRequest` | Yes | The completion request object containing messages, model, and generation settings |
|
|
287
|
-
| `request.messages` | `Array<{role: string, content: string}>` | Yes | Conversation history as an array of role/content message objects |
|
|
288
|
-
| `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 |
|
|
289
|
-
| `request.temperature` | `number` | No | Sampling temperature between 0–2. Lower = more deterministic, higher = more creative |
|
|
290
|
-
| `request.maxTokens` | `number` | No | Maximum number of tokens to generate in the response |
|
|
291
|
-
| `request.systemPrompt` | `string` | No | System-level instruction prepended to the conversation |
|
|
292
|
-
|
|
293
|
-
#### Returns
|
|
294
|
-
|
|
295
|
-
Returns a `Promise<CompletionResponse>` that resolves to:
|
|
296
|
-
|
|
297
|
-
| Field | Type | Description |
|
|
298
|
-
|-------|------|-------------|
|
|
299
|
-
| `content` | `string` | The generated text from the model |
|
|
300
|
-
| `model` | `string` | The model that was actually used to generate the response |
|
|
301
|
-
| `usage.promptTokens` | `number` | Number of tokens consumed by the input messages |
|
|
302
|
-
| `usage.completionTokens` | `number` | Number of tokens in the generated response |
|
|
303
|
-
| `usage.totalTokens` | `number` | Total tokens used (prompt + completion) |
|
|
304
|
-
|
|
305
|
-
Throws an error if the API request fails, the model is unavailable, or the API key is invalid.
|
|
306
|
-
|
|
307
|
-
**Example:**
|
|
308
|
-
|
|
309
|
-
```typescript example.ts
|
|
310
|
-
// ── Inline types (no external imports needed) ──────────────────────────────
|
|
311
|
-
|
|
312
|
-
type Message = { role: 'system' | 'user' | 'assistant'; content: string }
|
|
313
|
-
|
|
314
|
-
type CompletionRequest = {
|
|
315
|
-
messages: Message[]
|
|
316
|
-
model?: string
|
|
317
|
-
temperature?: number
|
|
318
|
-
maxTokens?: number
|
|
319
|
-
systemPrompt?: string
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
type CompletionResponse = {
|
|
323
|
-
content: string
|
|
324
|
-
model: string
|
|
325
|
-
usage: {
|
|
326
|
-
promptTokens: number
|
|
327
|
-
completionTokens: number
|
|
328
|
-
totalTokens: number
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// ── Minimal OpenAI-compatible client (self-contained simulation) ───────────
|
|
333
|
-
|
|
334
|
-
class OpenAICompatibleClient {
|
|
335
|
-
private apiKey: string
|
|
336
|
-
private baseURL: string
|
|
337
|
-
private model: string
|
|
338
|
-
|
|
339
|
-
constructor(config: { apiKey: string; baseURL?: string; model?: string }) {
|
|
340
|
-
this.apiKey = config.apiKey
|
|
341
|
-
this.baseURL = config.baseURL || 'https://api.openai.com/v1'
|
|
342
|
-
this.model = config.model || 'gpt-4o'
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
async complete(request: CompletionRequest): Promise<CompletionResponse> {
|
|
346
|
-
const model = request.model || this.model
|
|
347
|
-
|
|
348
|
-
const messages: Message[] = []
|
|
349
|
-
|
|
350
|
-
if (request.systemPrompt) {
|
|
351
|
-
messages.push({ role: 'system', content: request.systemPrompt })
|
|
352
|
-
}
|
|
353
|
-
messages.push(...request.messages)
|
|
354
|
-
|
|
355
|
-
const body = {
|
|
356
|
-
model,
|
|
357
|
-
messages,
|
|
358
|
-
...(request.temperature !== undefined && { temperature: request.temperature }),
|
|
359
|
-
...(request.maxTokens !== undefined && { max_tokens: request.maxTokens }),
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
363
|
-
method: 'POST',
|
|
364
|
-
headers: {
|
|
365
|
-
'Content-Type': 'application/json',
|
|
366
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
367
|
-
},
|
|
368
|
-
body: JSON.stringify(body),
|
|
369
|
-
})
|
|
370
|
-
|
|
371
|
-
if (!response.ok) {
|
|
372
|
-
const error = await response.text()
|
|
373
|
-
throw new Error(`API request failed (${response.status}): ${error}`)
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
const data = await response.json()
|
|
377
|
-
const choice = data.choices[0]
|
|
378
|
-
|
|
379
|
-
return {
|
|
380
|
-
content: choice.message.content ?? '',
|
|
381
|
-
model: data.model,
|
|
382
|
-
usage: {
|
|
383
|
-
promptTokens: data.usage.prompt_tokens,
|
|
384
|
-
completionTokens: data.usage.completion_tokens,
|
|
385
|
-
totalTokens: data.usage.total_tokens,
|
|
386
|
-
},
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// ── Usage example ──────────────────────────────────────────────────────────
|
|
392
|
-
|
|
393
|
-
const client = new OpenAICompatibleClient({
|
|
394
|
-
apiKey: process.env.OPENAI_API_KEY || 'sk-your-api-key-here',
|
|
395
|
-
baseURL: 'https://api.openai.com/v1',
|
|
396
|
-
model: 'gpt-4o-mini',
|
|
397
|
-
})
|
|
398
|
-
|
|
399
|
-
async function main() {
|
|
400
|
-
try {
|
|
401
|
-
const response = await client.complete({
|
|
402
|
-
systemPrompt: 'You are a concise assistant. Reply in one sentence.',
|
|
403
|
-
messages: [
|
|
404
|
-
{ role: 'user', content: 'What is the capital of Japan?' },
|
|
405
|
-
],
|
|
406
|
-
temperature: 0.3,
|
|
407
|
-
maxTokens: 60,
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
console.log('Generated text:', response.content)
|
|
411
|
-
// Output: "The capital of Japan is Tokyo."
|
|
412
|
-
|
|
413
|
-
console.log('Model used:', response.model)
|
|
414
|
-
// Output: "gpt-4o-mini"
|
|
415
|
-
|
|
416
|
-
console.log('Token usage:', response.usage)
|
|
417
|
-
// Output: { promptTokens: 28, completionTokens: 10, totalTokens: 38 }
|
|
418
|
-
|
|
419
|
-
} catch (error) {
|
|
420
|
-
if (error instanceof Error) {
|
|
421
|
-
console.error('Completion failed:', error.message)
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
main()
|
|
427
|
-
```
|
|
428
|
-
|