@animalabs/membrane 0.5.50 → 0.5.52
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/context/index.d.ts +12 -0
- package/dist/context/index.js +11 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/process.d.ts +43 -0
- package/dist/context/process.js +381 -0
- package/dist/context/process.js.map +1 -0
- package/dist/context/types.d.ts +164 -0
- package/dist/context/types.js +61 -0
- package/dist/context/types.js.map +1 -0
- package/dist/formatters/anthropic-xml.d.ts +63 -0
- package/dist/formatters/anthropic-xml.js +417 -0
- package/dist/formatters/anthropic-xml.js.map +1 -0
- package/dist/formatters/completions.d.ts +68 -0
- package/dist/formatters/completions.js +261 -0
- package/dist/formatters/completions.js.map +1 -0
- package/dist/formatters/index.d.ts +8 -0
- package/dist/formatters/index.js +7 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/native.d.ts +35 -0
- package/dist/formatters/native.js +336 -0
- package/dist/formatters/native.js.map +1 -0
- package/dist/formatters/types.d.ts +167 -0
- package/dist/formatters/types.js +7 -0
- package/dist/formatters/types.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/membrane.d.ts +155 -0
- package/dist/providers/anthropic.d.ts +36 -0
- package/dist/providers/bedrock.d.ts +43 -0
- package/dist/providers/gemini.d.ts +68 -0
- package/dist/providers/gemini.js +538 -0
- package/dist/providers/gemini.js.map +1 -0
- package/dist/providers/index.d.ts +13 -0
- package/dist/providers/index.js +13 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/mock.d.ts +90 -0
- package/dist/providers/mock.d.ts.map +1 -0
- package/dist/providers/mock.js +210 -0
- package/dist/providers/mock.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +82 -0
- package/dist/providers/openai-compatible.js +480 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/providers/openai-completions.d.ts +89 -0
- package/dist/providers/openai-completions.js +347 -0
- package/dist/providers/openai-completions.js.map +1 -0
- package/dist/providers/openai-responses.d.ts +77 -0
- package/dist/providers/openai-responses.js +333 -0
- package/dist/providers/openai-responses.js.map +1 -0
- package/dist/providers/openai.d.ts +77 -0
- package/dist/providers/openai.js +533 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/openrouter.d.ts +82 -0
- package/dist/providers/openrouter.js +556 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/utils.d.ts +44 -0
- package/dist/providers/utils.d.ts.map +1 -0
- package/dist/providers/utils.js +100 -0
- package/dist/providers/utils.js.map +1 -0
- package/dist/registry/default-pricing.d.ts +3 -0
- package/dist/registry/default-pricing.d.ts.map +1 -0
- package/dist/registry/default-pricing.js +75 -0
- package/dist/registry/default-pricing.js.map +1 -0
- package/dist/transforms/chat.d.ts +52 -0
- package/dist/transforms/chat.js +136 -0
- package/dist/transforms/chat.js.map +1 -0
- package/dist/transforms/index.d.ts +5 -0
- package/dist/transforms/index.js +7 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/types/config.d.ts +110 -0
- package/dist/types/config.js +21 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types/content.d.ts +87 -0
- package/dist/types/content.d.ts.map +1 -0
- package/dist/types/content.js +40 -0
- package/dist/types/content.js.map +1 -0
- package/dist/types/errors.d.ts +50 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +253 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +20 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/message.d.ts +52 -0
- package/dist/types/message.d.ts.map +1 -0
- package/dist/types/message.js +38 -0
- package/dist/types/message.js.map +1 -0
- package/dist/types/provider.d.ts +169 -0
- package/dist/types/provider.d.ts.map +1 -0
- package/dist/types/provider.js +5 -0
- package/dist/types/provider.js.map +1 -0
- package/dist/types/request.d.ts +116 -0
- package/dist/types/request.d.ts.map +1 -0
- package/dist/types/request.js +5 -0
- package/dist/types/request.js.map +1 -0
- package/dist/types/response.d.ts +131 -0
- package/dist/types/response.d.ts.map +1 -0
- package/dist/types/response.js +7 -0
- package/dist/types/response.js.map +1 -0
- package/dist/types/streaming.d.ts +194 -0
- package/dist/types/streaming.js +5 -0
- package/dist/types/streaming.js.map +1 -0
- package/dist/types/tools.d.ts +71 -0
- package/dist/types/tools.d.ts.map +1 -0
- package/dist/types/tools.js +5 -0
- package/dist/types/tools.js.map +1 -0
- package/dist/utils/cost.d.ts +10 -0
- package/dist/utils/cost.d.ts.map +1 -0
- package/dist/utils/cost.js +19 -0
- package/dist/utils/cost.js.map +1 -0
- package/dist/utils/index.d.ts +7 -0
- package/dist/utils/index.js +6 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/stream-parser.d.ts +84 -0
- package/dist/utils/stream-parser.js +418 -0
- package/dist/utils/stream-parser.js.map +1 -0
- package/dist/utils/tool-parser.d.ts +134 -0
- package/dist/utils/tool-parser.js +600 -0
- package/dist/utils/tool-parser.js.map +1 -0
- package/dist/yielding-stream.d.ts +60 -0
- package/dist/yielding-stream.js +206 -0
- package/dist/yielding-stream.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,533 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI Direct provider adapter
|
|
3
|
+
*
|
|
4
|
+
* Direct adapter for OpenAI's API with support for modern models:
|
|
5
|
+
* - GPT-4o, GPT-4 Turbo
|
|
6
|
+
* - GPT-5, GPT-5-mini (uses max_completion_tokens)
|
|
7
|
+
* - o1, o3, o4-mini reasoning models
|
|
8
|
+
*
|
|
9
|
+
* Key differences from generic OpenAI-compatible:
|
|
10
|
+
* - Uses max_completion_tokens for newer models (not max_tokens)
|
|
11
|
+
* - Handles reasoning models' special requirements
|
|
12
|
+
* - Direct API integration with proper error handling
|
|
13
|
+
*/
|
|
14
|
+
import { MembraneError, rateLimitError, contextLengthError, authError, serverError, abortError, networkError, } from '../types/index.js';
|
|
15
|
+
import { safeParseJson, createCombinedSignal, SSELineParser } from './utils.js';
|
|
16
|
+
// ============================================================================
|
|
17
|
+
// Model Detection Helpers
|
|
18
|
+
// ============================================================================
|
|
19
|
+
/**
|
|
20
|
+
* Models that require max_completion_tokens instead of max_tokens
|
|
21
|
+
*/
|
|
22
|
+
const COMPLETION_TOKENS_MODELS = [
|
|
23
|
+
'gpt-5',
|
|
24
|
+
'gpt-5-mini',
|
|
25
|
+
'o1',
|
|
26
|
+
'o1-mini',
|
|
27
|
+
'o1-preview',
|
|
28
|
+
'o3',
|
|
29
|
+
'o3-mini',
|
|
30
|
+
'o4-mini',
|
|
31
|
+
];
|
|
32
|
+
/**
|
|
33
|
+
* Check if a model requires max_completion_tokens parameter
|
|
34
|
+
*/
|
|
35
|
+
function requiresCompletionTokens(model) {
|
|
36
|
+
return COMPLETION_TOKENS_MODELS.some(prefix => model.startsWith(prefix));
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Models that don't support custom temperature (only default 1.0)
|
|
40
|
+
*/
|
|
41
|
+
const NO_TEMPERATURE_MODELS = [
|
|
42
|
+
'gpt-5', // Base GPT-5 models
|
|
43
|
+
'gpt-5-mini',
|
|
44
|
+
'o1', // Reasoning models
|
|
45
|
+
'o1-mini',
|
|
46
|
+
'o1-preview',
|
|
47
|
+
'o3',
|
|
48
|
+
'o3-mini',
|
|
49
|
+
'o4-mini',
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* Check if a model doesn't support custom temperature
|
|
53
|
+
*/
|
|
54
|
+
function noTemperatureSupport(model) {
|
|
55
|
+
return NO_TEMPERATURE_MODELS.some(prefix => model.startsWith(prefix));
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Models that don't support stop sequences
|
|
59
|
+
*
|
|
60
|
+
* NOTE: Verified via API testing 2026-02-01. Some models that previously
|
|
61
|
+
* didn't support stop (o1, o3-mini) now do. Keep this list updated!
|
|
62
|
+
*
|
|
63
|
+
* Models using v1/responses endpoint (gpt-5-pro, o1-pro, etc.) are not
|
|
64
|
+
* included here as they use a different API path entirely.
|
|
65
|
+
*/
|
|
66
|
+
const NO_STOP_MODELS = [
|
|
67
|
+
// GPT-5.x chat models (all variants)
|
|
68
|
+
'gpt-5',
|
|
69
|
+
'gpt-5-mini',
|
|
70
|
+
'gpt-5-nano',
|
|
71
|
+
'gpt-5.1',
|
|
72
|
+
'gpt-5.2',
|
|
73
|
+
// Reasoning models that still don't support stop
|
|
74
|
+
'o3', // o3 (full) doesn't support stop, but o3-mini does!
|
|
75
|
+
'o4-mini',
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* Check if a model doesn't support stop sequences
|
|
79
|
+
*/
|
|
80
|
+
function noStopSupport(model) {
|
|
81
|
+
return NO_STOP_MODELS.some(prefix => model.startsWith(prefix));
|
|
82
|
+
}
|
|
83
|
+
// ============================================================================
|
|
84
|
+
// OpenAI Adapter
|
|
85
|
+
// ============================================================================
|
|
86
|
+
export class OpenAIAdapter {
|
|
87
|
+
name = 'openai';
|
|
88
|
+
apiKey;
|
|
89
|
+
baseURL;
|
|
90
|
+
organization;
|
|
91
|
+
defaultMaxTokens;
|
|
92
|
+
constructor(config = {}) {
|
|
93
|
+
this.apiKey = config.apiKey ?? process.env.OPENAI_API_KEY ?? '';
|
|
94
|
+
this.baseURL = config.baseURL ?? 'https://api.openai.com/v1';
|
|
95
|
+
this.organization = config.organization;
|
|
96
|
+
this.defaultMaxTokens = config.defaultMaxTokens ?? 4096;
|
|
97
|
+
if (!this.apiKey) {
|
|
98
|
+
throw new Error('OpenAI API key not provided');
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
supportsModel(modelId) {
|
|
102
|
+
// OpenAI models typically start with gpt-, o1, o3, o4
|
|
103
|
+
return (modelId.startsWith('gpt-') ||
|
|
104
|
+
modelId.startsWith('o1') ||
|
|
105
|
+
modelId.startsWith('o3') ||
|
|
106
|
+
modelId.startsWith('o4'));
|
|
107
|
+
}
|
|
108
|
+
async complete(request, options) {
|
|
109
|
+
const openAIRequest = this.buildRequest(request);
|
|
110
|
+
options?.onRequest?.(openAIRequest);
|
|
111
|
+
try {
|
|
112
|
+
const response = await this.makeRequest(openAIRequest, options);
|
|
113
|
+
return this.parseResponse(response, request.model, openAIRequest);
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
throw this.handleError(error, openAIRequest);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async stream(request, callbacks, options) {
|
|
120
|
+
const openAIRequest = this.buildRequest(request);
|
|
121
|
+
openAIRequest.stream = true;
|
|
122
|
+
// Request usage data in stream for cache metrics
|
|
123
|
+
openAIRequest.stream_options = { include_usage: true };
|
|
124
|
+
options?.onRequest?.(openAIRequest);
|
|
125
|
+
const { signal: combinedSignal, cleanup } = createCombinedSignal(options?.signal, options?.timeoutMs);
|
|
126
|
+
try {
|
|
127
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
128
|
+
method: 'POST',
|
|
129
|
+
headers: this.getHeaders(),
|
|
130
|
+
body: JSON.stringify(openAIRequest),
|
|
131
|
+
signal: combinedSignal,
|
|
132
|
+
});
|
|
133
|
+
if (!response.ok) {
|
|
134
|
+
const errorText = await response.text();
|
|
135
|
+
throw new Error(`OpenAI API error: ${response.status} ${errorText}`);
|
|
136
|
+
}
|
|
137
|
+
const reader = response.body?.getReader();
|
|
138
|
+
if (!reader) {
|
|
139
|
+
throw new Error('No response body');
|
|
140
|
+
}
|
|
141
|
+
const decoder = new TextDecoder();
|
|
142
|
+
const sseParser = new SSELineParser();
|
|
143
|
+
let accumulated = '';
|
|
144
|
+
let finishReason = 'stop';
|
|
145
|
+
let toolCalls = [];
|
|
146
|
+
let streamUsage;
|
|
147
|
+
while (true) {
|
|
148
|
+
const { done, value } = await reader.read();
|
|
149
|
+
if (done)
|
|
150
|
+
break;
|
|
151
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
152
|
+
const dataLines = sseParser.feed(chunk);
|
|
153
|
+
for (const data of dataLines) {
|
|
154
|
+
if (data === '[DONE]')
|
|
155
|
+
continue;
|
|
156
|
+
try {
|
|
157
|
+
const parsed = JSON.parse(data);
|
|
158
|
+
const delta = parsed.choices?.[0]?.delta;
|
|
159
|
+
if (delta?.content) {
|
|
160
|
+
accumulated += delta.content;
|
|
161
|
+
callbacks.onChunk(delta.content);
|
|
162
|
+
}
|
|
163
|
+
// Handle streaming tool calls
|
|
164
|
+
if (delta?.tool_calls) {
|
|
165
|
+
for (const tc of delta.tool_calls) {
|
|
166
|
+
const index = tc.index ?? 0;
|
|
167
|
+
if (!toolCalls[index]) {
|
|
168
|
+
toolCalls[index] = {
|
|
169
|
+
id: tc.id ?? '',
|
|
170
|
+
type: 'function',
|
|
171
|
+
function: { name: '', arguments: '' },
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
if (tc.id)
|
|
175
|
+
toolCalls[index].id = tc.id;
|
|
176
|
+
if (tc.function?.name)
|
|
177
|
+
toolCalls[index].function.name = tc.function.name;
|
|
178
|
+
if (tc.function?.arguments) {
|
|
179
|
+
toolCalls[index].function.arguments += tc.function.arguments;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (parsed.choices?.[0]?.finish_reason) {
|
|
184
|
+
finishReason = parsed.choices[0].finish_reason;
|
|
185
|
+
}
|
|
186
|
+
// Capture usage data (comes in final chunk with stream_options.include_usage)
|
|
187
|
+
if (parsed.usage) {
|
|
188
|
+
streamUsage = parsed.usage;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// Ignore parse errors in stream
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// Build response with accumulated data
|
|
197
|
+
const message = {
|
|
198
|
+
role: 'assistant',
|
|
199
|
+
content: accumulated || null,
|
|
200
|
+
};
|
|
201
|
+
if (toolCalls.length > 0) {
|
|
202
|
+
message.tool_calls = toolCalls;
|
|
203
|
+
}
|
|
204
|
+
return this.parseStreamedResponse(message, finishReason, request.model, streamUsage, openAIRequest);
|
|
205
|
+
}
|
|
206
|
+
catch (error) {
|
|
207
|
+
throw this.handleError(error, openAIRequest);
|
|
208
|
+
}
|
|
209
|
+
finally {
|
|
210
|
+
cleanup?.();
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
getHeaders() {
|
|
214
|
+
const headers = {
|
|
215
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
216
|
+
'Content-Type': 'application/json',
|
|
217
|
+
};
|
|
218
|
+
if (this.organization) {
|
|
219
|
+
headers['OpenAI-Organization'] = this.organization;
|
|
220
|
+
}
|
|
221
|
+
return headers;
|
|
222
|
+
}
|
|
223
|
+
buildRequest(request) {
|
|
224
|
+
const messages = this.convertMessages(request.messages);
|
|
225
|
+
const model = request.model;
|
|
226
|
+
const maxTokens = request.maxTokens || this.defaultMaxTokens;
|
|
227
|
+
// Handle system prompt (same as openrouter.ts)
|
|
228
|
+
if (request.system) {
|
|
229
|
+
if (typeof request.system === 'string') {
|
|
230
|
+
messages.unshift({ role: 'system', content: request.system });
|
|
231
|
+
}
|
|
232
|
+
else if (Array.isArray(request.system)) {
|
|
233
|
+
const text = request.system
|
|
234
|
+
.filter((b) => b.type === 'text')
|
|
235
|
+
.map((b) => b.text)
|
|
236
|
+
.join('\n');
|
|
237
|
+
if (text) {
|
|
238
|
+
messages.unshift({ role: 'system', content: text });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const params = {
|
|
243
|
+
model,
|
|
244
|
+
messages,
|
|
245
|
+
};
|
|
246
|
+
// Use appropriate max tokens parameter based on model
|
|
247
|
+
if (requiresCompletionTokens(model)) {
|
|
248
|
+
params.max_completion_tokens = maxTokens;
|
|
249
|
+
}
|
|
250
|
+
else {
|
|
251
|
+
params.max_tokens = maxTokens;
|
|
252
|
+
}
|
|
253
|
+
// Some models (gpt-5, o1, o3, o4) don't support custom temperature
|
|
254
|
+
if (request.temperature !== undefined && !noTemperatureSupport(model)) {
|
|
255
|
+
params.temperature = request.temperature;
|
|
256
|
+
}
|
|
257
|
+
if (request.topP !== undefined && !noTemperatureSupport(model)) {
|
|
258
|
+
params.top_p = request.topP;
|
|
259
|
+
}
|
|
260
|
+
if (request.presencePenalty !== undefined) {
|
|
261
|
+
params.presence_penalty = request.presencePenalty;
|
|
262
|
+
}
|
|
263
|
+
if (request.frequencyPenalty !== undefined) {
|
|
264
|
+
params.frequency_penalty = request.frequencyPenalty;
|
|
265
|
+
}
|
|
266
|
+
// Reasoning models (o1, o3, o4) don't support stop sequences
|
|
267
|
+
// OpenAI limits stop sequences to 4 — truncate to fit
|
|
268
|
+
if (request.stopSequences && request.stopSequences.length > 0 && !noStopSupport(model)) {
|
|
269
|
+
params.stop = request.stopSequences.slice(0, 4);
|
|
270
|
+
}
|
|
271
|
+
if (request.tools && request.tools.length > 0) {
|
|
272
|
+
params.tools = this.convertTools(request.tools);
|
|
273
|
+
}
|
|
274
|
+
// Apply extra params (filter out internal membrane fields)
|
|
275
|
+
if (request.extra) {
|
|
276
|
+
const { normalizedMessages, prompt, ...rest } = request.extra;
|
|
277
|
+
Object.assign(params, rest);
|
|
278
|
+
}
|
|
279
|
+
return params;
|
|
280
|
+
}
|
|
281
|
+
convertMessages(messages) {
|
|
282
|
+
// Use flatMap to handle one-to-many expansion (multiple tool_results → multiple messages)
|
|
283
|
+
return messages.flatMap(msg => {
|
|
284
|
+
// If it's already in OpenAI format, pass through
|
|
285
|
+
if (msg.role && (typeof msg.content === 'string' || msg.content === null || msg.tool_calls)) {
|
|
286
|
+
return [msg];
|
|
287
|
+
}
|
|
288
|
+
// Convert from Anthropic-style format
|
|
289
|
+
if (Array.isArray(msg.content)) {
|
|
290
|
+
const contentParts = [];
|
|
291
|
+
const toolCalls = [];
|
|
292
|
+
const toolResults = [];
|
|
293
|
+
for (const block of msg.content) {
|
|
294
|
+
if (block.type === 'text') {
|
|
295
|
+
contentParts.push({ type: 'text', text: block.text });
|
|
296
|
+
}
|
|
297
|
+
else if (block.type === 'image') {
|
|
298
|
+
// Convert Anthropic-style image to OpenAI image_url with data URI
|
|
299
|
+
if (block.source?.type === 'base64') {
|
|
300
|
+
const mediaType = block.source.media_type ?? block.source.mediaType ?? 'image/png';
|
|
301
|
+
contentParts.push({
|
|
302
|
+
type: 'image_url',
|
|
303
|
+
image_url: { url: `data:${mediaType};base64,${block.source.data}` },
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
else if (block.source?.type === 'url') {
|
|
307
|
+
contentParts.push({
|
|
308
|
+
type: 'image_url',
|
|
309
|
+
image_url: { url: block.source.url },
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
else if (block.type === 'tool_use') {
|
|
314
|
+
toolCalls.push({
|
|
315
|
+
id: block.id,
|
|
316
|
+
type: 'function',
|
|
317
|
+
function: {
|
|
318
|
+
name: block.name,
|
|
319
|
+
arguments: JSON.stringify(block.input),
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
else if (block.type === 'tool_result') {
|
|
324
|
+
// Collect ALL tool results - each becomes a separate message
|
|
325
|
+
toolResults.push({
|
|
326
|
+
role: 'tool',
|
|
327
|
+
tool_call_id: block.tool_use_id || block.toolUseId,
|
|
328
|
+
content: typeof block.content === 'string' ? block.content : JSON.stringify(block.content),
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
// If we have tool results, return them (possibly multiple)
|
|
333
|
+
if (toolResults.length > 0) {
|
|
334
|
+
return toolResults;
|
|
335
|
+
}
|
|
336
|
+
// Skip messages with no usable content
|
|
337
|
+
if (contentParts.length === 0 && toolCalls.length === 0) {
|
|
338
|
+
return [];
|
|
339
|
+
}
|
|
340
|
+
// Build message — use string content when there are no images (simpler, more compatible)
|
|
341
|
+
const hasImages = contentParts.some(p => p.type === 'image_url');
|
|
342
|
+
const textOnly = contentParts.filter(p => p.type === 'text').map(p => p.text).join('\n');
|
|
343
|
+
const result = {
|
|
344
|
+
role: msg.role,
|
|
345
|
+
content: hasImages ? contentParts : (textOnly || null),
|
|
346
|
+
};
|
|
347
|
+
if (toolCalls.length > 0) {
|
|
348
|
+
result.tool_calls = toolCalls;
|
|
349
|
+
}
|
|
350
|
+
return [result];
|
|
351
|
+
}
|
|
352
|
+
return [{
|
|
353
|
+
role: msg.role,
|
|
354
|
+
content: msg.content,
|
|
355
|
+
}];
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
convertTools(tools) {
|
|
359
|
+
return tools.map(tool => {
|
|
360
|
+
const inputSchema = tool.inputSchema || tool.input_schema || { type: 'object', properties: {} };
|
|
361
|
+
return {
|
|
362
|
+
type: 'function',
|
|
363
|
+
function: {
|
|
364
|
+
name: tool.name,
|
|
365
|
+
description: tool.description,
|
|
366
|
+
parameters: inputSchema,
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
});
|
|
370
|
+
}
|
|
371
|
+
async makeRequest(request, options) {
|
|
372
|
+
const { signal: combinedSignal, cleanup } = createCombinedSignal(options?.signal, options?.timeoutMs);
|
|
373
|
+
try {
|
|
374
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
375
|
+
method: 'POST',
|
|
376
|
+
headers: this.getHeaders(),
|
|
377
|
+
body: JSON.stringify(request),
|
|
378
|
+
signal: combinedSignal,
|
|
379
|
+
});
|
|
380
|
+
if (!response.ok) {
|
|
381
|
+
const errorText = await response.text();
|
|
382
|
+
throw new Error(`OpenAI API error: ${response.status} ${errorText}`);
|
|
383
|
+
}
|
|
384
|
+
return await response.json();
|
|
385
|
+
}
|
|
386
|
+
finally {
|
|
387
|
+
cleanup?.();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
parseResponse(response, requestedModel, rawRequest) {
|
|
391
|
+
const choice = response.choices[0];
|
|
392
|
+
const message = choice?.message;
|
|
393
|
+
// Extract prompt caching details (OpenAI automatic caching for prompts ≥1024 tokens)
|
|
394
|
+
const cachedTokens = response.usage?.prompt_tokens_details?.cached_tokens ?? 0;
|
|
395
|
+
return {
|
|
396
|
+
content: this.messageToContent(message),
|
|
397
|
+
stopReason: this.mapFinishReason(choice?.finish_reason),
|
|
398
|
+
stopSequence: undefined,
|
|
399
|
+
usage: {
|
|
400
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
401
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
402
|
+
// OpenAI's automatic prompt caching - cached tokens are read from cache
|
|
403
|
+
// Note: OpenAI doesn't have separate "creation" tokens - it's automatic
|
|
404
|
+
cacheReadTokens: cachedTokens > 0 ? cachedTokens : undefined,
|
|
405
|
+
},
|
|
406
|
+
model: response.model ?? requestedModel,
|
|
407
|
+
rawRequest,
|
|
408
|
+
raw: response,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
411
|
+
parseStreamedResponse(message, finishReason, requestedModel, streamUsage, rawRequest) {
|
|
412
|
+
// Extract cached tokens from stream usage if available
|
|
413
|
+
const cachedTokens = streamUsage?.prompt_tokens_details?.cached_tokens ?? 0;
|
|
414
|
+
return {
|
|
415
|
+
content: this.messageToContent(message),
|
|
416
|
+
stopReason: this.mapFinishReason(finishReason),
|
|
417
|
+
stopSequence: undefined,
|
|
418
|
+
usage: {
|
|
419
|
+
inputTokens: streamUsage?.prompt_tokens ?? 0,
|
|
420
|
+
outputTokens: streamUsage?.completion_tokens ?? 0,
|
|
421
|
+
cacheReadTokens: cachedTokens > 0 ? cachedTokens : undefined,
|
|
422
|
+
},
|
|
423
|
+
model: requestedModel,
|
|
424
|
+
rawRequest,
|
|
425
|
+
raw: { message, finish_reason: finishReason, usage: streamUsage },
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
messageToContent(message) {
|
|
429
|
+
if (!message)
|
|
430
|
+
return [];
|
|
431
|
+
const content = [];
|
|
432
|
+
if (message.content) {
|
|
433
|
+
// Response content is always a string (array format is request-only)
|
|
434
|
+
const text = typeof message.content === 'string' ? message.content : message.content.filter(p => p.type === 'text').map(p => p.text).join('\n');
|
|
435
|
+
if (text)
|
|
436
|
+
content.push({ type: 'text', text });
|
|
437
|
+
}
|
|
438
|
+
if (message.tool_calls) {
|
|
439
|
+
for (const tc of message.tool_calls) {
|
|
440
|
+
content.push({
|
|
441
|
+
type: 'tool_use',
|
|
442
|
+
id: tc.id,
|
|
443
|
+
name: tc.function.name,
|
|
444
|
+
input: safeParseJson(tc.function.arguments),
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
return content;
|
|
449
|
+
}
|
|
450
|
+
mapFinishReason(reason) {
|
|
451
|
+
switch (reason) {
|
|
452
|
+
case 'stop':
|
|
453
|
+
return 'end_turn';
|
|
454
|
+
case 'length':
|
|
455
|
+
return 'max_tokens';
|
|
456
|
+
case 'tool_calls':
|
|
457
|
+
return 'tool_use';
|
|
458
|
+
case 'content_filter':
|
|
459
|
+
return 'refusal';
|
|
460
|
+
default:
|
|
461
|
+
return 'end_turn';
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
handleError(error, rawRequest) {
|
|
465
|
+
if (error instanceof Error) {
|
|
466
|
+
const message = error.message;
|
|
467
|
+
// OpenAI specific error patterns
|
|
468
|
+
if (message.includes('429') || message.includes('rate_limit')) {
|
|
469
|
+
// Try to extract retry-after
|
|
470
|
+
const retryMatch = message.match(/retry after (\d+)/i);
|
|
471
|
+
const retryAfter = retryMatch?.[1] ? parseInt(retryMatch[1], 10) * 1000 : undefined;
|
|
472
|
+
return rateLimitError(message, retryAfter, error, rawRequest);
|
|
473
|
+
}
|
|
474
|
+
if (message.includes('401') || message.includes('invalid_api_key') || message.includes('Incorrect API key')) {
|
|
475
|
+
return authError(message, error, rawRequest);
|
|
476
|
+
}
|
|
477
|
+
if (message.includes('context_length') || message.includes('maximum context') || message.includes('too long')) {
|
|
478
|
+
return contextLengthError(message, error, rawRequest);
|
|
479
|
+
}
|
|
480
|
+
if (message.includes('500') || message.includes('502') || message.includes('503') || message.includes('server_error')) {
|
|
481
|
+
return serverError(message, undefined, error, rawRequest);
|
|
482
|
+
}
|
|
483
|
+
if (error.name === 'AbortError') {
|
|
484
|
+
return abortError(undefined, rawRequest);
|
|
485
|
+
}
|
|
486
|
+
if (message.includes('network') || message.includes('fetch') || message.includes('ECONNREFUSED')) {
|
|
487
|
+
return networkError(message, error, rawRequest);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
return new MembraneError({
|
|
491
|
+
type: 'unknown',
|
|
492
|
+
message: error instanceof Error ? error.message : String(error),
|
|
493
|
+
retryable: false,
|
|
494
|
+
rawError: error,
|
|
495
|
+
rawRequest,
|
|
496
|
+
});
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
// ============================================================================
|
|
500
|
+
// Content Conversion Utilities
|
|
501
|
+
// ============================================================================
|
|
502
|
+
/**
|
|
503
|
+
* Convert normalized content blocks to OpenAI message format
|
|
504
|
+
*/
|
|
505
|
+
export function toOpenAIContent(blocks) {
|
|
506
|
+
const textBlocks = blocks.filter(b => b.type === 'text');
|
|
507
|
+
if (textBlocks.length === 0)
|
|
508
|
+
return null;
|
|
509
|
+
return textBlocks.map(b => b.text).join('\n');
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* Convert OpenAI response message to normalized content blocks
|
|
513
|
+
*/
|
|
514
|
+
export function fromOpenAIContent(message) {
|
|
515
|
+
const result = [];
|
|
516
|
+
if (message.content) {
|
|
517
|
+
const text = typeof message.content === 'string' ? message.content : message.content.filter(p => p.type === 'text').map(p => p.text).join('\n');
|
|
518
|
+
if (text)
|
|
519
|
+
result.push({ type: 'text', text });
|
|
520
|
+
}
|
|
521
|
+
if (message.tool_calls) {
|
|
522
|
+
for (const tc of message.tool_calls) {
|
|
523
|
+
result.push({
|
|
524
|
+
type: 'tool_use',
|
|
525
|
+
id: tc.id,
|
|
526
|
+
name: tc.function.name,
|
|
527
|
+
input: safeParseJson(tc.function.arguments),
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
return result;
|
|
532
|
+
}
|
|
533
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenRouter provider adapter
|
|
3
|
+
*
|
|
4
|
+
* Handles OpenAI-compatible API with tool_calls format
|
|
5
|
+
*/
|
|
6
|
+
import type { ProviderAdapter, ProviderRequest, ProviderRequestOptions, ProviderResponse, StreamCallbacks, ContentBlock } from '../types/index.js';
|
|
7
|
+
/** Content block for messages through OpenRouter */
|
|
8
|
+
type OpenRouterContentBlock = {
|
|
9
|
+
type: 'text';
|
|
10
|
+
text: string;
|
|
11
|
+
cache_control?: {
|
|
12
|
+
type: 'ephemeral';
|
|
13
|
+
};
|
|
14
|
+
} | {
|
|
15
|
+
type: 'image_url';
|
|
16
|
+
image_url: {
|
|
17
|
+
url: string;
|
|
18
|
+
detail?: string;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
interface OpenRouterMessage {
|
|
22
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
23
|
+
/** Can be string, null, or content blocks array (for Claude cache_control / images) */
|
|
24
|
+
content?: string | null | OpenRouterContentBlock[];
|
|
25
|
+
tool_calls?: OpenRouterToolCall[];
|
|
26
|
+
tool_call_id?: string;
|
|
27
|
+
}
|
|
28
|
+
interface OpenRouterToolCall {
|
|
29
|
+
id: string;
|
|
30
|
+
type: 'function';
|
|
31
|
+
function: {
|
|
32
|
+
name: string;
|
|
33
|
+
arguments: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface OpenRouterAdapterConfig {
|
|
37
|
+
/** API key (defaults to OPENROUTER_API_KEY env var) */
|
|
38
|
+
apiKey?: string;
|
|
39
|
+
/** Base URL (default: https://openrouter.ai/api/v1) */
|
|
40
|
+
baseURL?: string;
|
|
41
|
+
/** HTTP Referer header for OpenRouter */
|
|
42
|
+
httpReferer?: string;
|
|
43
|
+
/** X-Title header for OpenRouter */
|
|
44
|
+
xTitle?: string;
|
|
45
|
+
/** Default max tokens */
|
|
46
|
+
defaultMaxTokens?: number;
|
|
47
|
+
}
|
|
48
|
+
export declare class OpenRouterAdapter implements ProviderAdapter {
|
|
49
|
+
readonly name = "openrouter";
|
|
50
|
+
private apiKey;
|
|
51
|
+
private baseURL;
|
|
52
|
+
private httpReferer;
|
|
53
|
+
private xTitle;
|
|
54
|
+
private defaultMaxTokens;
|
|
55
|
+
constructor(config?: OpenRouterAdapterConfig);
|
|
56
|
+
supportsModel(modelId: string): boolean;
|
|
57
|
+
complete(request: ProviderRequest, options?: ProviderRequestOptions): Promise<ProviderResponse>;
|
|
58
|
+
stream(request: ProviderRequest, callbacks: StreamCallbacks, options?: ProviderRequestOptions): Promise<ProviderResponse>;
|
|
59
|
+
private getHeaders;
|
|
60
|
+
private buildRequest;
|
|
61
|
+
private convertMessages;
|
|
62
|
+
private convertTools;
|
|
63
|
+
private makeRequest;
|
|
64
|
+
private parseResponse;
|
|
65
|
+
private parseStreamedResponse;
|
|
66
|
+
private messageToContent;
|
|
67
|
+
private mapFinishReason;
|
|
68
|
+
private handleError;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Convert normalized content blocks to OpenRouter format
|
|
72
|
+
*/
|
|
73
|
+
export declare function toOpenRouterMessages(messages: {
|
|
74
|
+
role: string;
|
|
75
|
+
content: ContentBlock[];
|
|
76
|
+
}[]): OpenRouterMessage[];
|
|
77
|
+
/**
|
|
78
|
+
* Convert OpenRouter response to normalized content blocks
|
|
79
|
+
*/
|
|
80
|
+
export declare function fromOpenRouterMessage(message: OpenRouterMessage): ContentBlock[];
|
|
81
|
+
export {};
|
|
82
|
+
//# sourceMappingURL=openrouter.d.ts.map
|