@redonvn/event-ws-cliproxyapi-sdk 1.0.3 → 1.0.5
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/README.md +258 -428
- package/dist/claude/client.d.ts +1 -1
- package/dist/claude/index.d.ts +1 -1
- package/dist/client.d.ts +19 -0
- package/dist/client.js +96 -0
- package/dist/cliproxy/client.d.ts +1 -1
- package/dist/cliproxy/index.d.ts +1 -1
- package/dist/codec.d.ts +8 -0
- package/dist/codec.js +79 -0
- package/dist/errors/index.d.ts +13 -0
- package/dist/errors/index.js +26 -0
- package/dist/gemini/client.d.ts +1 -1
- package/dist/gemini/index.d.ts +1 -1
- package/dist/http/client.d.ts +260 -0
- package/dist/http/client.js +591 -0
- package/dist/http/index.d.ts +2 -0
- package/dist/http/index.js +2 -0
- package/dist/http/types.d.ts +783 -0
- package/dist/http/types.js +1 -0
- package/dist/http-client.d.ts +259 -0
- package/dist/http-client.js +557 -0
- package/dist/http-types.d.ts +677 -0
- package/dist/http-types.js +1 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +3 -3
- package/dist/management/client.d.ts +1 -1
- package/dist/management/client.js +1 -1
- package/dist/management/index.d.ts +1 -1
- package/dist/openai/client.d.ts +1 -1
- package/dist/openai/index.d.ts +1 -1
- package/dist/shared/errors.d.ts +4 -4
- package/dist/shared/errors.js +15 -9
- package/dist/shared/http.d.ts +3 -1
- package/dist/shared/http.js +18 -12
- package/dist/shared/index.d.ts +1 -1
- package/dist/shared/index.js +1 -1
- package/dist/shared/types.d.ts +9 -8
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +2 -0
- package/dist/types.d.ts +101 -0
- package/dist/types.js +1 -0
- package/dist/utils/index.d.ts +0 -0
- package/dist/utils/index.js +2 -0
- package/dist/ws/client.d.ts +1 -0
- package/dist/ws/client.js +22 -14
- package/dist/ws/codec.js +1 -1
- package/dist/ws/index.d.ts +1 -1
- package/dist/ws/index.js +1 -1
- package/dist/ws/types.d.ts +7 -4
- package/package.json +23 -23
package/README.md
CHANGED
|
@@ -1,428 +1,258 @@
|
|
|
1
|
-
# event-ws-
|
|
2
|
-
|
|
3
|
-
TypeScript SDK for CLIProxyAPI
|
|
4
|
-
-
|
|
5
|
-
-
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- `
|
|
66
|
-
- `
|
|
67
|
-
- `
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
- `
|
|
71
|
-
- `
|
|
72
|
-
- `
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
- `
|
|
78
|
-
- `
|
|
79
|
-
- `
|
|
80
|
-
- `
|
|
81
|
-
- `
|
|
82
|
-
- `
|
|
83
|
-
- `
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
- `
|
|
87
|
-
-
|
|
88
|
-
- `
|
|
89
|
-
- `
|
|
90
|
-
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
- `GET /
|
|
98
|
-
- `
|
|
99
|
-
- `
|
|
100
|
-
- `
|
|
101
|
-
- `
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
- `GET /
|
|
120
|
-
- `
|
|
121
|
-
- `
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
- `
|
|
127
|
-
- `
|
|
128
|
-
- `GET /
|
|
129
|
-
- `
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
- `
|
|
135
|
-
- `GET /
|
|
136
|
-
- `
|
|
137
|
-
-
|
|
138
|
-
- `
|
|
139
|
-
- `GET /
|
|
140
|
-
- `
|
|
141
|
-
- `
|
|
142
|
-
- `
|
|
143
|
-
-
|
|
144
|
-
- `
|
|
145
|
-
- `
|
|
146
|
-
- `
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
-
|
|
152
|
-
-
|
|
153
|
-
-
|
|
154
|
-
- `
|
|
155
|
-
-
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
- `
|
|
161
|
-
- `
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
-
|
|
167
|
-
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
- `
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
const provider = new CliproxyWSProvider({
|
|
260
|
-
baseUrl: 'http://127.0.0.1:8317',
|
|
261
|
-
accessKey: 'andev'
|
|
262
|
-
});
|
|
263
|
-
|
|
264
|
-
await provider.connect({
|
|
265
|
-
onEvent: (ev) => {
|
|
266
|
-
if (ev.type === 'ws:open') console.log('ws open');
|
|
267
|
-
if (ev.type === 'ws:close') console.log('ws close', ev.code, ev.reason);
|
|
268
|
-
},
|
|
269
|
-
onRequest: async (req, ctx) => {
|
|
270
|
-
if (req.url === '/v1/cliproxy/chat') {
|
|
271
|
-
ctx.streamStart(200, { 'Content-Type': 'text/plain' });
|
|
272
|
-
ctx.streamChunk('hello ');
|
|
273
|
-
ctx.streamChunk('world');
|
|
274
|
-
ctx.streamEnd();
|
|
275
|
-
return;
|
|
276
|
-
}
|
|
277
|
-
ctx.respond({ status: 404, body: 'not found' });
|
|
278
|
-
}
|
|
279
|
-
});
|
|
280
|
-
|
|
281
|
-
provider.close();
|
|
282
|
-
```
|
|
283
|
-
|
|
284
|
-
## Usage (HTTP Client)
|
|
285
|
-
|
|
286
|
-
```ts
|
|
287
|
-
import { CliproxyClient, OpenAIClient, ClaudeClient, GeminiClient, ManagementClient } from 'event-ws-cliproxyapi-sdk';
|
|
288
|
-
|
|
289
|
-
const cliproxy = new CliproxyClient({
|
|
290
|
-
baseUrl: 'http://127.0.0.1:8317',
|
|
291
|
-
accessKey: 'your-access-key',
|
|
292
|
-
managementKey: 'your-management-key'
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
// Public: list auths
|
|
296
|
-
const auths = await cliproxy.getCliproxyAuths();
|
|
297
|
-
|
|
298
|
-
// OpenAI-compatible chat
|
|
299
|
-
const openai = new OpenAIClient({ baseUrl: 'http://127.0.0.1:8317', accessKey: 'your-access-key' });
|
|
300
|
-
await openai.postChatCompletions({
|
|
301
|
-
model: 'gpt-4o-mini',
|
|
302
|
-
messages: [
|
|
303
|
-
{ role: 'user', content: [{ type: 'text', text: 'hello' }] }
|
|
304
|
-
]
|
|
305
|
-
});
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
## Response Types
|
|
309
|
-
|
|
310
|
-
OpenAI-compatible
|
|
311
|
-
- `OpenAIChatCompletionResponse` (non-stream)
|
|
312
|
-
- `OpenAIChatCompletionChunk` (stream)
|
|
313
|
-
- `OpenAICompletionResponse` (non-stream)
|
|
314
|
-
- `OpenAICompletionChunk` (stream)
|
|
315
|
-
- `OpenAIResponsesResponse` (non-stream)
|
|
316
|
-
- `OpenAIResponsesChunk` (stream)
|
|
317
|
-
|
|
318
|
-
Claude-compatible
|
|
319
|
-
- `ClaudeMessagesResponse` (non-stream)
|
|
320
|
-
- `ClaudeStreamEvent` (stream)
|
|
321
|
-
|
|
322
|
-
Gemini-compatible
|
|
323
|
-
- `GeminiGenerateContentResponse` (non-stream)
|
|
324
|
-
- `GeminiStreamChunk` (stream)
|
|
325
|
-
|
|
326
|
-
Errors
|
|
327
|
-
- `OpenAIErrorResponse` (OpenAI-style `{ error: { message, type, code? } }`)
|
|
328
|
-
- `ErrorResponse` (management `{ error: string, message?: string }`)
|
|
329
|
-
- `StatusResponse` (status polling `{ status: "ok" | "error" | "wait", error?: string }`)
|
|
330
|
-
- `APIError` (thrown by service clients on non-2xx)
|
|
331
|
-
|
|
332
|
-
## Response Examples (OK / Failed)
|
|
333
|
-
|
|
334
|
-
OpenAI Chat Completions (OK, non-stream):
|
|
335
|
-
```json
|
|
336
|
-
{
|
|
337
|
-
"id": "chatcmpl_123",
|
|
338
|
-
"object": "chat.completion",
|
|
339
|
-
"created": 1730000000,
|
|
340
|
-
"model": "gpt-4o-mini",
|
|
341
|
-
"choices": [
|
|
342
|
-
{
|
|
343
|
-
"index": 0,
|
|
344
|
-
"message": { "role": "assistant", "content": "hello" },
|
|
345
|
-
"finish_reason": "stop"
|
|
346
|
-
}
|
|
347
|
-
],
|
|
348
|
-
"usage": { "total_tokens": 10 }
|
|
349
|
-
}
|
|
350
|
-
```
|
|
351
|
-
|
|
352
|
-
OpenAI Chat Completions (Failed):
|
|
353
|
-
```json
|
|
354
|
-
{
|
|
355
|
-
"error": {
|
|
356
|
-
"message": "Invalid request: Missing model",
|
|
357
|
-
"type": "invalid_request_error",
|
|
358
|
-
"code": "invalid_request_error"
|
|
359
|
-
}
|
|
360
|
-
}
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
Claude Messages (OK, non-stream):
|
|
364
|
-
```json
|
|
365
|
-
{
|
|
366
|
-
"id": "msg_123",
|
|
367
|
-
"type": "message",
|
|
368
|
-
"role": "assistant",
|
|
369
|
-
"model": "claude-3-5-sonnet",
|
|
370
|
-
"content": [{ "type": "text", "text": "hello" }],
|
|
371
|
-
"stop_reason": "end_turn",
|
|
372
|
-
"usage": { "input_tokens": 5, "output_tokens": 5 }
|
|
373
|
-
}
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
Claude Messages (Failed):
|
|
377
|
-
```json
|
|
378
|
-
{ "error": "invalid request" }
|
|
379
|
-
```
|
|
380
|
-
|
|
381
|
-
Gemini GenerateContent (OK, non-stream):
|
|
382
|
-
```json
|
|
383
|
-
{
|
|
384
|
-
"candidates": [
|
|
385
|
-
{
|
|
386
|
-
"content": {
|
|
387
|
-
"role": "model",
|
|
388
|
-
"parts": [{ "text": "hello" }]
|
|
389
|
-
},
|
|
390
|
-
"finishReason": "STOP",
|
|
391
|
-
"index": 0
|
|
392
|
-
}
|
|
393
|
-
]
|
|
394
|
-
}
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
Gemini GenerateContent (Failed):
|
|
398
|
-
```json
|
|
399
|
-
{ "error": "invalid request" }
|
|
400
|
-
```
|
|
401
|
-
|
|
402
|
-
Management (Failed):
|
|
403
|
-
```json
|
|
404
|
-
{ "error": "invalid management key" }
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
## Image + Text in One Message
|
|
408
|
-
|
|
409
|
-
```ts
|
|
410
|
-
await openai.postChatCompletions({
|
|
411
|
-
model: 'gpt-4o-mini',
|
|
412
|
-
messages: [
|
|
413
|
-
{
|
|
414
|
-
role: 'user',
|
|
415
|
-
content: [
|
|
416
|
-
{ type: 'text', text: 'describe this image' },
|
|
417
|
-
{ type: 'image_url', image_url: { url: 'https://example.com/cat.jpg' } }
|
|
418
|
-
]
|
|
419
|
-
}
|
|
420
|
-
]
|
|
421
|
-
});
|
|
422
|
-
```
|
|
423
|
-
|
|
424
|
-
## Notes
|
|
425
|
-
|
|
426
|
-
- For WS relay, if `ws-auth: true`, pass `accessKey` as `Authorization: Bearer ...`.
|
|
427
|
-
- Management APIs require `managementKey` (or local password for `/keep-alive` if enabled).
|
|
428
|
-
- HTTP client returns `Response` for streaming endpoints; parse SSE or chunks based on your client.
|
|
1
|
+
# @redonvn/event-ws-cliproxyapi-sdk
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for CLIProxyAPI with two main capabilities:
|
|
4
|
+
- HTTP clients for OpenAI/Claude/Gemini-compatible and management endpoints
|
|
5
|
+
- Provider-side WebSocket relay for `/v1/ws`
|
|
6
|
+
|
|
7
|
+
## Why This SDK
|
|
8
|
+
|
|
9
|
+
- Strong TypeScript types for request/response payloads
|
|
10
|
+
- Unified auth model (`accessKey`, `managementKey`, `localPassword`)
|
|
11
|
+
- Shared error model (`APIError`) across all HTTP clients
|
|
12
|
+
- Explicit client modules by domain: `OpenAIClient`, `ClaudeClient`, `GeminiClient`, `CliproxyClient`, `ManagementClient`, `CliproxyWSProvider`
|
|
13
|
+
|
|
14
|
+
## Install
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm i @redonvn/event-ws-cliproxyapi-sdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Requirements
|
|
21
|
+
|
|
22
|
+
- Node.js with `fetch` support (Node 18+ recommended)
|
|
23
|
+
- TypeScript 5+ (if consuming types in TS)
|
|
24
|
+
|
|
25
|
+
If your runtime does not provide `fetch`, pass `options.fetch` when creating clients.
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
import {
|
|
31
|
+
CliproxyClient,
|
|
32
|
+
OpenAIClient,
|
|
33
|
+
ClaudeClient,
|
|
34
|
+
GeminiClient,
|
|
35
|
+
ManagementClient,
|
|
36
|
+
APIError
|
|
37
|
+
} from '@redonvn/event-ws-cliproxyapi-sdk';
|
|
38
|
+
|
|
39
|
+
const baseUrl = 'http://127.0.0.1:8317';
|
|
40
|
+
|
|
41
|
+
const cliproxy = new CliproxyClient({
|
|
42
|
+
baseUrl,
|
|
43
|
+
accessKey: process.env.ACCESS_KEY,
|
|
44
|
+
managementKey: process.env.MANAGEMENT_KEY,
|
|
45
|
+
localPassword: process.env.LOCAL_PASSWORD
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const openai = new OpenAIClient({ baseUrl, accessKey: process.env.ACCESS_KEY });
|
|
49
|
+
const claude = new ClaudeClient({ baseUrl, accessKey: process.env.ACCESS_KEY });
|
|
50
|
+
const gemini = new GeminiClient({ baseUrl, accessKey: process.env.ACCESS_KEY });
|
|
51
|
+
const management = new ManagementClient({ baseUrl, managementKey: process.env.MANAGEMENT_KEY });
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const models = await openai.getModels();
|
|
55
|
+
console.log(models.data.length);
|
|
56
|
+
} catch (err) {
|
|
57
|
+
if (err instanceof APIError) {
|
|
58
|
+
console.error(err.status, err.message, err.payload);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Auth Model
|
|
64
|
+
|
|
65
|
+
- `accessKey`: used for access-protected public inference endpoints
|
|
66
|
+
- `managementKey`: used for `/v0/management/*`
|
|
67
|
+
- `localPassword`: used for local-protected endpoints such as `/keep-alive`
|
|
68
|
+
|
|
69
|
+
You can update keys at runtime:
|
|
70
|
+
- `setAccessKey(key?)`
|
|
71
|
+
- `setManagementKey(key?)`
|
|
72
|
+
- `setLocalPassword(value?)`
|
|
73
|
+
|
|
74
|
+
## Exported Modules
|
|
75
|
+
|
|
76
|
+
From package root (`src/index.ts`):
|
|
77
|
+
- `openai/*`
|
|
78
|
+
- `claude/*`
|
|
79
|
+
- `gemini/*`
|
|
80
|
+
- `cliproxy/*`
|
|
81
|
+
- `management/*`
|
|
82
|
+
- `ws/*`
|
|
83
|
+
- `shared/*`
|
|
84
|
+
|
|
85
|
+
Core exports:
|
|
86
|
+
- Clients: `OpenAIClient`, `ClaudeClient`, `GeminiClient`, `CliproxyClient`, `ManagementClient`
|
|
87
|
+
- WS relay: `CliproxyWSProvider`, `CliproxyWSClient`
|
|
88
|
+
- WS codec helpers: `decodeRequest`, `encodeResponse`, `decodeResponse`, `encodeChunk`, `decodeChunk`, `encodeError`, `decodeError`
|
|
89
|
+
- Errors: `APIError`, `isOpenAIError`, `isStatusError`, `isManagementError`
|
|
90
|
+
- Full payload types from `shared/types`
|
|
91
|
+
|
|
92
|
+
## HTTP Clients
|
|
93
|
+
|
|
94
|
+
### `OpenAIClient`
|
|
95
|
+
|
|
96
|
+
Methods:
|
|
97
|
+
- `getModels()` -> `GET /v1/models`
|
|
98
|
+
- `postChatCompletions(body)` -> `POST /v1/chat/completions`
|
|
99
|
+
- `postCompletions(body)` -> `POST /v1/completions`
|
|
100
|
+
- `postResponses(body)` -> `POST /v1/responses`
|
|
101
|
+
- `postResponsesCompact(body)` -> `POST /v1/responses/compact`
|
|
102
|
+
|
|
103
|
+
Example:
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
const res = await openai.postChatCompletions({
|
|
107
|
+
model: 'gpt-4o-mini',
|
|
108
|
+
messages: [{ role: 'user', content: 'hello' }],
|
|
109
|
+
stream: false
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const json = await res.json();
|
|
113
|
+
console.log(json);
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### `ClaudeClient`
|
|
117
|
+
|
|
118
|
+
Methods:
|
|
119
|
+
- `getModels()` -> `GET /v1/models` (adds `User-Agent: claude-cli`)
|
|
120
|
+
- `postMessages(body)` -> `POST /v1/messages`
|
|
121
|
+
- `postMessagesCountTokens(body)` -> `POST /v1/messages/count_tokens`
|
|
122
|
+
|
|
123
|
+
### `GeminiClient`
|
|
124
|
+
|
|
125
|
+
Methods:
|
|
126
|
+
- `getModels()` -> `GET /v1beta/models`
|
|
127
|
+
- `postModelsAction(action, body)` -> `POST /v1beta/models/{action}`
|
|
128
|
+
- `getModelsAction(action, query?)` -> `GET /v1beta/models/{action}`
|
|
129
|
+
- `postV1Internal(method, body)` -> `POST /v1internal:{method}`
|
|
130
|
+
|
|
131
|
+
### `CliproxyClient`
|
|
132
|
+
|
|
133
|
+
Methods:
|
|
134
|
+
- `getRoot()` -> `GET /`
|
|
135
|
+
- `getManagementHtml()` -> `GET /management.html`
|
|
136
|
+
- `keepAlive()` -> `GET /keep-alive`
|
|
137
|
+
- OAuth callbacks:
|
|
138
|
+
- `anthropicCallback(query)` -> `GET /anthropic/callback`
|
|
139
|
+
- `codexCallback(query)` -> `GET /codex/callback`
|
|
140
|
+
- `googleCallback(query)` -> `GET /google/callback`
|
|
141
|
+
- `iflowCallback(query)` -> `GET /iflow/callback`
|
|
142
|
+
- `antigravityCallback(query)` -> `GET /antigravity/callback`
|
|
143
|
+
- CLIProxy endpoints:
|
|
144
|
+
- `getCliproxyAuths(query?)` -> `GET /v1/cliproxy/auths`
|
|
145
|
+
- `getCliproxyModels(query?)` -> `GET /v1/cliproxy/models`
|
|
146
|
+
- `postCliproxyChat(body)` -> `POST /v1/cliproxy/chat`
|
|
147
|
+
|
|
148
|
+
### `ManagementClient`
|
|
149
|
+
|
|
150
|
+
Covers management APIs under `/v0/management/*`, including:
|
|
151
|
+
- usage import/export
|
|
152
|
+
- runtime config and YAML config
|
|
153
|
+
- logging and debug flags
|
|
154
|
+
- key/config CRUD (`api-keys`, `claude-api-key`, `gemini-api-key`, `codex-api-key`, `vertex-api-key`, `openai-compatibility`)
|
|
155
|
+
- routing/retry/quota flags
|
|
156
|
+
- auth files and model definitions
|
|
157
|
+
- OAuth helper flows
|
|
158
|
+
|
|
159
|
+
Also includes:
|
|
160
|
+
- `getDesktopKeys()` -> `GET /desktop/keys`
|
|
161
|
+
- `getManagementApiKeys()` convenience fallback helper
|
|
162
|
+
|
|
163
|
+
## Streaming Responses
|
|
164
|
+
|
|
165
|
+
Many inference methods return raw `Response` for stream compatibility.
|
|
166
|
+
- For SSE/event-stream, read `response.body`
|
|
167
|
+
- For non-stream mode, parse with `await response.json()` or `await response.text()`
|
|
168
|
+
|
|
169
|
+
## WebSocket Relay (Provider Side)
|
|
170
|
+
|
|
171
|
+
Use `CliproxyWSProvider` to handle server forwarded requests over `/v1/ws`.
|
|
172
|
+
|
|
173
|
+
```ts
|
|
174
|
+
import { CliproxyWSProvider } from '@redonvn/event-ws-cliproxyapi-sdk';
|
|
175
|
+
|
|
176
|
+
const provider = new CliproxyWSProvider({
|
|
177
|
+
baseUrl: 'http://127.0.0.1:8317',
|
|
178
|
+
accessKey: process.env.ACCESS_KEY
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
await provider.connect({
|
|
182
|
+
onEvent: (ev) => {
|
|
183
|
+
if (ev.type === 'ws:open') console.log('connected');
|
|
184
|
+
if (ev.type === 'ws:close') console.log('closed', ev.code, ev.reason);
|
|
185
|
+
if (ev.type === 'error') console.error(ev.error);
|
|
186
|
+
},
|
|
187
|
+
onRequest: async (req, ctx) => {
|
|
188
|
+
if (req.url === '/health') {
|
|
189
|
+
ctx.respond({ status: 200, body: 'ok' });
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
ctx.streamStart(200, { 'Content-Type': 'text/plain' });
|
|
194
|
+
ctx.streamChunk('hello ');
|
|
195
|
+
ctx.streamChunk('world');
|
|
196
|
+
ctx.streamEnd();
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
provider.close();
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
WS message/event types are exported from `ws/types`.
|
|
204
|
+
|
|
205
|
+
## Error Handling
|
|
206
|
+
|
|
207
|
+
All non-2xx HTTP responses throw `APIError`.
|
|
208
|
+
|
|
209
|
+
```ts
|
|
210
|
+
import { APIError, isOpenAIError, isManagementError } from '@redonvn/event-ws-cliproxyapi-sdk';
|
|
211
|
+
|
|
212
|
+
try {
|
|
213
|
+
await management.getConfig();
|
|
214
|
+
} catch (err) {
|
|
215
|
+
if (err instanceof APIError) {
|
|
216
|
+
if (isOpenAIError(err.payload)) {
|
|
217
|
+
console.error('openai error:', err.payload.error.message);
|
|
218
|
+
} else if (isManagementError(err.payload)) {
|
|
219
|
+
console.error('management error:', err.payload.error);
|
|
220
|
+
} else {
|
|
221
|
+
console.error(err.status, err.message);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## Common Types
|
|
228
|
+
|
|
229
|
+
Selected primary request aliases:
|
|
230
|
+
- `PrimaryOpenAIChatRequest`
|
|
231
|
+
- `PrimaryOpenAICompletionRequest`
|
|
232
|
+
- `PrimaryOpenAIResponsesRequest`
|
|
233
|
+
- `PrimaryClaudeRequest`
|
|
234
|
+
- `PrimaryGeminiRequest`
|
|
235
|
+
- `PrimaryCliproxyRequest`
|
|
236
|
+
|
|
237
|
+
Protocol and shared types:
|
|
238
|
+
- JSON primitives/objects (`JsonValue`, `JsonObject`)
|
|
239
|
+
- model/config/auth entities
|
|
240
|
+
- OpenAI/Claude/Gemini compatible request/response types
|
|
241
|
+
|
|
242
|
+
## Development
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
npm i
|
|
246
|
+
npm run build
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
Build output:
|
|
250
|
+
- JS: `dist/*.js`
|
|
251
|
+
- Declarations: `dist/*.d.ts`
|
|
252
|
+
|
|
253
|
+
## Notes
|
|
254
|
+
|
|
255
|
+
- WebSocket auth: if server has `ws-auth: true`, provide `accessKey`.
|
|
256
|
+
- Management endpoints require `managementKey`.
|
|
257
|
+
- `keepAlive()` uses local auth (`localPassword`) if server enforces it.
|
|
258
|
+
- This SDK is transport-oriented; retries/backoff are intentionally left to the consumer.
|