@omnicross/core 0.1.9 → 0.2.0

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 (176) hide show
  1. package/LICENSE +21 -21
  2. package/NOTICE +57 -57
  3. package/README.md +22 -15
  4. package/dist/{CompletionService-kNA17cfI.d.cts → CompletionService-BiJqftc-.d.cts} +1 -1
  5. package/dist/{CompletionService-C3BX0Ovy.d.ts → CompletionService-NXN_Av5W.d.ts} +1 -1
  6. package/dist/{ProviderProxy-QdwNV6l1.d.cts → ProviderProxy-CgIcCVwk.d.cts} +1 -1
  7. package/dist/{ProviderProxy--ROec6VI.d.ts → ProviderProxy-DYoY5XoT.d.ts} +1 -1
  8. package/dist/auth/GeminiCodeAssistProjectResolver.cjs +6 -6
  9. package/dist/auth/GeminiCodeAssistProjectResolver.js +4 -4
  10. package/dist/chunk-32SRZFFP.cjs +153 -0
  11. package/dist/chunk-4JOU54M5.js +200 -0
  12. package/dist/{chunk-2UTGX6FM.js → chunk-4VVCXVB7.js} +1 -1
  13. package/dist/{chunk-EPN67EGP.cjs → chunk-5UK3KLE2.cjs} +9 -1
  14. package/dist/chunk-6DDYNS2B.cjs +384 -0
  15. package/dist/{chunk-HKB656B4.js → chunk-6OC3ORW6.js} +55 -287
  16. package/dist/chunk-6OKXH2TW.js +320 -0
  17. package/dist/{chunk-XELFM7KL.cjs → chunk-7B56AJBB.cjs} +6275 -2421
  18. package/dist/{chunk-YWL7YZWS.cjs → chunk-7LRTPNFL.cjs} +5 -0
  19. package/dist/{chunk-CCVRRJOX.js → chunk-7PIUVCKK.js} +9 -2
  20. package/dist/{chunk-IIRPUVPH.cjs → chunk-7ZHBN75N.cjs} +3 -1
  21. package/dist/{chunk-UAPBLNN2.js → chunk-AQDON6MB.js} +8 -0
  22. package/dist/{chunk-RJ5ZGNI3.js → chunk-CFSGYFOZ.js} +1 -1
  23. package/dist/chunk-CTKM773J.cjs +3919 -0
  24. package/dist/chunk-DEIUR2TH.js +3919 -0
  25. package/dist/{chunk-WNKWAEUR.js → chunk-EYGBM2VC.js} +3 -1
  26. package/dist/{chunk-NGYOO5TO.js → chunk-FJNKXOWE.js} +9 -9
  27. package/dist/chunk-FX325I5Q.cjs +320 -0
  28. package/dist/chunk-G4CZIUIB.cjs +200 -0
  29. package/dist/chunk-HCOQQAZE.cjs +123 -0
  30. package/dist/{chunk-55FMGZ3L.js → chunk-HN74IGEO.js} +1 -1
  31. package/dist/{chunk-ZY6KU6P3.js → chunk-HOMUGKHR.js} +8 -5
  32. package/dist/{chunk-AOFWNWLT.cjs → chunk-IUL4VWNU.cjs} +22 -1
  33. package/dist/{chunk-5LNYGCIW.cjs → chunk-KIQ2HA2A.cjs} +5 -5
  34. package/dist/{chunk-MUHWHQVM.cjs → chunk-KQBLZMP6.cjs} +4 -3
  35. package/dist/chunk-LFEH7CEO.js +384 -0
  36. package/dist/chunk-N76KU6F5.js +123 -0
  37. package/dist/{chunk-CMVXX7ON.cjs → chunk-NOITAVHA.cjs} +114 -58
  38. package/dist/{chunk-Q27JY5RG.cjs → chunk-OIKREZVQ.cjs} +7 -4
  39. package/dist/{chunk-RJUONLUQ.cjs → chunk-OST5RJOJ.cjs} +1 -1
  40. package/dist/chunk-QIIAMBTM.js +153 -0
  41. package/dist/{chunk-56QD3YW6.cjs → chunk-QWNUOR7F.cjs} +11 -4
  42. package/dist/{chunk-S3DYFEBE.js → chunk-R4VCO2CB.js} +10 -1
  43. package/dist/{chunk-ZQQUD66M.cjs → chunk-SQMAEDNE.cjs} +63 -295
  44. package/dist/{chunk-4VZX5F4T.cjs → chunk-T6NWPIYZ.cjs} +5 -2
  45. package/dist/{chunk-P7EM6BND.cjs → chunk-TVYA5JSQ.cjs} +10 -10
  46. package/dist/{chunk-EBLFCNPY.js → chunk-U47LQXPB.js} +5 -2
  47. package/dist/{chunk-N7OOJI5V.js → chunk-V2UKUTJ3.js} +5 -0
  48. package/dist/{chunk-45FHEOKW.js → chunk-V53ZEFXC.js} +92 -36
  49. package/dist/{chunk-OC6DOOFX.cjs → chunk-VXRTQZF2.cjs} +5 -5
  50. package/dist/{chunk-CQIJCPMF.js → chunk-WSJE42SG.js} +5149 -1295
  51. package/dist/{chunk-RICPANBY.cjs → chunk-WX2E2G7H.cjs} +13 -4
  52. package/dist/{chunk-DE2SRBFZ.js → chunk-X335TJNS.js} +4 -3
  53. package/dist/{chunk-N2EIM2XJ.js → chunk-ZLNHPUFA.js} +22 -1
  54. package/dist/completion/CompletionService.cjs +30 -27
  55. package/dist/completion/CompletionService.d.cts +3 -2
  56. package/dist/completion/CompletionService.d.ts +3 -2
  57. package/dist/completion/CompletionService.js +29 -26
  58. package/dist/completion.cjs +38 -35
  59. package/dist/completion.d.cts +3 -2
  60. package/dist/completion.d.ts +3 -2
  61. package/dist/completion.js +37 -34
  62. package/dist/image-generation.cjs +52 -0
  63. package/dist/image-generation.d.cts +93 -0
  64. package/dist/image-generation.d.ts +93 -0
  65. package/dist/image-generation.js +52 -0
  66. package/dist/index.cjs +126 -31
  67. package/dist/index.d.cts +11 -7
  68. package/dist/index.d.ts +11 -7
  69. package/dist/index.js +143 -48
  70. package/dist/openai-operation.cjs +18 -0
  71. package/dist/openai-operation.d.cts +19 -0
  72. package/dist/openai-operation.d.ts +19 -0
  73. package/dist/openai-operation.js +18 -0
  74. package/dist/outbound-api/auditCapture.cjs +3 -3
  75. package/dist/outbound-api/auditCapture.d.cts +19 -2
  76. package/dist/outbound-api/auditCapture.d.ts +19 -2
  77. package/dist/outbound-api/auditCapture.js +2 -2
  78. package/dist/outbound-api/auditRedact.cjs +2 -2
  79. package/dist/outbound-api/auditRedact.js +1 -1
  80. package/dist/outbound-api/routeResolver.cjs +2 -2
  81. package/dist/outbound-api/routeResolver.d.cts +7 -4
  82. package/dist/outbound-api/routeResolver.d.ts +7 -4
  83. package/dist/outbound-api/routeResolver.js +1 -1
  84. package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -1
  85. package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -1
  86. package/dist/outbound-api/types.d.cts +6 -3
  87. package/dist/outbound-api/types.d.ts +6 -3
  88. package/dist/outbound-api.cjs +49 -32
  89. package/dist/outbound-api.d.cts +97 -10
  90. package/dist/outbound-api.d.ts +97 -10
  91. package/dist/outbound-api.js +48 -31
  92. package/dist/pipeline/AccountAllowanceScheduling.d.cts +18 -15
  93. package/dist/pipeline/AccountAllowanceScheduling.d.ts +18 -15
  94. package/dist/pipeline/LlmConfigProviderAuth.cjs +3 -3
  95. package/dist/pipeline/LlmConfigProviderAuth.js +2 -2
  96. package/dist/pipeline/SubscriptionAccountHealth.cjs +2 -2
  97. package/dist/pipeline/SubscriptionAccountHealth.d.cts +7 -0
  98. package/dist/pipeline/SubscriptionAccountHealth.d.ts +7 -0
  99. package/dist/pipeline/SubscriptionAccountHealth.js +1 -1
  100. package/dist/pipeline/executeProviderCall.cjs +2 -2
  101. package/dist/pipeline/executeProviderCall.d.cts +11 -6
  102. package/dist/pipeline/executeProviderCall.d.ts +11 -6
  103. package/dist/pipeline/executeProviderCall.js +1 -1
  104. package/dist/pipeline/upstreamFetch.cjs +2 -2
  105. package/dist/pipeline/upstreamFetch.d.cts +5 -0
  106. package/dist/pipeline/upstreamFetch.d.ts +5 -0
  107. package/dist/pipeline/upstreamFetch.js +1 -1
  108. package/dist/ports.d.cts +6 -3
  109. package/dist/ports.d.ts +6 -3
  110. package/dist/provider-proxy/ProviderProxy.cjs +30 -27
  111. package/dist/provider-proxy/ProviderProxy.d.cts +3 -2
  112. package/dist/provider-proxy/ProviderProxy.d.ts +3 -2
  113. package/dist/provider-proxy/ProviderProxy.js +29 -26
  114. package/dist/provider-proxy/identity/codexCliHeaders.cjs +4 -2
  115. package/dist/provider-proxy/identity/codexCliHeaders.d.cts +26 -6
  116. package/dist/provider-proxy/identity/codexCliHeaders.d.ts +26 -6
  117. package/dist/provider-proxy/identity/codexCliHeaders.js +5 -3
  118. package/dist/provider-proxy/ingress/providerProxyShared.cjs +32 -27
  119. package/dist/provider-proxy/ingress/providerProxyShared.d.cts +21 -8
  120. package/dist/provider-proxy/ingress/providerProxyShared.d.ts +21 -8
  121. package/dist/provider-proxy/ingress/providerProxyShared.js +31 -26
  122. package/dist/provider-proxy/types.d.cts +14 -483
  123. package/dist/provider-proxy/types.d.ts +14 -483
  124. package/dist/provider-proxy.cjs +44 -27
  125. package/dist/provider-proxy.d.cts +30 -8
  126. package/dist/provider-proxy.d.ts +30 -8
  127. package/dist/provider-proxy.js +43 -26
  128. package/dist/{routeResolver-C0mkkZaM.d.ts → routeResolver-CTCcSHWu.d.ts} +4 -2
  129. package/dist/{routeResolver-CVFE8KKe.d.cts → routeResolver-rpKQLyDO.d.cts} +4 -2
  130. package/dist/transformer/TransformerChainExecutor.cjs +2 -2
  131. package/dist/transformer/TransformerChainExecutor.d.cts +2 -2
  132. package/dist/transformer/TransformerChainExecutor.d.ts +2 -2
  133. package/dist/transformer/TransformerChainExecutor.js +1 -1
  134. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.cjs +16 -0
  135. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.cts +53 -0
  136. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.d.ts +53 -0
  137. package/dist/transformer/transformers/AnthropicOpenAIToAnthropicStream.js +16 -0
  138. package/dist/transformer/transformers/AnthropicTransformer.cjs +4 -3
  139. package/dist/transformer/transformers/AnthropicTransformer.js +3 -2
  140. package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -4
  141. package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +3 -3
  142. package/dist/transformer/transformers/GeminiTransformer.cjs +4 -4
  143. package/dist/transformer/transformers/GeminiTransformer.js +3 -3
  144. package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -3
  145. package/dist/transformer/transformers/OpenAIResponseTransformer.js +2 -2
  146. package/dist/transformer/transformers/OpenAITransformer.cjs +3 -3
  147. package/dist/transformer/transformers/OpenAITransformer.js +2 -2
  148. package/dist/transformer/transformers.cjs +10 -9
  149. package/dist/transformer/transformers.js +13 -12
  150. package/dist/transformer/types.d.cts +39 -4
  151. package/dist/transformer/types.d.ts +39 -4
  152. package/dist/transformer.cjs +14 -13
  153. package/dist/transformer.js +14 -13
  154. package/dist/{types-BB8pxk_3.d.ts → types-5T223WYQ.d.ts} +183 -23
  155. package/dist/types-Bd72H4SB.d.ts +196 -0
  156. package/dist/types-CVRge76p.d.ts +1115 -0
  157. package/dist/types-CbglB73l.d.cts +196 -0
  158. package/dist/types-DsHBBk3h.d.cts +1115 -0
  159. package/dist/{types-C2MwkLah.d.cts → types-jjU24eYG.d.cts} +183 -23
  160. package/dist/usage/usage-recorder.cjs +2 -2
  161. package/dist/usage/usage-recorder.d.cts +12 -2
  162. package/dist/usage/usage-recorder.d.ts +12 -2
  163. package/dist/usage/usage-recorder.js +1 -1
  164. package/dist/usage.cjs +20 -3
  165. package/dist/usage.d.cts +154 -0
  166. package/dist/usage.d.ts +154 -0
  167. package/dist/usage.js +20 -3
  168. package/package.json +69 -64
  169. package/dist/chunk-7C7DET6S.js +0 -154
  170. package/dist/chunk-7VU7V2E4.js +0 -0
  171. package/dist/chunk-EYZYXJTJ.cjs +0 -1
  172. package/dist/chunk-FCR77GYM.cjs +0 -33
  173. package/dist/chunk-K5NM7VAH.js +0 -33
  174. package/dist/chunk-XPIOJQS2.cjs +0 -154
  175. /package/dist/{chunk-XXFYLL7R.js → chunk-ECZ3ZE2C.js} +0 -0
  176. /package/dist/{chunk-3SCOLIPT.cjs → chunk-MXI2PWIC.cjs} +0 -0
@@ -1,6 +1,9 @@
1
1
  import {
2
2
  anthropicUsageToChatUsage
3
3
  } from "./chunk-FU7EAR73.js";
4
+ import {
5
+ convertOpenAIStreamToAnthropic
6
+ } from "./chunk-LFEH7CEO.js";
4
7
  import {
5
8
  flattenToolResultContent,
6
9
  formatBase64,
@@ -9,8 +12,9 @@ import {
9
12
  import {
10
13
  extractReasoningIntent,
11
14
  normalizeThinkLevel,
15
+ recordDroppedField,
12
16
  resolveReasoningPlan
13
- } from "./chunk-N2EIM2XJ.js";
17
+ } from "./chunk-ZLNHPUFA.js";
14
18
 
15
19
  // src/transformer/transformers/AnthropicToolHandling.ts
16
20
  function isServerSideTool(tool) {
@@ -155,6 +159,14 @@ function buildAnthropicRequestBody(request, provider) {
155
159
  if (request.temperature !== void 0) {
156
160
  body.temperature = request.temperature;
157
161
  }
162
+ if (request.stop !== void 0 && request.stop.length > 0) {
163
+ body.stop_sequences = request.stop;
164
+ }
165
+ if (request.top_p !== void 0) body.top_p = request.top_p;
166
+ if (request.top_k !== void 0) body.top_k = request.top_k;
167
+ if (request.metadata_user_id !== void 0) {
168
+ body.metadata = { user_id: request.metadata_user_id };
169
+ }
158
170
  if (systemContent !== void 0) {
159
171
  body.system = systemContent;
160
172
  }
@@ -325,6 +337,7 @@ function convertOpenAIResponseToAnthropic(openaiResponse) {
325
337
  function transformAnthropicRequestToUnified(request) {
326
338
  const anthropicRequest = request;
327
339
  const messages = [];
340
+ let redactedSeen = false;
328
341
  if (anthropicRequest.system) {
329
342
  if (typeof anthropicRequest.system === "string") {
330
343
  messages.push({
@@ -419,15 +432,40 @@ function transformAnthropicRequestToUnified(request) {
419
432
  }
420
433
  }));
421
434
  }
422
- const thinkingPart = msg.content.find(
423
- (c) => c.type === "thinking"
424
- );
425
- if (thinkingPart?.thinking) {
435
+ let thinkingText = "";
436
+ let firstSignature;
437
+ let sawRedacted = false;
438
+ for (const block of msg.content) {
439
+ if (block.type === "thinking") {
440
+ const t = block.thinking;
441
+ if (typeof t === "string" && t.length > 0) {
442
+ if (thinkingText.length > 0) thinkingText += "\n";
443
+ thinkingText += t;
444
+ }
445
+ const signature = block.signature;
446
+ if (signature) {
447
+ if (firstSignature === void 0) {
448
+ firstSignature = signature;
449
+ } else if (typeof t === "string" && t.length > 0) {
450
+ thinkingText += `
451
+ [signature: ${signature}]`;
452
+ }
453
+ }
454
+ } else if (block.type === "redacted_thinking") {
455
+ sawRedacted = true;
456
+ if (thinkingText.length > 0) thinkingText += "\n";
457
+ thinkingText += "[redacted thinking omitted]";
458
+ }
459
+ }
460
+ if (thinkingText.length > 0) {
426
461
  assistantMessage.thinking = {
427
- content: thinkingPart.thinking,
428
- signature: thinkingPart.signature
462
+ content: thinkingText,
463
+ signature: firstSignature
429
464
  };
430
465
  }
466
+ if (sawRedacted) {
467
+ redactedSeen = true;
468
+ }
431
469
  messages.push(assistantMessage);
432
470
  }
433
471
  }
@@ -443,6 +481,16 @@ function transformAnthropicRequestToUnified(request) {
443
481
  stream: anthropicRequest.stream,
444
482
  tools: functionTools?.length ? functionTools : void 0
445
483
  };
484
+ const raw = anthropicRequest;
485
+ if (Array.isArray(raw.stop_sequences)) {
486
+ result.stop = raw.stop_sequences.filter((s) => typeof s === "string");
487
+ }
488
+ if (typeof raw.top_p === "number") result.top_p = raw.top_p;
489
+ if (typeof raw.top_k === "number") result.top_k = raw.top_k;
490
+ if (typeof raw.metadata?.user_id === "string") result.metadata_user_id = raw.metadata.user_id;
491
+ if (redactedSeen) {
492
+ recordDroppedField(result, "redacted_thinking", "unified");
493
+ }
446
494
  if (serverSideTools.length > 0) {
447
495
  result._serverSideTools = serverSideTools;
448
496
  }
@@ -644,286 +692,6 @@ ${formatted}` },
644
692
  });
645
693
  }
646
694
 
647
- // src/transformer/transformers/AnthropicOpenAIToAnthropicStream.ts
648
- function convertOpenAIStreamToAnthropic(openaiStream, _context, logger) {
649
- const decoder = new TextDecoder();
650
- const encoder = new TextEncoder();
651
- let hasStarted = false;
652
- let hasTextContentStarted = false;
653
- let isThinkingStarted = false;
654
- let contentIndex = 0;
655
- let currentContentBlockIndex = -1;
656
- const toolCallIndexToContentBlockIndex = /* @__PURE__ */ new Map();
657
- return new ReadableStream({
658
- start: async (controller) => {
659
- const reader = openaiStream.getReader();
660
- let buffer = "";
661
- const messageId = `msg_${Date.now()}`;
662
- let model = "unknown";
663
- let isClosed = false;
664
- let stopReasonDelta = null;
665
- const safeEnqueue = (data) => {
666
- if (!isClosed) {
667
- try {
668
- controller.enqueue(encoder.encode(data));
669
- } catch (_e) {
670
- isClosed = true;
671
- }
672
- }
673
- };
674
- const assignContentBlockIndex = () => {
675
- return contentIndex++;
676
- };
677
- const safeClose = () => {
678
- if (isClosed) return;
679
- if (currentContentBlockIndex >= 0) {
680
- safeEnqueue(`event: content_block_stop
681
- data: ${JSON.stringify({
682
- type: "content_block_stop",
683
- index: currentContentBlockIndex
684
- })}
685
-
686
- `);
687
- }
688
- if (stopReasonDelta) {
689
- safeEnqueue(`event: message_delta
690
- data: ${JSON.stringify(stopReasonDelta)}
691
-
692
- `);
693
- } else {
694
- safeEnqueue(`event: message_delta
695
- data: ${JSON.stringify({
696
- type: "message_delta",
697
- delta: { stop_reason: "end_turn", stop_sequence: null },
698
- usage: { input_tokens: 0, output_tokens: 0 }
699
- })}
700
-
701
- `);
702
- }
703
- safeEnqueue(`event: message_stop
704
- data: ${JSON.stringify({ type: "message_stop" })}
705
-
706
- `);
707
- try {
708
- controller.close();
709
- } catch (_e) {
710
- }
711
- isClosed = true;
712
- };
713
- try {
714
- while (true) {
715
- const { done, value } = await reader.read();
716
- if (done) break;
717
- buffer += decoder.decode(value, { stream: true });
718
- const lines = buffer.split("\n");
719
- buffer = lines.pop() || "";
720
- for (const line of lines) {
721
- if (isClosed) break;
722
- if (!line.startsWith("data:")) continue;
723
- const data = line.slice(5).trim();
724
- if (data === "[DONE]") continue;
725
- try {
726
- const chunk = JSON.parse(data);
727
- if (chunk.error) {
728
- safeEnqueue(`event: error
729
- data: ${JSON.stringify({
730
- type: "error",
731
- message: { type: "api_error", message: JSON.stringify(chunk.error) }
732
- })}
733
-
734
- `);
735
- continue;
736
- }
737
- model = chunk.model || model;
738
- if (!hasStarted) {
739
- hasStarted = true;
740
- safeEnqueue(`event: message_start
741
- data: ${JSON.stringify({
742
- type: "message_start",
743
- message: {
744
- id: messageId,
745
- type: "message",
746
- role: "assistant",
747
- content: [],
748
- model,
749
- stop_reason: null,
750
- stop_sequence: null,
751
- usage: { input_tokens: 0, output_tokens: 0 }
752
- }
753
- })}
754
-
755
- `);
756
- }
757
- const choice = chunk.choices?.[0];
758
- if (!choice) continue;
759
- if (chunk.usage) {
760
- stopReasonDelta = {
761
- type: "message_delta",
762
- delta: { stop_reason: "end_turn", stop_sequence: null },
763
- usage: {
764
- input_tokens: (chunk.usage.prompt_tokens || 0) - (chunk.usage.prompt_tokens_details?.cached_tokens || 0),
765
- output_tokens: chunk.usage.completion_tokens || 0,
766
- cache_read_input_tokens: chunk.usage.prompt_tokens_details?.cached_tokens || 0
767
- }
768
- };
769
- }
770
- if (choice.delta?.thinking) {
771
- if (!isThinkingStarted) {
772
- const thinkingBlockIndex = assignContentBlockIndex();
773
- safeEnqueue(`event: content_block_start
774
- data: ${JSON.stringify({
775
- type: "content_block_start",
776
- index: thinkingBlockIndex,
777
- content_block: { type: "thinking", thinking: "" }
778
- })}
779
-
780
- `);
781
- currentContentBlockIndex = thinkingBlockIndex;
782
- isThinkingStarted = true;
783
- }
784
- if (choice.delta.thinking.signature) {
785
- safeEnqueue(`event: content_block_delta
786
- data: ${JSON.stringify({
787
- type: "content_block_delta",
788
- index: currentContentBlockIndex,
789
- delta: { type: "signature_delta", signature: choice.delta.thinking.signature }
790
- })}
791
-
792
- `);
793
- safeEnqueue(`event: content_block_stop
794
- data: ${JSON.stringify({
795
- type: "content_block_stop",
796
- index: currentContentBlockIndex
797
- })}
798
-
799
- `);
800
- currentContentBlockIndex = -1;
801
- } else if (choice.delta.thinking.content) {
802
- safeEnqueue(`event: content_block_delta
803
- data: ${JSON.stringify({
804
- type: "content_block_delta",
805
- index: currentContentBlockIndex,
806
- delta: { type: "thinking_delta", thinking: choice.delta.thinking.content }
807
- })}
808
-
809
- `);
810
- }
811
- }
812
- if (choice.delta?.content) {
813
- if (!hasTextContentStarted) {
814
- if (currentContentBlockIndex >= 0 && isThinkingStarted) {
815
- safeEnqueue(`event: content_block_stop
816
- data: ${JSON.stringify({
817
- type: "content_block_stop",
818
- index: currentContentBlockIndex
819
- })}
820
-
821
- `);
822
- }
823
- hasTextContentStarted = true;
824
- const textBlockIndex = assignContentBlockIndex();
825
- safeEnqueue(`event: content_block_start
826
- data: ${JSON.stringify({
827
- type: "content_block_start",
828
- index: textBlockIndex,
829
- content_block: { type: "text", text: "" }
830
- })}
831
-
832
- `);
833
- currentContentBlockIndex = textBlockIndex;
834
- }
835
- safeEnqueue(`event: content_block_delta
836
- data: ${JSON.stringify({
837
- type: "content_block_delta",
838
- index: currentContentBlockIndex,
839
- delta: { type: "text_delta", text: choice.delta.content }
840
- })}
841
-
842
- `);
843
- }
844
- if (choice.delta?.tool_calls) {
845
- for (const toolCall of choice.delta.tool_calls) {
846
- const toolCallIndex = toolCall.index ?? 0;
847
- if (!toolCallIndexToContentBlockIndex.has(toolCallIndex)) {
848
- if (currentContentBlockIndex >= 0) {
849
- safeEnqueue(`event: content_block_stop
850
- data: ${JSON.stringify({
851
- type: "content_block_stop",
852
- index: currentContentBlockIndex
853
- })}
854
-
855
- `);
856
- hasTextContentStarted = false;
857
- }
858
- const newBlockIndex = assignContentBlockIndex();
859
- toolCallIndexToContentBlockIndex.set(toolCallIndex, newBlockIndex);
860
- safeEnqueue(`event: content_block_start
861
- data: ${JSON.stringify({
862
- type: "content_block_start",
863
- index: newBlockIndex,
864
- content_block: {
865
- type: "tool_use",
866
- id: toolCall.id || `call_${Date.now()}_${toolCallIndex}`,
867
- name: toolCall.function?.name || `tool_${toolCallIndex}`,
868
- input: {}
869
- }
870
- })}
871
-
872
- `);
873
- currentContentBlockIndex = newBlockIndex;
874
- }
875
- if (toolCall.function?.arguments) {
876
- const blockIndex = toolCallIndexToContentBlockIndex.get(toolCallIndex);
877
- if (blockIndex !== void 0) {
878
- safeEnqueue(`event: content_block_delta
879
- data: ${JSON.stringify({
880
- type: "content_block_delta",
881
- index: blockIndex,
882
- delta: { type: "input_json_delta", partial_json: toolCall.function.arguments }
883
- })}
884
-
885
- `);
886
- }
887
- }
888
- }
889
- }
890
- if (choice.finish_reason) {
891
- const stopReasonMapping = {
892
- stop: "end_turn",
893
- length: "max_tokens",
894
- tool_calls: "tool_use",
895
- content_filter: "stop_sequence"
896
- };
897
- stopReasonDelta = {
898
- type: "message_delta",
899
- delta: {
900
- stop_reason: stopReasonMapping[choice.finish_reason] || "end_turn",
901
- stop_sequence: null
902
- },
903
- usage: {
904
- input_tokens: (chunk.usage?.prompt_tokens || 0) - (chunk.usage?.prompt_tokens_details?.cached_tokens || 0),
905
- output_tokens: chunk.usage?.completion_tokens || 0,
906
- cache_read_input_tokens: chunk.usage?.prompt_tokens_details?.cached_tokens || 0
907
- }
908
- };
909
- }
910
- } catch (e) {
911
- logger?.error("Error parsing stream chunk:", e);
912
- }
913
- }
914
- }
915
- } catch (e) {
916
- if (!isClosed) {
917
- controller.error(e);
918
- }
919
- } finally {
920
- safeClose();
921
- reader.releaseLock();
922
- }
923
- }
924
- });
925
- }
926
-
927
695
  // src/transformer/transformers/AnthropicTransformer.ts
928
696
  var AnthropicTransformer = class {
929
697
  static TransformerName = "anthropic";
@@ -0,0 +1,320 @@
1
+ import {
2
+ getAuditCaptureConfig,
3
+ recordAudit
4
+ } from "./chunk-WNY4WMRF.js";
5
+ import {
6
+ redactAuditText
7
+ } from "./chunk-N76KU6F5.js";
8
+ import {
9
+ readAuditUsage
10
+ } from "./chunk-OZFM4X3S.js";
11
+
12
+ // src/outbound-api/auditCapture.ts
13
+ import { randomUUID } from "crypto";
14
+
15
+ // src/outbound-api/auditSseCompact.ts
16
+ var MERGED_FRAMES_FIELD = "_omnicrossMergedFrames";
17
+ function asObject(value) {
18
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
19
+ }
20
+ function scalar(value) {
21
+ return typeof value === "string" || typeof value === "number" ? String(value) : "";
22
+ }
23
+ function classify(payload) {
24
+ const type = scalar(payload["type"]);
25
+ if (type === "content_block_delta") {
26
+ const delta = asObject(payload["delta"]);
27
+ const deltaType = scalar(delta?.["type"]);
28
+ const field = deltaType === "text_delta" ? "text" : deltaType === "thinking_delta" ? "thinking" : deltaType === "input_json_delta" ? "partial_json" : null;
29
+ if (!delta || !field || typeof delta[field] !== "string") return null;
30
+ return {
31
+ channel: "anthropic:" + scalar(payload["index"]) + ":" + deltaType,
32
+ text: delta[field],
33
+ payload,
34
+ textPath: ["delta", field]
35
+ };
36
+ }
37
+ if (type.endsWith(".delta") && typeof payload["delta"] === "string") {
38
+ const channel = [
39
+ "responses",
40
+ type,
41
+ scalar(payload["item_id"]),
42
+ scalar(payload["output_index"]),
43
+ scalar(payload["content_index"])
44
+ ].join(":");
45
+ return { channel, text: payload["delta"], payload, textPath: ["delta"] };
46
+ }
47
+ const choices = payload["choices"];
48
+ if (Array.isArray(choices) && choices.length === 1) {
49
+ const choice = asObject(choices[0]);
50
+ const delta = asObject(choice?.["delta"]);
51
+ if (choice && delta && typeof delta["content"] === "string" && choice["finish_reason"] == null && delta["tool_calls"] === void 0 && delta["function_call"] === void 0) {
52
+ return {
53
+ channel: "chat:" + scalar(choice["index"]),
54
+ text: delta["content"],
55
+ payload,
56
+ textPath: ["choices", "0", "delta", "content"]
57
+ };
58
+ }
59
+ }
60
+ return null;
61
+ }
62
+ function withMergedText(frame, text, mergedCount) {
63
+ const clone = JSON.parse(JSON.stringify(frame.payload));
64
+ let cursor = clone;
65
+ for (let i = 0; i < frame.textPath.length - 1; i += 1) {
66
+ const step = frame.textPath[i];
67
+ const next = Array.isArray(cursor) ? cursor[Number(step)] : cursor[step];
68
+ if (next === null || typeof next !== "object") return clone;
69
+ cursor = next;
70
+ }
71
+ const leaf = frame.textPath[frame.textPath.length - 1];
72
+ if (Array.isArray(cursor)) cursor[Number(leaf)] = text;
73
+ else cursor[leaf] = text;
74
+ clone[MERGED_FRAMES_FIELD] = mergedCount;
75
+ return clone;
76
+ }
77
+ function splitBlocks(text, nl) {
78
+ const blocks = [];
79
+ let head = [];
80
+ let data = null;
81
+ let raw = [];
82
+ const flush = () => {
83
+ if (raw.length === 0) return;
84
+ blocks.push({ head, data, raw: raw.join(nl) });
85
+ head = [];
86
+ data = null;
87
+ raw = [];
88
+ };
89
+ for (const line of text.split(nl)) {
90
+ if (line.trim() === "") {
91
+ flush();
92
+ continue;
93
+ }
94
+ raw.push(line);
95
+ if (line.startsWith("data:")) {
96
+ const payload = line.slice("data:".length).trimStart();
97
+ data = data === null ? payload : data + nl + payload;
98
+ } else {
99
+ head.push(line);
100
+ }
101
+ }
102
+ flush();
103
+ return blocks;
104
+ }
105
+ function compactSseBody(text) {
106
+ if (!text || !text.includes("data:")) return text;
107
+ const nl = "\n";
108
+ const blocks = splitBlocks(text, nl);
109
+ if (blocks.length === 0) return text;
110
+ const out = [];
111
+ let runFrame = null;
112
+ let runBlock = null;
113
+ let runText = "";
114
+ let runCount = 0;
115
+ let merged = 0;
116
+ const flushRun = () => {
117
+ if (runFrame === null || runBlock === null) return;
118
+ if (runCount === 1) {
119
+ out.push(runBlock.raw);
120
+ } else {
121
+ const payload = withMergedText(runFrame, runText, runCount);
122
+ out.push([...runBlock.head, "data: " + JSON.stringify(payload)].join(nl));
123
+ merged += runCount;
124
+ }
125
+ runFrame = null;
126
+ runBlock = null;
127
+ runText = "";
128
+ runCount = 0;
129
+ };
130
+ for (const block of blocks) {
131
+ let frame = null;
132
+ if (block.data !== null && block.data !== "[DONE]") {
133
+ try {
134
+ const parsed = asObject(JSON.parse(block.data));
135
+ if (parsed) frame = classify(parsed);
136
+ } catch {
137
+ frame = null;
138
+ }
139
+ }
140
+ if (frame === null) {
141
+ flushRun();
142
+ out.push(block.raw);
143
+ continue;
144
+ }
145
+ const open = runFrame;
146
+ if (open !== null && open.channel === frame.channel) {
147
+ runText += frame.text;
148
+ runCount += 1;
149
+ continue;
150
+ }
151
+ flushRun();
152
+ runFrame = frame;
153
+ runBlock = block;
154
+ runText = frame.text;
155
+ runCount = 1;
156
+ }
157
+ flushRun();
158
+ if (merged === 0) return text;
159
+ const trailer = /\s$/.test(text) ? nl + nl : "";
160
+ return out.join(nl + nl) + trailer;
161
+ }
162
+
163
+ // src/outbound-api/auditCapture.ts
164
+ function completeUtf8PrefixLength(buf) {
165
+ if (buf.length === 0) return 0;
166
+ let leadIndex = buf.length - 1;
167
+ while (leadIndex >= 0 && (buf[leadIndex] & 192) === 128) leadIndex -= 1;
168
+ if (leadIndex < 0) return 0;
169
+ const lead = buf[leadIndex];
170
+ let expectedLength = 1;
171
+ if ((lead & 224) === 192) expectedLength = 2;
172
+ else if ((lead & 240) === 224) expectedLength = 3;
173
+ else if ((lead & 248) === 240) expectedLength = 4;
174
+ return buf.length - leadIndex < expectedLength ? leadIndex : buf.length;
175
+ }
176
+ function truncateToBytes(text, maxBytes) {
177
+ if (maxBytes < 0) return text;
178
+ const buf = Buffer.from(text, "utf8");
179
+ if (buf.length <= maxBytes) return text;
180
+ const head = buf.subarray(0, maxBytes);
181
+ return head.subarray(0, completeUtf8PrefixLength(head)).toString("utf8");
182
+ }
183
+ function decodeCapturedBody(body, truncated) {
184
+ if (!truncated) return body.toString("utf8");
185
+ return body.subarray(0, completeUtf8PrefixLength(body)).toString("utf8");
186
+ }
187
+ function resolveClientIp(req, trustForwardedFor) {
188
+ if (trustForwardedFor) {
189
+ const xff = req.headers["x-forwarded-for"];
190
+ const raw = Array.isArray(xff) ? xff[0] : xff;
191
+ if (typeof raw === "string" && raw.trim()) {
192
+ const first = raw.split(",")[0]?.trim();
193
+ if (first) return first;
194
+ }
195
+ }
196
+ return req.socket?.remoteAddress ?? void 0;
197
+ }
198
+ function beginAuditCapture(req, res, now, options) {
199
+ const config = getAuditCaptureConfig();
200
+ if (!config) return null;
201
+ const captureBodies = config.captureBodies;
202
+ let requestBody;
203
+ const responseChunks = [];
204
+ let responseBytes = 0;
205
+ let responseTruncated = false;
206
+ let bodiesSuppressed = options?.suppressBodies === true;
207
+ let finished = false;
208
+ const ctx = {
209
+ setRequestBody(raw) {
210
+ if (captureBodies && !bodiesSuppressed) {
211
+ requestBody = truncateToBytes(redactAuditText(raw), config.maxBodyBytes);
212
+ }
213
+ },
214
+ suppressBodies() {
215
+ if (bodiesSuppressed) return;
216
+ bodiesSuppressed = true;
217
+ requestBody = void 0;
218
+ responseChunks.length = 0;
219
+ responseBytes = 0;
220
+ responseTruncated = false;
221
+ }
222
+ };
223
+ if (captureBodies && !bodiesSuppressed) {
224
+ installResponseCapture(res, {
225
+ push(chunk) {
226
+ if (bodiesSuppressed) return;
227
+ if (config.maxBodyBytes < 0) {
228
+ responseChunks.push(chunk);
229
+ responseBytes += chunk.length;
230
+ return;
231
+ }
232
+ const remaining = config.maxBodyBytes - responseBytes;
233
+ if (remaining <= 0) {
234
+ responseTruncated = true;
235
+ return;
236
+ }
237
+ if (chunk.length > remaining) {
238
+ responseChunks.push(chunk.subarray(0, remaining));
239
+ responseBytes += remaining;
240
+ responseTruncated = true;
241
+ return;
242
+ }
243
+ responseChunks.push(chunk);
244
+ responseBytes += chunk.length;
245
+ }
246
+ });
247
+ }
248
+ const finalize = () => {
249
+ if (finished) return;
250
+ finished = true;
251
+ try {
252
+ const record = {
253
+ id: randomUUID(),
254
+ ts: now,
255
+ method: req.method ?? "",
256
+ path: (req.url ?? "").split("?")[0] ?? "",
257
+ status: res.statusCode,
258
+ latencyMs: Math.max(0, Date.now() - now)
259
+ };
260
+ if (ctx.keyId != null) record.keyId = ctx.keyId;
261
+ const ip = resolveClientIp(req, config.trustForwardedFor);
262
+ if (ip) record.ip = ip;
263
+ const ua = req.headers["user-agent"];
264
+ if (typeof ua === "string" && ua) record.ua = ua;
265
+ if (ctx.model) record.model = ctx.model;
266
+ if (ctx.provider) record.provider = ctx.provider;
267
+ const usage = readAuditUsage(res);
268
+ if (usage) {
269
+ if (typeof usage.inputTokens === "number") record.inputTokens = usage.inputTokens;
270
+ if (typeof usage.outputTokens === "number") record.outputTokens = usage.outputTokens;
271
+ if (typeof usage.costUsd === "number") record.costUsd = usage.costUsd;
272
+ if (!record.model && usage.model) record.model = usage.model;
273
+ if (!record.provider && usage.provider) record.provider = usage.provider;
274
+ }
275
+ if (ctx.error) record.error = redactAuditText(ctx.error);
276
+ if (ctx.sessionKey) record.sessionKey = ctx.sessionKey;
277
+ if (captureBodies && !bodiesSuppressed) {
278
+ if (requestBody != null && requestBody.length > 0) {
279
+ record.requestBody = requestBody;
280
+ }
281
+ if (responseChunks.length > 0) {
282
+ const captured = Buffer.concat(responseChunks, responseBytes);
283
+ const decoded = decodeCapturedBody(captured, responseTruncated);
284
+ const body = config.compactStreamingBodies ? compactSseBody(decoded) : decoded;
285
+ record.responseBody = truncateToBytes(redactAuditText(body), config.maxBodyBytes);
286
+ }
287
+ if (record.requestBody !== void 0 || record.responseBody !== void 0) {
288
+ record.hasBody = true;
289
+ }
290
+ }
291
+ recordAudit(record);
292
+ } catch {
293
+ }
294
+ };
295
+ res.once("close", finalize);
296
+ return ctx;
297
+ }
298
+ function installResponseCapture(res, sink) {
299
+ const capture = (chunk) => {
300
+ let buf = null;
301
+ if (Buffer.isBuffer(chunk)) buf = chunk;
302
+ else if (typeof chunk === "string") buf = Buffer.from(chunk, "utf8");
303
+ if (!buf || buf.length === 0) return;
304
+ sink.push(buf);
305
+ };
306
+ const originalWrite = res.write.bind(res);
307
+ const originalEnd = res.end.bind(res);
308
+ res.write = ((chunk, ...args) => {
309
+ if (chunk != null) capture(chunk);
310
+ return originalWrite(chunk, ...args);
311
+ });
312
+ res.end = ((chunk, ...args) => {
313
+ if (chunk != null && typeof chunk !== "function") capture(chunk);
314
+ return originalEnd(chunk, ...args);
315
+ });
316
+ }
317
+
318
+ export {
319
+ beginAuditCapture
320
+ };