@premai/api-sdk 1.0.41 → 1.0.43
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 +184 -39
- package/dist/anthropic/count-tokens-route.d.ts +3 -0
- package/dist/anthropic/from-openai.d.ts +33 -0
- package/dist/anthropic/http.d.ts +19 -0
- package/dist/anthropic/messages-route.d.ts +3 -0
- package/dist/anthropic/models-route.d.ts +3 -0
- package/dist/anthropic/to-openai.d.ts +35 -0
- package/dist/bare.cjs +25981 -0
- package/dist/bare.d.ts +31 -0
- package/dist/bare.mjs +25938 -0
- package/dist/cli-claude.d.ts +2 -0
- package/dist/cli-claude.mjs +3304 -0
- package/dist/cli.mjs +2959 -0
- package/dist/core.browser.cjs +159 -20
- package/dist/core.browser.mjs +159 -20
- package/dist/index.cjs +1506 -237
- package/dist/index.d.ts +5 -3
- package/dist/index.mjs +1506 -239
- package/dist/launcher/claude-code.d.ts +1 -0
- package/dist/launcher/model-picker.d.ts +7 -0
- package/dist/launcher/proxy-subprocess.d.ts +13 -0
- package/dist/launcher/text-input.d.ts +3 -0
- package/dist/openai/routes.d.ts +3 -0
- package/dist/server/create-app.d.ts +8 -0
- package/dist/server/discovery.d.ts +7 -0
- package/dist/server/route-prefix.d.ts +9 -0
- package/dist/server/runtime.d.ts +8 -0
- package/dist/server/start.d.ts +4 -0
- package/dist/server.d.ts +7 -5
- package/dist/types.d.ts +9 -3
- package/package.json +20 -10
- package/dist/bare-global.d.ts +0 -4
- package/dist/bare-global.mjs +0 -30
- package/dist/cli.cjs +0 -1699
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ Environment Variables:
|
|
|
34
34
|
* ENCLAVE_URL
|
|
35
35
|
* PROXY_URL
|
|
36
36
|
* CLIENT_KEK
|
|
37
|
+
* JSON_BODY_LIMIT (optional, default: `32mb`)
|
|
37
38
|
* HOST (optional)
|
|
38
39
|
* PORT (optional)
|
|
39
40
|
|
|
@@ -42,8 +43,8 @@ Run as a standalone server with automatic DEK store management per API key:
|
|
|
42
43
|
```bash
|
|
43
44
|
# ways to run the termination proxy
|
|
44
45
|
## run command from local/remote NPM package
|
|
45
|
-
bunx -p @premai/api-sdk
|
|
46
|
-
npx -p @premai/api-sdk
|
|
46
|
+
bunx -p @premai/api-sdk confidential-proxy
|
|
47
|
+
npx -p @premai/api-sdk confidential-proxy
|
|
47
48
|
|
|
48
49
|
## install globally
|
|
49
50
|
## make sure to have the "global bin dir" in your PATH
|
|
@@ -51,13 +52,54 @@ npx -p @premai/api-sdk pcci-proxy
|
|
|
51
52
|
npm i -g @premai/api-sdk
|
|
52
53
|
bun i -g @premai/api-sdk
|
|
53
54
|
|
|
54
|
-
# Server runs on http://
|
|
55
|
+
# Server runs on http://127.0.0.1:8000
|
|
55
56
|
```
|
|
56
57
|
|
|
57
|
-
|
|
58
|
+
### CLI Options
|
|
58
59
|
|
|
59
60
|
```bash
|
|
60
|
-
|
|
61
|
+
# Basic usage
|
|
62
|
+
confidential-proxy --host 127.0.0.1 --port 8000
|
|
63
|
+
|
|
64
|
+
# Anthropic compatibility mode
|
|
65
|
+
confidential-proxy --compat anthropic
|
|
66
|
+
|
|
67
|
+
# Both OpenAI and Anthropic (served under /openai and /anthropic prefixes)
|
|
68
|
+
confidential-proxy --compat both
|
|
69
|
+
|
|
70
|
+
# Custom route prefixes
|
|
71
|
+
confidential-proxy --compat both --openai-prefix /openai --anthropic-prefix /anthropic
|
|
72
|
+
|
|
73
|
+
# Custom backend URLs
|
|
74
|
+
confidential-proxy --proxy-url https://proxy.example.com --enclave-url https://enclave.example.com
|
|
75
|
+
|
|
76
|
+
# Client KEK
|
|
77
|
+
confidential-proxy --kek your-kek
|
|
78
|
+
|
|
79
|
+
# JSON body size limit
|
|
80
|
+
confidential-proxy --json-body-limit 64mb
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Compatibility Modes
|
|
84
|
+
|
|
85
|
+
The server supports three compatibility modes via `--compat`:
|
|
86
|
+
|
|
87
|
+
| Mode | Description | Routes |
|
|
88
|
+
|------|-------------|--------|
|
|
89
|
+
| `openai` | OpenAI-compatible API only | `/v1/*` |
|
|
90
|
+
| `anthropic` | Anthropic-compatible API only | `/v1/*` |
|
|
91
|
+
| `both` | Both APIs side-by-side | `/openai/v1/*` and `/anthropic/v1/*` |
|
|
92
|
+
|
|
93
|
+
When using `--compat both`, the server exposes both OpenAI and Anthropic APIs under separate route prefixes to avoid conflicts. Custom prefixes can be set with `--openai-prefix` and `--anthropic-prefix`.
|
|
94
|
+
|
|
95
|
+
The Anthropic API translates incoming Anthropic Messages requests to the internal OpenAI-compatible enclave, then pipes the response back as Anthropic SSE events.
|
|
96
|
+
|
|
97
|
+
### OpenAI API Usage
|
|
98
|
+
|
|
99
|
+
Use with any OpenAI-compatible client via curl:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
curl http://127.0.0.1:8000/v1/chat/completions \
|
|
61
103
|
-H "Authorization: Bearer your-api-key" \
|
|
62
104
|
-H "Content-Type: application/json" \
|
|
63
105
|
-d '{
|
|
@@ -76,7 +118,7 @@ import OpenAI from "openai";
|
|
|
76
118
|
|
|
77
119
|
const client = new OpenAI({
|
|
78
120
|
apiKey: "your-api-key",
|
|
79
|
-
baseURL: "http://
|
|
121
|
+
baseURL: "http://127.0.0.1:8000/v1",
|
|
80
122
|
});
|
|
81
123
|
|
|
82
124
|
const stream = await client.chat.completions.create({
|
|
@@ -90,19 +132,92 @@ for await (const chunk of stream) {
|
|
|
90
132
|
}
|
|
91
133
|
```
|
|
92
134
|
|
|
135
|
+
### Anthropic API Usage
|
|
136
|
+
|
|
137
|
+
When `--compat anthropic` or `--compat both`, the server exposes an Anthropic-compatible Messages API:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
curl http://127.0.0.1:8000/v1/messages \
|
|
141
|
+
-H "x-api-key: your-api-key" \
|
|
142
|
+
-H "anthropic-version: 2023-06-01" \
|
|
143
|
+
-H "Content-Type: application/json" \
|
|
144
|
+
-d '{
|
|
145
|
+
"model": "claude-sonnet-4-6",
|
|
146
|
+
"max_tokens": 1024,
|
|
147
|
+
"messages": [
|
|
148
|
+
{"role": "user", "content": "Hello!"}
|
|
149
|
+
]
|
|
150
|
+
}'
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
With streaming:
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
curl -N http://127.0.0.1:8000/v1/messages \
|
|
157
|
+
-H "x-api-key: your-api-key" \
|
|
158
|
+
-H "anthropic-version: 2023-06-01" \
|
|
159
|
+
-H "Content-Type: application/json" \
|
|
160
|
+
-d '{
|
|
161
|
+
"model": "claude-sonnet-4-6",
|
|
162
|
+
"max_tokens": 1024,
|
|
163
|
+
"messages": [
|
|
164
|
+
{"role": "user", "content": "Count to 10"}
|
|
165
|
+
],
|
|
166
|
+
"stream": true
|
|
167
|
+
}'
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
The server supports system prompts, tool use, image inputs, stop sequences, temperature, and top_p. Response events follow the Anthropic SSE format (`message_start`, `content_block_start`, `content_block_delta`, `content_block_stop`, `message_delta`, `message_stop`).
|
|
171
|
+
|
|
93
172
|
The server caches clients in memory per API key for better performance.
|
|
94
173
|
|
|
174
|
+
## confidential-claude — Claude Code Launcher
|
|
175
|
+
|
|
176
|
+
Run [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview) through the encrypted proxy with zero configuration:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# run without installing
|
|
180
|
+
bunx -p @premai/api-sdk confidential-claude
|
|
181
|
+
npx -p @premai/api-sdk confidential-claude
|
|
182
|
+
|
|
183
|
+
# or install globally first
|
|
184
|
+
npm i -g @premai/api-sdk
|
|
185
|
+
bun i -g @premai/api-sdk
|
|
186
|
+
|
|
187
|
+
confidential-claude
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The launcher:
|
|
191
|
+
|
|
192
|
+
1. Reads `.env` from application directory or environment variables (prompts interactively if missing)
|
|
193
|
+
2. Spawns an encrypted proxy subprocess in Anthropic-only mode
|
|
194
|
+
3. Fetches the available model list and lets you pick one
|
|
195
|
+
4. Launches `claude` wired to the confidential gateway
|
|
196
|
+
|
|
197
|
+
All traffic remains end-to-end encrypted. The proxy subprocess is cleaned up when Claude Code exits.
|
|
198
|
+
|
|
199
|
+
Any extra arguments are forwarded to `claude` directly:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
# Run in a specific directory
|
|
203
|
+
confidential-claude -p /path/to/project
|
|
204
|
+
|
|
205
|
+
# Run a one-shot command
|
|
206
|
+
confidential-claude --print "summarize the changed files"
|
|
207
|
+
```
|
|
208
|
+
|
|
95
209
|
## Features
|
|
96
210
|
|
|
97
|
-
-
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
-
|
|
103
|
-
-
|
|
104
|
-
-
|
|
105
|
-
-
|
|
211
|
+
- Chat Completions - OpenAI and Anthropic compatible APIs with streaming support
|
|
212
|
+
- Models - List available models
|
|
213
|
+
- File Management - Upload, list, get, and delete encrypted files
|
|
214
|
+
- File Upload - Client-side encrypted file uploads with per-file DEKs
|
|
215
|
+
- Tools - Image generation, transcription, RAG search, and more
|
|
216
|
+
- End-to-end Encryption - Post-quantum cryptography (XWing)
|
|
217
|
+
- KEK Architecture - Key Encryption Key wraps all file DEKs
|
|
218
|
+
- RAG Support - Encrypted document retrieval with persistent RAG DEK
|
|
219
|
+
- Attestation - Enclave attestation is always enabled for security
|
|
220
|
+
- TypeScript - Full type safety
|
|
106
221
|
|
|
107
222
|
## Chat Completions
|
|
108
223
|
|
|
@@ -224,7 +339,7 @@ const client = await createRvencClient({
|
|
|
224
339
|
const serializedStore = serializeDEKStore(client.dekStore);
|
|
225
340
|
fs.writeFileSync("./dek-store.json", serializedStore);
|
|
226
341
|
|
|
227
|
-
console.log("
|
|
342
|
+
console.log("DEK store saved. Keep this file secure!");
|
|
228
343
|
```
|
|
229
344
|
|
|
230
345
|
### Subsequent Usage
|
|
@@ -263,7 +378,7 @@ console.log("Uploaded:", result.id);
|
|
|
263
378
|
// ⚠️ IMPORTANT: Save dekStore after upload to persist file DEKs
|
|
264
379
|
const serialized = serializeDEKStore(client.dekStore);
|
|
265
380
|
fs.writeFileSync("./dek-store.json", serialized);
|
|
266
|
-
console.log("
|
|
381
|
+
console.log("DEK store updated with file encryption keys");
|
|
267
382
|
```
|
|
268
383
|
|
|
269
384
|
### Upload Files with RAG Indexing
|
|
@@ -357,7 +472,7 @@ console.log(file.mime_type);
|
|
|
357
472
|
console.log(file.created_at);
|
|
358
473
|
|
|
359
474
|
// Get file with signed download URL
|
|
360
|
-
const fileWithUrl = await client.files.get({
|
|
475
|
+
const fileWithUrl = await client.files.get({
|
|
361
476
|
id: 'file-id-123',
|
|
362
477
|
url: true // Include signed download URL
|
|
363
478
|
});
|
|
@@ -409,9 +524,9 @@ const indexResult = await client.files.index({
|
|
|
409
524
|
// Check results
|
|
410
525
|
indexResult.data.results.forEach(result => {
|
|
411
526
|
if (result.success) {
|
|
412
|
-
console.log(
|
|
527
|
+
console.log(`File ${result.file_id}: ${result.rag_status}`);
|
|
413
528
|
} else {
|
|
414
|
-
console.error(
|
|
529
|
+
console.error(`File ${result.file_id} failed: ${result.error}`);
|
|
415
530
|
}
|
|
416
531
|
});
|
|
417
532
|
```
|
|
@@ -440,14 +555,14 @@ await client.files.index({
|
|
|
440
555
|
// Option 3: Provide custom fileDEK for specific files
|
|
441
556
|
await client.files.index({
|
|
442
557
|
files: [
|
|
443
|
-
{
|
|
444
|
-
fileId: 'file-id-1',
|
|
558
|
+
{
|
|
559
|
+
fileId: 'file-id-1',
|
|
445
560
|
filePath: 's3/path/file1.enc',
|
|
446
561
|
fileDEK: customFileDEK // Custom DEK for this file
|
|
447
562
|
},
|
|
448
|
-
{
|
|
449
|
-
fileId: 'file-id-2',
|
|
450
|
-
filePath: 's3/path/file2.enc'
|
|
563
|
+
{
|
|
564
|
+
fileId: 'file-id-2',
|
|
565
|
+
filePath: 's3/path/file2.enc'
|
|
451
566
|
// Uses dekStore for this file
|
|
452
567
|
},
|
|
453
568
|
],
|
|
@@ -504,9 +619,9 @@ const deleteResult = await client.files.deleteIndex({
|
|
|
504
619
|
// Check results
|
|
505
620
|
deleteResult.data.results.forEach(result => {
|
|
506
621
|
if (result.success) {
|
|
507
|
-
console.log(
|
|
622
|
+
console.log(`File ${result.file_id} removed from index`);
|
|
508
623
|
} else {
|
|
509
|
-
console.error(
|
|
624
|
+
console.error(`File ${result.file_id} failed: ${result.error}`);
|
|
510
625
|
}
|
|
511
626
|
});
|
|
512
627
|
```
|
|
@@ -701,8 +816,9 @@ console.log(ragResults);
|
|
|
701
816
|
|--------|------|---------|-------------|
|
|
702
817
|
| `apiKey` | `string` | **required** | Authorization token |
|
|
703
818
|
| `encryptionKeys` | `EncryptionKeys` | auto-generated | Pre-generated ML-KEM keys |
|
|
819
|
+
| `clientKEK` | `string` | `CLIENT_KEK` env | Key Encryption Key for wrapping file DEKs |
|
|
704
820
|
| `dekStore` | `DEKStore` | auto-generated | DEKs for files and RAG |
|
|
705
|
-
| `requestTimeoutMs` | `number` | `
|
|
821
|
+
| `requestTimeoutMs` | `number` | `600000` | Request timeout in milliseconds (10 min) |
|
|
706
822
|
| `maxBufferSize` | `number` | `10485760` | Max SSE buffer size (10MB) |
|
|
707
823
|
|
|
708
824
|
## DEK Store Management
|
|
@@ -775,6 +891,15 @@ fs.writeFileSync("dek-store.json", serialized);
|
|
|
775
891
|
3. **Encrypted Transport**: Sends `{ cipherText, encryptedInference, nonce }` to proxy
|
|
776
892
|
4. **Response Decryption**: Decrypts response (streaming SSE or JSON) using shared secret
|
|
777
893
|
|
|
894
|
+
### Anthropic API Compatibility
|
|
895
|
+
|
|
896
|
+
The server translates Anthropic Messages requests to OpenAI-compatible format internally:
|
|
897
|
+
|
|
898
|
+
1. **Request conversion**: Anthropic system blocks, tool_use, image inputs, and tool_result blocks are mapped to OpenAI equivalents
|
|
899
|
+
2. **Enclave call**: The translated request is dispatched through the encrypted OpenAI pipeline
|
|
900
|
+
3. **Response conversion**: OpenAI completions (or chunk streams) are translated back to Anthropic SSE events with proper `content_block_start`, `content_block_delta`, and `content_block_stop` framing
|
|
901
|
+
4. **Tool streaming**: OpenAI tool_call chunks are replayed as Anthropic `input_json_delta` events with incremental argument flushing
|
|
902
|
+
|
|
778
903
|
### File Upload
|
|
779
904
|
|
|
780
905
|
1. **DEK Generation**: Generates random 32-byte DEK for this file
|
|
@@ -801,7 +926,7 @@ fs.writeFileSync("dek-store.json", serialized);
|
|
|
801
926
|
4. **Enclave Decrypts**: Enclave decrypts fileDEK, then decrypts file from S3
|
|
802
927
|
5. **Response**: Returns encrypted result, SDK decrypts with shared secret
|
|
803
928
|
|
|
804
|
-
#### File-Producing Tools
|
|
929
|
+
#### File-Producing Tools
|
|
805
930
|
1. **Generate DEK**: Creates random DEK for output file
|
|
806
931
|
2. **Encrypt Request**: Encrypts tool parameters with shared secret
|
|
807
932
|
3. **Enclave Executes**: Generates file, encrypts with provided DEK
|
|
@@ -824,10 +949,10 @@ try {
|
|
|
824
949
|
apiKey: "your-api-key",
|
|
825
950
|
clientKEK: "your-kek" // You can pass clientKEK here or as an env variable CLIENT_KEK
|
|
826
951
|
});
|
|
827
|
-
|
|
952
|
+
|
|
828
953
|
const image = await client.tools.generateImage("mountain landscape");
|
|
829
954
|
fs.writeFileSync(image.fileName, image.content);
|
|
830
|
-
|
|
955
|
+
|
|
831
956
|
} catch (error) {
|
|
832
957
|
if (error.message.includes("timeout")) {
|
|
833
958
|
console.error("Request timed out");
|
|
@@ -839,14 +964,15 @@ try {
|
|
|
839
964
|
|
|
840
965
|
## Security Notes
|
|
841
966
|
|
|
842
|
-
-
|
|
843
|
-
-
|
|
844
|
-
-
|
|
845
|
-
-
|
|
846
|
-
-
|
|
847
|
-
-
|
|
848
|
-
-
|
|
849
|
-
-
|
|
967
|
+
- **Use environment variables** for API keys & client KEK
|
|
968
|
+
- **Always persist dekStore after file uploads** - file DEKs must be saved
|
|
969
|
+
- **Backup your dekStore** - losing it means losing access to uploaded files
|
|
970
|
+
- All encryption happens client-side (zero-knowledge)
|
|
971
|
+
- Files are encrypted with unique DEKs before upload
|
|
972
|
+
- KEK-based architecture - KEK wraps all file DEKs
|
|
973
|
+
- Tool responses are automatically decrypted
|
|
974
|
+
- Post-quantum secure (XWing: ML-KEM768 + X25519)
|
|
975
|
+
- Enclave attestation is always enabled and cannot be disabled
|
|
850
976
|
|
|
851
977
|
### Encryption Architecture
|
|
852
978
|
|
|
@@ -897,3 +1023,22 @@ import type {
|
|
|
897
1023
|
PaginationInfo,
|
|
898
1024
|
} from "@premai/api-sdk";
|
|
899
1025
|
```
|
|
1026
|
+
|
|
1027
|
+
## BareKit (mobile)
|
|
1028
|
+
|
|
1029
|
+
When running this SDK inside a [react-native-bare-kit](https://github.com/holepunchto/react-native-bare-kit) worklet, pass an `assets` directory to `new Worklet(...)`. bare-kit extracts bundled assets to that directory at startup and rewrites resolutions to real `file://` URLs — this lets WASM to load directly from disk on the fast path:
|
|
1030
|
+
|
|
1031
|
+
```js
|
|
1032
|
+
import { Worklet } from 'react-native-bare-kit';
|
|
1033
|
+
import * as FileSystem from 'expo-file-system'
|
|
1034
|
+
|
|
1035
|
+
const cacheDir = new FileSystem.Directory(FileSystem.Paths.cache, 'reticle-assets')
|
|
1036
|
+
if (!cacheDir.exists) cacheDir.create()
|
|
1037
|
+
|
|
1038
|
+
const worklet = new Worklet({
|
|
1039
|
+
assets: cacheDir.uri.replace(/^file:\/\//, ''),
|
|
1040
|
+
});
|
|
1041
|
+
await worklet.start('/worklet.bundle', source);
|
|
1042
|
+
```
|
|
1043
|
+
|
|
1044
|
+
If `assets` is omitted, the SDK falls back to an inline base64 copy of the WASM bytes shipped inside the module.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Response } from "express";
|
|
2
|
+
import type OpenAI from "openai";
|
|
3
|
+
export type AnthropicUsage = {
|
|
4
|
+
input_tokens: number;
|
|
5
|
+
output_tokens: number;
|
|
6
|
+
};
|
|
7
|
+
export type AnthropicTextContentBlock = {
|
|
8
|
+
type: "text";
|
|
9
|
+
text: string;
|
|
10
|
+
};
|
|
11
|
+
export type AnthropicToolUseContentBlock = {
|
|
12
|
+
type: "tool_use";
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
input: unknown;
|
|
16
|
+
};
|
|
17
|
+
export type AnthropicAssistantContentBlock = AnthropicTextContentBlock | AnthropicToolUseContentBlock;
|
|
18
|
+
export type AnthropicMessagePayload = {
|
|
19
|
+
id: string;
|
|
20
|
+
type: "message";
|
|
21
|
+
role: "assistant";
|
|
22
|
+
content: AnthropicAssistantContentBlock[];
|
|
23
|
+
model: string;
|
|
24
|
+
stop_reason: AnthropicStopReason | null;
|
|
25
|
+
stop_sequence: string | null;
|
|
26
|
+
usage: AnthropicUsage;
|
|
27
|
+
};
|
|
28
|
+
export type AnthropicStopReason = "end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "pause_turn" | "refusal";
|
|
29
|
+
export declare function openAIChatCompletionToAnthropicMessage(completion: OpenAI.Chat.ChatCompletion, requestModel: string): AnthropicMessagePayload;
|
|
30
|
+
export declare function pipeOpenAIChunkStreamToAnthropicSse(res: Response, stream: AsyncIterable<OpenAI.Chat.Completions.ChatCompletionChunk>, options: {
|
|
31
|
+
anthropicModel: string;
|
|
32
|
+
messageId: string;
|
|
33
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Request, Response } from "express";
|
|
2
|
+
export declare const ANTHROPIC_VERSION_DEFAULT = "2023-06-01";
|
|
3
|
+
export declare function isAnthropicApiVersionSupported(version: string): boolean;
|
|
4
|
+
export declare function newAnthropicRequestId(): string;
|
|
5
|
+
export declare function newAnthropicMessageId(): string;
|
|
6
|
+
export declare function extractAnthropicApiKey(req: Request): string | null;
|
|
7
|
+
export declare function getAnthropicVersionHeader(req: Request): string | null;
|
|
8
|
+
export type AnthropicVersionResult = {
|
|
9
|
+
ok: true;
|
|
10
|
+
version: string;
|
|
11
|
+
} | {
|
|
12
|
+
ok: false;
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function resolveAnthropicVersion(req: Request): AnthropicVersionResult;
|
|
16
|
+
export declare function sendAnthropicHttpError(res: Response, status: number, errorType: string, message: string, requestId: string): void;
|
|
17
|
+
export declare function httpStatusToAnthropicErrorType(status: number): string;
|
|
18
|
+
export declare function mapUnknownErrorToAnthropicResponse(err: unknown, res: Response, requestId: string): void;
|
|
19
|
+
export declare function writeAnthropicSseEvent(res: Response, event: string, data: Record<string, unknown>): void;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type OpenAI from "openai";
|
|
2
|
+
export type AnthropicTextBlock = {
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
};
|
|
6
|
+
type AnthropicContentPart = AnthropicTextBlock | {
|
|
7
|
+
type: string;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
};
|
|
10
|
+
export type AnthropicMessage = {
|
|
11
|
+
role: "user" | "assistant";
|
|
12
|
+
content: string | AnthropicContentPart[];
|
|
13
|
+
};
|
|
14
|
+
export type AnthropicMessagesCreateBody = {
|
|
15
|
+
model: string;
|
|
16
|
+
max_tokens: number;
|
|
17
|
+
messages: AnthropicMessage[];
|
|
18
|
+
system?: string | AnthropicTextBlock | AnthropicTextBlock[];
|
|
19
|
+
stream?: boolean;
|
|
20
|
+
metadata?: unknown;
|
|
21
|
+
stop_sequences?: string[];
|
|
22
|
+
temperature?: number;
|
|
23
|
+
top_p?: number;
|
|
24
|
+
top_k?: number;
|
|
25
|
+
tools?: unknown;
|
|
26
|
+
tool_choice?: unknown;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
};
|
|
29
|
+
export declare class AnthropicRequestValidationError extends Error {
|
|
30
|
+
readonly status = 400;
|
|
31
|
+
readonly anthropicType = "invalid_request_error";
|
|
32
|
+
constructor(message: string);
|
|
33
|
+
}
|
|
34
|
+
export declare function anthropicMessagesCreateToOpenAI(body: AnthropicMessagesCreateBody): OpenAI.Chat.ChatCompletionCreateParams;
|
|
35
|
+
export {};
|