@animalabs/membrane 0.5.43 → 0.5.45

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 (38) hide show
  1. package/dist/formatters/index.d.ts +1 -0
  2. package/dist/formatters/index.js +1 -0
  3. package/dist/formatters/index.js.map +1 -1
  4. package/dist/formatters/pseudo-prefill.d.ts +71 -0
  5. package/dist/formatters/pseudo-prefill.d.ts.map +1 -0
  6. package/dist/formatters/pseudo-prefill.js +410 -0
  7. package/dist/formatters/pseudo-prefill.js.map +1 -0
  8. package/dist/formatters/types.d.ts +4 -0
  9. package/dist/membrane.d.ts.map +1 -1
  10. package/dist/membrane.js +6 -1
  11. package/dist/membrane.js.map +1 -1
  12. package/dist/providers/bedrock.d.ts.map +1 -1
  13. package/dist/providers/bedrock.js +33 -5
  14. package/dist/providers/bedrock.js.map +1 -1
  15. package/dist/providers/gemini.js +2 -11
  16. package/dist/providers/gemini.js.map +1 -1
  17. package/dist/providers/openai-compatible.js +15 -25
  18. package/dist/providers/openai-compatible.js.map +1 -1
  19. package/dist/providers/openai-completions.js +24 -48
  20. package/dist/providers/openai-completions.js.map +1 -1
  21. package/dist/providers/openai-responses.js +1 -6
  22. package/dist/providers/openai-responses.js.map +1 -1
  23. package/dist/providers/openai.js +15 -25
  24. package/dist/providers/openai.js.map +1 -1
  25. package/dist/providers/openrouter.js +16 -35
  26. package/dist/providers/openrouter.js.map +1 -1
  27. package/dist/providers/utils.d.ts +0 -38
  28. package/dist/providers/utils.d.ts.map +1 -1
  29. package/dist/providers/utils.js +0 -86
  30. package/dist/providers/utils.js.map +1 -1
  31. package/dist/transforms/prefill.d.ts.map +1 -1
  32. package/dist/transforms/prefill.js +44 -45
  33. package/dist/transforms/prefill.js.map +1 -1
  34. package/dist/types/request.d.ts +0 -8
  35. package/dist/types/request.d.ts.map +1 -1
  36. package/package.json +1 -1
  37. package/src/membrane.ts +6 -1
  38. package/src/providers/bedrock.ts +40 -3
@@ -533,8 +533,9 @@ export class BedrockAdapter implements ProviderAdapter {
533
533
  const payloadEnd = totalLength - 4;
534
534
  const payloadBytes = buffer.slice(payloadStart, payloadEnd);
535
535
 
536
- // Parse headers to find event type
536
+ // Parse headers to find event type and exception type
537
537
  let eventType = '';
538
+ let exceptionType = '';
538
539
  let headerOffset = 12;
539
540
  const headerEnd = 12 + headersLength;
540
541
  while (headerOffset < headerEnd) {
@@ -554,6 +555,8 @@ export class BedrockAdapter implements ProviderAdapter {
554
555
 
555
556
  if (name === ':event-type') {
556
557
  eventType = value;
558
+ } else if (name === ':exception-type') {
559
+ exceptionType = value;
557
560
  }
558
561
  } else {
559
562
  // Skip other header types
@@ -561,6 +564,21 @@ export class BedrockAdapter implements ProviderAdapter {
561
564
  }
562
565
  }
563
566
 
567
+ // Handle exception events from Bedrock (throttling, model errors, etc.)
568
+ if (exceptionType) {
569
+ let errorMessage = exceptionType;
570
+ try {
571
+ const exPayload = JSON.parse(new TextDecoder().decode(payloadBytes));
572
+ errorMessage = exPayload.message || exPayload.Message || exceptionType;
573
+ } catch {
574
+ // Use exception type as message
575
+ }
576
+ throw new BedrockError(
577
+ exceptionType.toLowerCase().includes('throttl') ? 429 : 500,
578
+ `Bedrock stream error (${exceptionType}): ${errorMessage}`
579
+ );
580
+ }
581
+
564
582
  // Parse the JSON payload
565
583
  if (eventType === 'chunk' && payloadBytes.length > 0) {
566
584
  try {
@@ -575,6 +593,14 @@ export class BedrockAdapter implements ProviderAdapter {
575
593
  }
576
594
  const eventData = JSON.parse(new TextDecoder().decode(bytes)) as BedrockStreamEvent;
577
595
 
596
+ // Check for error events within the stream
597
+ if (eventData.type === 'error') {
598
+ throw new BedrockError(
599
+ 500,
600
+ `Bedrock stream error: ${(eventData as any).error?.message || JSON.stringify(eventData)}`
601
+ );
602
+ }
603
+
578
604
  if (eventData.type === 'message_start' && eventData.message) {
579
605
  inputTokens = eventData.message.usage?.input_tokens ?? 0;
580
606
  } else if (eventData.type === 'content_block_start') {
@@ -607,8 +633,11 @@ export class BedrockAdapter implements ProviderAdapter {
607
633
  }
608
634
  }
609
635
  }
610
- } catch {
611
- // Skip malformed events
636
+ } catch (e) {
637
+ // Re-throw BedrockErrors (from error events above)
638
+ if (e instanceof BedrockError) throw e;
639
+ // Skip genuinely malformed events (e.g. truncated JSON)
640
+ console.warn('[membrane:bedrock] Skipping malformed stream event:', e);
612
641
  }
613
642
  }
614
643
 
@@ -620,6 +649,14 @@ export class BedrockAdapter implements ProviderAdapter {
620
649
  reader.releaseLock();
621
650
  }
622
651
 
652
+ // Detect empty responses — Bedrock returned no content and no tokens
653
+ if (contentBlocks.length === 0 && inputTokens === 0 && outputTokens === 0) {
654
+ throw new BedrockError(
655
+ 500,
656
+ 'Bedrock returned empty response: no content blocks, 0 input/output tokens. This may indicate a transient service issue.'
657
+ );
658
+ }
659
+
623
660
  // Build response from accumulated data
624
661
  finalMessage = {
625
662
  id: 'msg_stream',