@animalabs/membrane 0.5.51 → 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.
Files changed (123) hide show
  1. package/dist/context/index.d.ts +12 -0
  2. package/dist/context/index.js +11 -0
  3. package/dist/context/index.js.map +1 -0
  4. package/dist/context/process.d.ts +43 -0
  5. package/dist/context/process.js +381 -0
  6. package/dist/context/process.js.map +1 -0
  7. package/dist/context/types.d.ts +164 -0
  8. package/dist/context/types.js +61 -0
  9. package/dist/context/types.js.map +1 -0
  10. package/dist/formatters/anthropic-xml.d.ts +63 -0
  11. package/dist/formatters/anthropic-xml.js +417 -0
  12. package/dist/formatters/anthropic-xml.js.map +1 -0
  13. package/dist/formatters/completions.d.ts +68 -0
  14. package/dist/formatters/completions.js +261 -0
  15. package/dist/formatters/completions.js.map +1 -0
  16. package/dist/formatters/index.d.ts +8 -0
  17. package/dist/formatters/index.js +7 -0
  18. package/dist/formatters/index.js.map +1 -0
  19. package/dist/formatters/native.d.ts +35 -0
  20. package/dist/formatters/native.js +336 -0
  21. package/dist/formatters/native.js.map +1 -0
  22. package/dist/formatters/types.d.ts +167 -0
  23. package/dist/formatters/types.js +7 -0
  24. package/dist/formatters/types.js.map +1 -0
  25. package/dist/index.d.ts +13 -0
  26. package/dist/index.js +20 -0
  27. package/dist/index.js.map +1 -0
  28. package/dist/membrane.d.ts +155 -0
  29. package/dist/providers/anthropic.d.ts +36 -0
  30. package/dist/providers/bedrock.d.ts +43 -0
  31. package/dist/providers/gemini.d.ts +68 -0
  32. package/dist/providers/gemini.js +538 -0
  33. package/dist/providers/gemini.js.map +1 -0
  34. package/dist/providers/index.d.ts +13 -0
  35. package/dist/providers/index.js +13 -0
  36. package/dist/providers/index.js.map +1 -0
  37. package/dist/providers/mock.d.ts +90 -0
  38. package/dist/providers/mock.d.ts.map +1 -0
  39. package/dist/providers/mock.js +210 -0
  40. package/dist/providers/mock.js.map +1 -0
  41. package/dist/providers/openai-compatible.d.ts +82 -0
  42. package/dist/providers/openai-compatible.js +480 -0
  43. package/dist/providers/openai-compatible.js.map +1 -0
  44. package/dist/providers/openai-completions.d.ts +89 -0
  45. package/dist/providers/openai-completions.js +347 -0
  46. package/dist/providers/openai-completions.js.map +1 -0
  47. package/dist/providers/openai-responses.d.ts +77 -0
  48. package/dist/providers/openai-responses.js +333 -0
  49. package/dist/providers/openai-responses.js.map +1 -0
  50. package/dist/providers/openai.d.ts +77 -0
  51. package/dist/providers/openai.js +533 -0
  52. package/dist/providers/openai.js.map +1 -0
  53. package/dist/providers/openrouter.d.ts +82 -0
  54. package/dist/providers/openrouter.js +556 -0
  55. package/dist/providers/openrouter.js.map +1 -0
  56. package/dist/providers/utils.d.ts +44 -0
  57. package/dist/providers/utils.d.ts.map +1 -0
  58. package/dist/providers/utils.js +100 -0
  59. package/dist/providers/utils.js.map +1 -0
  60. package/dist/registry/default-pricing.d.ts +3 -0
  61. package/dist/registry/default-pricing.d.ts.map +1 -0
  62. package/dist/registry/default-pricing.js +75 -0
  63. package/dist/registry/default-pricing.js.map +1 -0
  64. package/dist/transforms/chat.d.ts +52 -0
  65. package/dist/transforms/chat.js +136 -0
  66. package/dist/transforms/chat.js.map +1 -0
  67. package/dist/transforms/index.d.ts +5 -0
  68. package/dist/transforms/index.js +7 -0
  69. package/dist/transforms/index.js.map +1 -0
  70. package/dist/types/config.d.ts +110 -0
  71. package/dist/types/config.js +21 -0
  72. package/dist/types/config.js.map +1 -0
  73. package/dist/types/content.d.ts +87 -0
  74. package/dist/types/content.d.ts.map +1 -0
  75. package/dist/types/content.js +40 -0
  76. package/dist/types/content.js.map +1 -0
  77. package/dist/types/errors.d.ts +50 -0
  78. package/dist/types/errors.d.ts.map +1 -0
  79. package/dist/types/errors.js +253 -0
  80. package/dist/types/errors.js.map +1 -0
  81. package/dist/types/index.d.ts +20 -0
  82. package/dist/types/index.js +10 -0
  83. package/dist/types/index.js.map +1 -0
  84. package/dist/types/message.d.ts +52 -0
  85. package/dist/types/message.d.ts.map +1 -0
  86. package/dist/types/message.js +38 -0
  87. package/dist/types/message.js.map +1 -0
  88. package/dist/types/provider.d.ts +169 -0
  89. package/dist/types/provider.d.ts.map +1 -0
  90. package/dist/types/provider.js +5 -0
  91. package/dist/types/provider.js.map +1 -0
  92. package/dist/types/request.d.ts +116 -0
  93. package/dist/types/request.d.ts.map +1 -0
  94. package/dist/types/request.js +5 -0
  95. package/dist/types/request.js.map +1 -0
  96. package/dist/types/response.d.ts +131 -0
  97. package/dist/types/response.d.ts.map +1 -0
  98. package/dist/types/response.js +7 -0
  99. package/dist/types/response.js.map +1 -0
  100. package/dist/types/streaming.d.ts +194 -0
  101. package/dist/types/streaming.js +5 -0
  102. package/dist/types/streaming.js.map +1 -0
  103. package/dist/types/tools.d.ts +71 -0
  104. package/dist/types/tools.d.ts.map +1 -0
  105. package/dist/types/tools.js +5 -0
  106. package/dist/types/tools.js.map +1 -0
  107. package/dist/utils/cost.d.ts +10 -0
  108. package/dist/utils/cost.d.ts.map +1 -0
  109. package/dist/utils/cost.js +19 -0
  110. package/dist/utils/cost.js.map +1 -0
  111. package/dist/utils/index.d.ts +7 -0
  112. package/dist/utils/index.js +6 -0
  113. package/dist/utils/index.js.map +1 -0
  114. package/dist/utils/stream-parser.d.ts +84 -0
  115. package/dist/utils/stream-parser.js +418 -0
  116. package/dist/utils/stream-parser.js.map +1 -0
  117. package/dist/utils/tool-parser.d.ts +134 -0
  118. package/dist/utils/tool-parser.js +600 -0
  119. package/dist/utils/tool-parser.js.map +1 -0
  120. package/dist/yielding-stream.d.ts +60 -0
  121. package/dist/yielding-stream.js +206 -0
  122. package/dist/yielding-stream.js.map +1 -0
  123. package/package.json +1 -1
@@ -0,0 +1,556 @@
1
+ /**
2
+ * OpenRouter provider adapter
3
+ *
4
+ * Handles OpenAI-compatible API with tool_calls format
5
+ */
6
+ import { MembraneError, rateLimitError, contextLengthError, authError, serverError, abortError, networkError, } from '../types/index.js';
7
+ import { safeParseJson, createCombinedSignal, SSELineParser } from './utils.js';
8
+ // ============================================================================
9
+ // OpenRouter Adapter
10
+ // ============================================================================
11
+ export class OpenRouterAdapter {
12
+ name = 'openrouter';
13
+ apiKey;
14
+ baseURL;
15
+ httpReferer;
16
+ xTitle;
17
+ defaultMaxTokens;
18
+ constructor(config = {}) {
19
+ this.apiKey = config.apiKey ?? process.env.OPENROUTER_API_KEY ?? '';
20
+ this.baseURL = config.baseURL ?? 'https://openrouter.ai/api/v1';
21
+ this.httpReferer = config.httpReferer ?? 'https://membrane.local';
22
+ this.xTitle = config.xTitle ?? 'Membrane';
23
+ this.defaultMaxTokens = config.defaultMaxTokens ?? 4096;
24
+ if (!this.apiKey) {
25
+ throw new Error('OpenRouter API key not provided');
26
+ }
27
+ }
28
+ supportsModel(modelId) {
29
+ // OpenRouter supports many models
30
+ return modelId.includes('/');
31
+ }
32
+ async complete(request, options) {
33
+ const openRouterRequest = this.buildRequest(request);
34
+ options?.onRequest?.(openRouterRequest);
35
+ try {
36
+ const response = await this.makeRequest(openRouterRequest, options);
37
+ return this.parseResponse(response, request.model, openRouterRequest);
38
+ }
39
+ catch (error) {
40
+ throw this.handleError(error, openRouterRequest);
41
+ }
42
+ }
43
+ async stream(request, callbacks, options) {
44
+ const openRouterRequest = this.buildRequest(request);
45
+ openRouterRequest.stream = true;
46
+ // Request usage data in stream for cache metrics
47
+ openRouterRequest.stream_options = { include_usage: true };
48
+ options?.onRequest?.(openRouterRequest);
49
+ const { signal: combinedSignal, cleanup } = createCombinedSignal(options?.signal, options?.timeoutMs);
50
+ try {
51
+ const response = await fetch(`${this.baseURL}/chat/completions`, {
52
+ method: 'POST',
53
+ headers: this.getHeaders(),
54
+ body: JSON.stringify(openRouterRequest),
55
+ signal: combinedSignal,
56
+ });
57
+ if (!response.ok) {
58
+ const errorText = await response.text();
59
+ throw new Error(`OpenRouter error: ${response.status} ${errorText}`);
60
+ }
61
+ const reader = response.body?.getReader();
62
+ if (!reader) {
63
+ throw new Error('No response body');
64
+ }
65
+ const decoder = new TextDecoder();
66
+ const sseParser = new SSELineParser();
67
+ let accumulated = '';
68
+ let finishReason = 'stop';
69
+ let toolCalls = [];
70
+ let streamUsage;
71
+ while (true) {
72
+ const { done, value } = await reader.read();
73
+ if (done)
74
+ break;
75
+ const chunk = decoder.decode(value, { stream: true });
76
+ const dataLines = sseParser.feed(chunk);
77
+ for (const data of dataLines) {
78
+ if (data === '[DONE]')
79
+ continue;
80
+ try {
81
+ const parsed = JSON.parse(data);
82
+ const delta = parsed.choices?.[0]?.delta;
83
+ if (delta?.content) {
84
+ accumulated += delta.content;
85
+ callbacks.onChunk(delta.content);
86
+ }
87
+ // Handle streaming tool calls
88
+ if (delta?.tool_calls) {
89
+ for (const tc of delta.tool_calls) {
90
+ const index = tc.index ?? 0;
91
+ if (!toolCalls[index]) {
92
+ toolCalls[index] = {
93
+ id: tc.id ?? '',
94
+ type: 'function',
95
+ function: { name: '', arguments: '' },
96
+ };
97
+ }
98
+ if (tc.id)
99
+ toolCalls[index].id = tc.id;
100
+ if (tc.function?.name)
101
+ toolCalls[index].function.name = tc.function.name;
102
+ if (tc.function?.arguments) {
103
+ toolCalls[index].function.arguments += tc.function.arguments;
104
+ }
105
+ }
106
+ }
107
+ if (parsed.choices?.[0]?.finish_reason) {
108
+ finishReason = parsed.choices[0].finish_reason;
109
+ }
110
+ // Capture usage data (comes in final chunk when stream_options.include_usage is set)
111
+ if (parsed.usage) {
112
+ streamUsage = parsed.usage;
113
+ }
114
+ }
115
+ catch (e) {
116
+ // Ignore parse errors
117
+ }
118
+ }
119
+ }
120
+ // Build response with accumulated data
121
+ const message = {
122
+ role: 'assistant',
123
+ content: accumulated || null,
124
+ };
125
+ if (toolCalls.length > 0) {
126
+ message.tool_calls = toolCalls;
127
+ }
128
+ return this.parseStreamedResponse(message, finishReason, request.model, streamUsage, openRouterRequest);
129
+ }
130
+ catch (error) {
131
+ throw this.handleError(error, openRouterRequest);
132
+ }
133
+ finally {
134
+ cleanup?.();
135
+ }
136
+ }
137
+ getHeaders() {
138
+ return {
139
+ 'Authorization': `Bearer ${this.apiKey}`,
140
+ 'Content-Type': 'application/json',
141
+ 'HTTP-Referer': this.httpReferer,
142
+ 'X-Title': this.xTitle,
143
+ };
144
+ }
145
+ buildRequest(request) {
146
+ const messages = this.convertMessages(request.messages);
147
+ const params = {
148
+ model: request.model,
149
+ messages,
150
+ max_tokens: request.maxTokens || this.defaultMaxTokens,
151
+ };
152
+ // Handle system prompt (can be string or content blocks with cache_control)
153
+ if (request.system) {
154
+ if (typeof request.system === 'string') {
155
+ // Simple string system prompt - prepend as system message
156
+ messages.unshift({ role: 'system', content: request.system });
157
+ }
158
+ else if (Array.isArray(request.system)) {
159
+ // Content blocks with potential cache_control - preserve for Claude caching
160
+ const hasCache = request.system.some((block) => block.cache_control);
161
+ if (hasCache) {
162
+ // Preserve cache_control in content block format for Claude
163
+ messages.unshift({
164
+ role: 'system',
165
+ content: request.system,
166
+ });
167
+ }
168
+ else {
169
+ // No caching, just join text
170
+ const text = request.system
171
+ .filter((b) => b.type === 'text')
172
+ .map((b) => b.text)
173
+ .join('\n');
174
+ messages.unshift({ role: 'system', content: text });
175
+ }
176
+ }
177
+ }
178
+ if (request.temperature !== undefined) {
179
+ params.temperature = request.temperature;
180
+ }
181
+ // Anthropic models (routed via OpenRouter) reject both temperature and top_p.
182
+ const isAnthropicModel = /claude|anthropic/i.test(request.model);
183
+ if (request.topP !== undefined && !(isAnthropicModel && request.temperature !== undefined)) {
184
+ params.top_p = request.topP;
185
+ }
186
+ if (request.presencePenalty !== undefined) {
187
+ params.presence_penalty = request.presencePenalty;
188
+ }
189
+ if (request.frequencyPenalty !== undefined) {
190
+ params.frequency_penalty = request.frequencyPenalty;
191
+ }
192
+ // OpenAI-compatible APIs may limit stop sequences (OpenAI: 4) — truncate to be safe
193
+ if (request.stopSequences && request.stopSequences.length > 0) {
194
+ params.stop = request.stopSequences.slice(0, 4);
195
+ }
196
+ if (request.tools && request.tools.length > 0) {
197
+ // Check if tools are already in OpenRouter format (from buildNativeToolRequest)
198
+ const firstTool = request.tools[0];
199
+ if (firstTool.input_schema) {
200
+ // Already in provider format
201
+ params.tools = request.tools.map((t) => ({
202
+ type: 'function',
203
+ function: {
204
+ name: t.name,
205
+ description: t.description,
206
+ parameters: t.input_schema,
207
+ },
208
+ }));
209
+ }
210
+ else if (firstTool.inputSchema) {
211
+ // In ToolDefinition format
212
+ params.tools = this.convertTools(request.tools);
213
+ }
214
+ else {
215
+ // Unknown format, pass through
216
+ params.tools = request.tools;
217
+ }
218
+ }
219
+ // Apply extra params (filter out internal membrane fields)
220
+ if (request.extra) {
221
+ const { normalizedMessages, prompt, ...rest } = request.extra;
222
+ Object.assign(params, rest);
223
+ }
224
+ return params;
225
+ }
226
+ convertMessages(messages) {
227
+ // Use flatMap to handle one-to-many expansion (multiple tool_results → multiple messages)
228
+ return messages.flatMap(msg => {
229
+ // If it's already in OpenRouter format, pass through
230
+ if (msg.role && (typeof msg.content === 'string' || msg.content === null || msg.tool_calls)) {
231
+ return [msg];
232
+ }
233
+ // Convert from Anthropic-style format
234
+ if (Array.isArray(msg.content)) {
235
+ // Check if any block has cache_control - if so, preserve the array format
236
+ // This is needed for Claude models through OpenRouter to use prompt caching
237
+ const hasCache = msg.content.some((block) => block.cache_control);
238
+ const toolCalls = [];
239
+ const contentBlocks = [];
240
+ const textParts = [];
241
+ const toolResults = [];
242
+ let hasImages = false;
243
+ for (const block of msg.content) {
244
+ if (block.type === 'text') {
245
+ if (hasCache || hasImages) {
246
+ const contentBlock = {
247
+ type: 'text',
248
+ text: block.text,
249
+ };
250
+ if (block.cache_control) {
251
+ contentBlock.cache_control = block.cache_control;
252
+ }
253
+ contentBlocks.push(contentBlock);
254
+ }
255
+ else {
256
+ textParts.push(block.text);
257
+ }
258
+ }
259
+ else if (block.type === 'image') {
260
+ hasImages = true;
261
+ // Migrate any already-collected textParts into contentBlocks
262
+ // (we didn't know we'd need array format until hitting an image)
263
+ for (const text of textParts) {
264
+ contentBlocks.push({ type: 'text', text });
265
+ }
266
+ textParts.length = 0;
267
+ if (block.source?.type === 'base64') {
268
+ const mediaType = block.source.media_type ?? block.source.mediaType ?? 'image/png';
269
+ contentBlocks.push({
270
+ type: 'image_url',
271
+ image_url: { url: `data:${mediaType};base64,${block.source.data}` },
272
+ });
273
+ }
274
+ else if (block.source?.type === 'url') {
275
+ contentBlocks.push({
276
+ type: 'image_url',
277
+ image_url: { url: block.source.url },
278
+ });
279
+ }
280
+ }
281
+ else if (block.type === 'tool_use') {
282
+ toolCalls.push({
283
+ id: block.id,
284
+ type: 'function',
285
+ function: {
286
+ name: block.name,
287
+ arguments: JSON.stringify(block.input),
288
+ },
289
+ });
290
+ }
291
+ else if (block.type === 'tool_result') {
292
+ // Collect ALL tool results - each becomes a separate message
293
+ toolResults.push({
294
+ role: 'tool',
295
+ tool_call_id: block.tool_use_id || block.toolUseId,
296
+ content: typeof block.content === 'string' ? block.content : JSON.stringify(block.content),
297
+ });
298
+ }
299
+ }
300
+ // If we have tool results, return them (possibly multiple)
301
+ if (toolResults.length > 0) {
302
+ return toolResults;
303
+ }
304
+ // Skip messages with no usable content
305
+ if (textParts.length === 0 && contentBlocks.length === 0 && toolCalls.length === 0) {
306
+ return [];
307
+ }
308
+ // Use content blocks array if caching or images require it, otherwise concatenate text
309
+ const useArray = hasCache || hasImages;
310
+ const result = {
311
+ role: msg.role,
312
+ content: useArray ? contentBlocks : (textParts.length > 0 ? textParts.join('\n') : null),
313
+ };
314
+ if (toolCalls.length > 0) {
315
+ result.tool_calls = toolCalls;
316
+ }
317
+ return [result];
318
+ }
319
+ return [{
320
+ role: msg.role,
321
+ content: msg.content,
322
+ }];
323
+ });
324
+ }
325
+ convertTools(tools) {
326
+ return tools.map(tool => ({
327
+ type: 'function',
328
+ function: {
329
+ name: tool.name,
330
+ description: tool.description,
331
+ parameters: tool.inputSchema,
332
+ },
333
+ }));
334
+ }
335
+ async makeRequest(request, options) {
336
+ const { signal: combinedSignal, cleanup } = createCombinedSignal(options?.signal, options?.timeoutMs);
337
+ try {
338
+ const response = await fetch(`${this.baseURL}/chat/completions`, {
339
+ method: 'POST',
340
+ headers: this.getHeaders(),
341
+ body: JSON.stringify(request),
342
+ signal: combinedSignal,
343
+ });
344
+ if (!response.ok) {
345
+ const errorText = await response.text();
346
+ throw new Error(`OpenRouter error: ${response.status} ${errorText}`);
347
+ }
348
+ return await response.json();
349
+ }
350
+ finally {
351
+ cleanup?.();
352
+ }
353
+ }
354
+ parseResponse(response, requestedModel, rawRequest) {
355
+ const choice = response.choices[0];
356
+ const message = choice?.message;
357
+ // Extract cache tokens - OpenRouter passes through both Anthropic and OpenAI caching
358
+ // Anthropic: cache_creation_input_tokens, cache_read_input_tokens
359
+ // OpenAI: prompt_tokens_details.cached_tokens
360
+ const cacheCreationTokens = response.usage?.cache_creation_input_tokens;
361
+ const cacheReadTokens = response.usage?.cache_read_input_tokens
362
+ ?? response.usage?.prompt_tokens_details?.cached_tokens;
363
+ return {
364
+ content: this.messageToContent(message),
365
+ stopReason: this.mapFinishReason(choice?.finish_reason),
366
+ stopSequence: undefined,
367
+ usage: {
368
+ inputTokens: response.usage?.prompt_tokens ?? 0,
369
+ outputTokens: response.usage?.completion_tokens ?? 0,
370
+ cacheCreationTokens: cacheCreationTokens ?? undefined,
371
+ cacheReadTokens: cacheReadTokens ?? undefined,
372
+ },
373
+ model: response.model ?? requestedModel,
374
+ rawRequest,
375
+ raw: response,
376
+ };
377
+ }
378
+ parseStreamedResponse(message, finishReason, requestedModel, streamUsage, rawRequest) {
379
+ // Extract cache tokens if available from stream usage
380
+ const cacheCreationTokens = streamUsage?.cache_creation_input_tokens;
381
+ const cacheReadTokens = streamUsage?.cache_read_input_tokens
382
+ ?? streamUsage?.prompt_tokens_details?.cached_tokens;
383
+ return {
384
+ content: this.messageToContent(message),
385
+ stopReason: this.mapFinishReason(finishReason),
386
+ stopSequence: undefined,
387
+ usage: {
388
+ inputTokens: streamUsage?.prompt_tokens ?? 0,
389
+ outputTokens: streamUsage?.completion_tokens ?? 0,
390
+ cacheCreationTokens: cacheCreationTokens ?? undefined,
391
+ cacheReadTokens: cacheReadTokens ?? undefined,
392
+ },
393
+ model: requestedModel,
394
+ rawRequest,
395
+ raw: { message, finish_reason: finishReason, usage: streamUsage },
396
+ };
397
+ }
398
+ messageToContent(message) {
399
+ if (!message)
400
+ return [];
401
+ const content = [];
402
+ if (message.content) {
403
+ if (typeof message.content === 'string') {
404
+ content.push({ type: 'text', text: message.content });
405
+ }
406
+ else if (Array.isArray(message.content)) {
407
+ for (const block of message.content) {
408
+ if (block.type === 'text') {
409
+ content.push({ type: 'text', text: block.text });
410
+ }
411
+ }
412
+ }
413
+ }
414
+ if (message.tool_calls) {
415
+ for (const tc of message.tool_calls) {
416
+ content.push({
417
+ type: 'tool_use',
418
+ id: tc.id,
419
+ name: tc.function.name,
420
+ input: safeParseJson(tc.function.arguments),
421
+ });
422
+ }
423
+ }
424
+ return content;
425
+ }
426
+ mapFinishReason(reason) {
427
+ switch (reason) {
428
+ case 'stop':
429
+ return 'end_turn';
430
+ case 'length':
431
+ return 'max_tokens';
432
+ case 'tool_calls':
433
+ return 'tool_use';
434
+ case 'content_filter':
435
+ return 'refusal';
436
+ default:
437
+ return 'end_turn';
438
+ }
439
+ }
440
+ handleError(error, rawRequest) {
441
+ if (error instanceof Error) {
442
+ const message = error.message;
443
+ if (message.includes('429') || message.includes('rate')) {
444
+ return rateLimitError(message, undefined, error, rawRequest);
445
+ }
446
+ if (message.includes('401') || message.includes('auth')) {
447
+ return authError(message, error, rawRequest);
448
+ }
449
+ if (message.includes('context') || message.includes('too long')) {
450
+ return contextLengthError(message, error, rawRequest);
451
+ }
452
+ if (message.includes('500') || message.includes('502') || message.includes('503')) {
453
+ return serverError(message, undefined, error, rawRequest);
454
+ }
455
+ if (error.name === 'AbortError') {
456
+ return abortError(undefined, rawRequest);
457
+ }
458
+ if (message.includes('network') || message.includes('fetch')) {
459
+ return networkError(message, error, rawRequest);
460
+ }
461
+ }
462
+ return new MembraneError({
463
+ type: 'unknown',
464
+ message: error instanceof Error ? error.message : String(error),
465
+ retryable: false,
466
+ rawError: error,
467
+ rawRequest,
468
+ });
469
+ }
470
+ }
471
+ // ============================================================================
472
+ // Content Conversion Utilities
473
+ // ============================================================================
474
+ /**
475
+ * Convert normalized content blocks to OpenRouter format
476
+ */
477
+ export function toOpenRouterMessages(messages) {
478
+ const result = [];
479
+ for (const msg of messages) {
480
+ const textParts = [];
481
+ const toolCalls = [];
482
+ const toolResults = [];
483
+ for (const block of msg.content) {
484
+ if (block.type === 'text') {
485
+ textParts.push(block.text);
486
+ }
487
+ else if (block.type === 'tool_use') {
488
+ toolCalls.push({
489
+ id: block.id,
490
+ type: 'function',
491
+ function: {
492
+ name: block.name,
493
+ arguments: JSON.stringify(block.input),
494
+ },
495
+ });
496
+ }
497
+ else if (block.type === 'tool_result') {
498
+ toolResults.push({
499
+ id: block.toolUseId,
500
+ content: typeof block.content === 'string' ? block.content : JSON.stringify(block.content),
501
+ });
502
+ }
503
+ }
504
+ // Add main message
505
+ if (textParts.length > 0 || toolCalls.length > 0) {
506
+ const message = {
507
+ role: msg.role,
508
+ content: textParts.join('\n') || null,
509
+ };
510
+ if (toolCalls.length > 0) {
511
+ message.tool_calls = toolCalls;
512
+ }
513
+ result.push(message);
514
+ }
515
+ // Add tool results as separate messages
516
+ for (const tr of toolResults) {
517
+ result.push({
518
+ role: 'tool',
519
+ tool_call_id: tr.id,
520
+ content: tr.content,
521
+ });
522
+ }
523
+ }
524
+ return result;
525
+ }
526
+ /**
527
+ * Convert OpenRouter response to normalized content blocks
528
+ */
529
+ export function fromOpenRouterMessage(message) {
530
+ const result = [];
531
+ if (message.content) {
532
+ if (typeof message.content === 'string') {
533
+ result.push({ type: 'text', text: message.content });
534
+ }
535
+ else if (Array.isArray(message.content)) {
536
+ // Content blocks array - extract text (cache_control is for requests only)
537
+ for (const block of message.content) {
538
+ if (block.type === 'text') {
539
+ result.push({ type: 'text', text: block.text });
540
+ }
541
+ }
542
+ }
543
+ }
544
+ if (message.tool_calls) {
545
+ for (const tc of message.tool_calls) {
546
+ result.push({
547
+ type: 'tool_use',
548
+ id: tc.id,
549
+ name: tc.function.name,
550
+ input: safeParseJson(tc.function.arguments),
551
+ });
552
+ }
553
+ }
554
+ return result;
555
+ }
556
+ //# sourceMappingURL=openrouter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openrouter.js","sourceRoot":"","sources":["../../src/providers/openrouter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Safely parse a JSON string, returning an empty object on failure.
3
+ * Used for tool call arguments which may be malformed from streaming.
4
+ */
5
+ export declare function safeParseJson(str: string | undefined): Record<string, unknown>;
6
+ /**
7
+ * Create a combined AbortSignal that fires on either the caller's signal
8
+ * or a timeout (whichever comes first).
9
+ *
10
+ * The returned `cleanup` function MUST be called in a `finally` block to
11
+ * clear the timeout and remove the event listener, preventing leaks.
12
+ *
13
+ * Timeout aborts with `DOMException('Request timed out', 'AbortError')`
14
+ * so it classifies identically to user-initiated aborts.
15
+ */
16
+ export declare function createCombinedSignal(signal?: AbortSignal, timeoutMs?: number): {
17
+ signal?: AbortSignal;
18
+ cleanup?: () => void;
19
+ };
20
+ /**
21
+ * SSE (Server-Sent Events) line parser that correctly handles events
22
+ * split across multiple TCP chunks.
23
+ *
24
+ * The naive approach of `chunk.split('\n').filter(l => l.startsWith('data: '))`
25
+ * silently drops events when an SSE line spans two chunks:
26
+ * Chunk 1: `data: {"choices":[{"delta":{"content":"don'` (no newline — incomplete)
27
+ * Chunk 2: `t do that"}}]}\n` (doesn't start with `data: `)
28
+ * Result: the entire event is lost, causing "skipped words" in output.
29
+ *
30
+ * This parser buffers partial lines and only yields complete `data: ...` lines.
31
+ */
32
+ export declare class SSELineParser {
33
+ private buffer;
34
+ /**
35
+ * Feed a raw chunk from the stream reader and get back complete SSE data lines.
36
+ * Each returned string is the content after `data: ` (e.g. the JSON payload or `[DONE]`).
37
+ */
38
+ feed(chunk: string): string[];
39
+ /**
40
+ * Flush any remaining buffered content (call when stream ends).
41
+ */
42
+ flush(): string[];
43
+ }
44
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/providers/utils.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAO9E;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,CAAC,EAAE,WAAW,EACpB,SAAS,CAAC,EAAE,MAAM,GACjB;IAAE,MAAM,CAAC,EAAE,WAAW,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,CA8BhD;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAc;IAE5B;;;OAGG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IAmB7B;;OAEG;IACH,KAAK,IAAI,MAAM,EAAE;CASlB"}