@omnicross/core 0.1.1 → 0.1.3
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/ApiConverter.cjs +3 -778
- package/dist/ApiConverter.js +12 -751
- package/dist/{CompletionService-DtOF_War.d.cts → CompletionService-D3a47vdU.d.cts} +2 -1
- package/dist/{CompletionService-7fCmKAP3.d.ts → CompletionService-DdWaAxq0.d.ts} +2 -1
- package/dist/auth/GeminiCodeAssistProjectResolver.cjs +32 -60
- package/dist/auth/GeminiCodeAssistProjectResolver.js +11 -10
- package/dist/builtin-web-fetch-77JZUZGM.cjs +100 -0
- package/dist/builtin-web-fetch-IGLBX2XY.js +100 -0
- package/dist/chunk-2DCNB7DF.cjs +514 -0
- package/dist/chunk-2FMI2B6V.cjs +6196 -0
- package/dist/chunk-3OPYJG76.cjs +266 -0
- package/dist/chunk-3QOSDDNI.cjs +130 -0
- package/dist/chunk-46RLHI7D.js +0 -0
- package/dist/chunk-46ZIFWYG.cjs +277 -0
- package/dist/chunk-4DECIFU7.js +6196 -0
- package/dist/chunk-4IH4EL7M.cjs +9 -0
- package/dist/chunk-4VAVYUZS.cjs +991 -0
- package/dist/chunk-5ENKBSWO.js +311 -0
- package/dist/chunk-5ERIZW3D.js +44 -0
- package/dist/chunk-5HTVET6E.js +514 -0
- package/dist/chunk-5ZQBEOMD.js +764 -0
- package/dist/chunk-6RPZADX3.cjs +92 -0
- package/dist/chunk-7VU7V2E4.js +0 -0
- package/dist/chunk-7YN22L2H.cjs +87 -0
- package/dist/chunk-A2YMUCBT.cjs +105 -0
- package/dist/chunk-AEOZIDEB.cjs +32 -0
- package/dist/chunk-AQ5TNQB7.js +13 -0
- package/dist/chunk-AVYJ4YBN.js +58 -0
- package/dist/chunk-BO4RFWBR.js +89 -0
- package/dist/chunk-C72S6TTV.cjs +49 -0
- package/dist/chunk-C7PSERMH.js +87 -0
- package/dist/chunk-CDHS2QDC.js +179 -0
- package/dist/chunk-CWM2ZDU5.js +130 -0
- package/dist/chunk-CZHZGRU7.js +383 -0
- package/dist/chunk-DK4A7DLE.js +266 -0
- package/dist/chunk-DQ5VAYZ6.cjs +42 -0
- package/dist/chunk-DRWHTIIZ.js +13 -0
- package/dist/chunk-DWKQZ2SK.cjs +254 -0
- package/dist/chunk-EYZYXJTJ.cjs +1 -0
- package/dist/chunk-FFALUUZZ.cjs +235 -0
- package/dist/chunk-FMOBD2OQ.js +39 -0
- package/dist/chunk-FTQ7IQUC.js +991 -0
- package/dist/chunk-FZ46M34D.cjs +1 -0
- package/dist/chunk-G2UTNSGU.js +277 -0
- package/dist/chunk-GBHYAGX3.cjs +26 -0
- package/dist/chunk-GMMT7RVN.cjs +39 -0
- package/dist/chunk-H5JUT3KV.js +105 -0
- package/dist/chunk-HQP3K7PU.cjs +431 -0
- package/dist/chunk-HUZZZ3JL.js +32 -0
- package/dist/chunk-IAXWICZU.js +69 -0
- package/dist/chunk-JMJBSACD.cjs +147 -0
- package/dist/chunk-JO5NLTLY.js +46 -0
- package/dist/chunk-JWC6APFQ.js +23 -0
- package/dist/chunk-KUU2RNG6.cjs +46 -0
- package/dist/chunk-L74VDN4A.cjs +32 -0
- package/dist/chunk-MQNDWYPN.js +235 -0
- package/dist/chunk-MZNPGW5Q.js +26 -0
- package/dist/chunk-N5QFKSDO.js +56 -0
- package/dist/chunk-NYUNU75A.cjs +44 -0
- package/dist/chunk-NZYN7C3P.cjs +179 -0
- package/dist/chunk-Q27JY5RG.cjs +126 -0
- package/dist/chunk-QBZJ7P2T.cjs +13 -0
- package/dist/chunk-QWBWGODS.cjs +69 -0
- package/dist/chunk-QXD4MV2X.cjs +23 -0
- package/dist/chunk-R3HK6R4B.cjs +13 -0
- package/dist/chunk-RPII3E6Z.cjs +145 -0
- package/dist/chunk-RSJ3TWJQ.cjs +186 -0
- package/dist/chunk-S4WBV25P.js +913 -0
- package/dist/chunk-S6JGLF3G.cjs +89 -0
- package/dist/chunk-SUEGJ75D.cjs +764 -0
- package/dist/chunk-SVNDB62D.cjs +58 -0
- package/dist/chunk-SVXC36MU.cjs +383 -0
- package/dist/chunk-TKJMZBAH.js +32 -0
- package/dist/chunk-UBWEBKRC.js +42 -0
- package/dist/chunk-UNEFIWXI.cjs +32 -0
- package/dist/chunk-VQY5W4YW.cjs +311 -0
- package/dist/chunk-VVEHS2LI.js +431 -0
- package/dist/chunk-WNY4WMRF.js +32 -0
- package/dist/chunk-XEKD23J5.js +9 -0
- package/dist/chunk-XTEI64OU.js +145 -0
- package/dist/chunk-XX6NQJMA.js +92 -0
- package/dist/chunk-Y6OM7EV7.cjs +56 -0
- package/dist/chunk-Y7FO65VT.js +147 -0
- package/dist/chunk-YGXJGRFI.cjs +913 -0
- package/dist/chunk-YMFAJFQT.cjs +173 -0
- package/dist/chunk-Z7LUNECE.js +49 -0
- package/dist/chunk-Z7Y2NPHY.js +186 -0
- package/dist/chunk-ZJZAOKI7.js +254 -0
- package/dist/chunk-ZLX3KGXX.js +173 -0
- package/dist/chunk-ZY6KU6P3.js +126 -0
- package/dist/completion/ApiKeyPoolService.cjs +23 -48
- package/dist/completion/ApiKeyPoolService.d.cts +150 -2
- package/dist/completion/ApiKeyPoolService.d.ts +150 -2
- package/dist/completion/BuiltinToolExecutor.cjs +9 -324
- package/dist/completion/BuiltinToolExecutor.js +6 -290
- package/dist/completion/CompletionService.cjs +45 -3487
- package/dist/completion/CompletionService.d.cts +3 -2
- package/dist/completion/CompletionService.d.ts +3 -2
- package/dist/completion/CompletionService.js +41 -3457
- package/dist/completion/NativeSearchInjector.cjs +8 -192
- package/dist/completion/NativeSearchInjector.js +7 -162
- package/dist/completion/ProviderSearchInjector.cjs +12 -39
- package/dist/completion/native-search-types.cjs +13 -66
- package/dist/completion/native-search-types.js +7 -31
- package/dist/completion/openrouter-headers.cjs +12 -71
- package/dist/completion/openrouter-headers.d.cts +9 -12
- package/dist/completion/openrouter-headers.d.ts +9 -12
- package/dist/completion/openrouter-headers.js +7 -36
- package/dist/completion/openrouter-models.cjs +11 -67
- package/dist/completion/openrouter-models.js +5 -34
- package/dist/completion/types.cjs +1 -18
- package/dist/completion/url-builder.cjs +24 -138
- package/dist/completion/url-builder.js +12 -92
- package/dist/completion.cjs +62 -3989
- package/dist/completion.d.cts +3 -2
- package/dist/completion.d.ts +3 -2
- package/dist/completion.js +70 -3953
- package/dist/index.cjs +319 -10429
- package/dist/index.d.cts +49 -12
- package/dist/index.d.ts +49 -12
- package/dist/index.js +248 -10269
- package/dist/logger-4GvQNzhE.d.cts +22 -0
- package/dist/logger-4GvQNzhE.d.ts +22 -0
- package/dist/outbound-api/routeResolver.cjs +10 -217
- package/dist/outbound-api/routeResolver.d.cts +10 -3
- package/dist/outbound-api/routeResolver.d.ts +10 -3
- package/dist/outbound-api/routeResolver.js +9 -187
- package/dist/outbound-api/subscriptionRegistryPort.cjs +7 -37
- package/dist/outbound-api/subscriptionRegistryPort.d.cts +2 -1
- package/dist/outbound-api/subscriptionRegistryPort.d.ts +2 -1
- package/dist/outbound-api/subscriptionRegistryPort.js +4 -8
- package/dist/outbound-api/types.cjs +5 -17
- package/dist/outbound-api/types.d.cts +12 -144
- package/dist/outbound-api/types.d.ts +12 -144
- package/dist/outbound-api/types.js +6 -0
- package/dist/outbound-api.cjs +197 -5265
- package/dist/outbound-api.d.cts +787 -25
- package/dist/outbound-api.d.ts +787 -25
- package/dist/outbound-api.js +173 -5195
- package/dist/pipeline/AuthSource.cjs +1 -18
- package/dist/pipeline/AuthSource.d.cts +23 -1
- package/dist/pipeline/AuthSource.d.ts +23 -1
- package/dist/pipeline/LlmConfigProviderAuth.cjs +5 -166
- package/dist/pipeline/LlmConfigProviderAuth.d.cts +2 -1
- package/dist/pipeline/LlmConfigProviderAuth.d.ts +2 -1
- package/dist/pipeline/LlmConfigProviderAuth.js +5 -139
- package/dist/pipeline/SubscriptionAccountHealth.cjs +22 -0
- package/dist/pipeline/SubscriptionAccountHealth.d.cts +235 -0
- package/dist/pipeline/SubscriptionAccountHealth.d.ts +235 -0
- package/dist/pipeline/SubscriptionAccountHealth.js +22 -0
- package/dist/pipeline/SubscriptionAuthSource.cjs +6 -128
- package/dist/pipeline/SubscriptionAuthSource.d.cts +3 -2
- package/dist/pipeline/SubscriptionAuthSource.d.ts +3 -2
- package/dist/pipeline/SubscriptionAuthSource.js +5 -99
- package/dist/pipeline/SubscriptionAuthStrategy.cjs +1 -18
- package/dist/pipeline/SubscriptionAuthStrategy.d.cts +24 -1
- package/dist/pipeline/SubscriptionAuthStrategy.d.ts +24 -1
- package/dist/pipeline/auditSink.cjs +14 -0
- package/dist/pipeline/auditSink.d.cts +48 -0
- package/dist/pipeline/auditSink.d.ts +48 -0
- package/dist/pipeline/auditSink.js +14 -0
- package/dist/pipeline/billingEmit.cjs +14 -0
- package/dist/pipeline/billingEmit.d.cts +49 -0
- package/dist/pipeline/billingEmit.d.ts +49 -0
- package/dist/pipeline/billingEmit.js +14 -0
- package/dist/pipeline/executeProviderCall.cjs +5 -69
- package/dist/pipeline/executeProviderCall.js +3 -42
- package/dist/pipeline/resolveProviderChain.cjs +5 -46
- package/dist/pipeline/resolveProviderChain.js +3 -19
- package/dist/pipeline/resolveSubscriptionChain.cjs +5 -67
- package/dist/pipeline/resolveSubscriptionChain.js +3 -40
- package/dist/ports/gemini-code-assist-resolver.cjs +7 -37
- package/dist/ports/gemini-code-assist-resolver.js +4 -8
- package/dist/ports/pricing-store.cjs +1 -0
- package/dist/ports/pricing-store.d.cts +50 -0
- package/dist/ports/pricing-store.d.ts +50 -0
- package/dist/ports/pricing-store.js +0 -0
- package/dist/ports/provider-config-source.cjs +1 -18
- package/dist/ports/usage-event-store.cjs +1 -0
- package/dist/ports/usage-event-store.d.cts +54 -0
- package/dist/ports/usage-event-store.d.ts +54 -0
- package/dist/ports/usage-event-store.js +0 -0
- package/dist/ports/web-search-backend.cjs +1 -18
- package/dist/ports.cjs +1 -18
- package/dist/ports.d.cts +13 -2
- package/dist/ports.d.ts +13 -2
- package/dist/provider-proxy/ProviderProxy.cjs +47 -4643
- package/dist/provider-proxy/ProviderProxy.d.cts +2 -1
- package/dist/provider-proxy/ProviderProxy.d.ts +2 -1
- package/dist/provider-proxy/ProviderProxy.js +42 -4613
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.cjs +15 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.cts +121 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.d.ts +121 -0
- package/dist/provider-proxy/identity/SubscriptionIdentityStore.js +15 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.cjs +20 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.d.cts +89 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.d.ts +89 -0
- package/dist/provider-proxy/identity/fingerprintHeaders.js +20 -0
- package/dist/provider-proxy/ingress/providerProxyShared.cjs +42 -2941
- package/dist/provider-proxy/ingress/providerProxyShared.d.cts +13 -3
- package/dist/provider-proxy/ingress/providerProxyShared.d.ts +13 -3
- package/dist/provider-proxy/ingress/providerProxyShared.js +48 -2914
- package/dist/provider-proxy/matchText.cjs +13 -72
- package/dist/provider-proxy/matchText.d.cts +14 -1
- package/dist/provider-proxy/matchText.d.ts +14 -1
- package/dist/provider-proxy/matchText.js +8 -39
- package/dist/provider-proxy/types.cjs +1 -18
- package/dist/provider-proxy/types.d.cts +25 -1
- package/dist/provider-proxy/types.d.ts +25 -1
- package/dist/provider-proxy.cjs +42 -4655
- package/dist/provider-proxy.d.cts +2 -1
- package/dist/provider-proxy.d.ts +2 -1
- package/dist/provider-proxy.js +46 -4628
- package/dist/{routeResolver-HE-ZO0fO.d.ts → routeResolver-B1NglTfe.d.ts} +36 -10
- package/dist/{routeResolver-BrbK6ja9.d.cts → routeResolver-CbG5uBgm.d.cts} +36 -10
- package/dist/serializeError.cjs +5 -81
- package/dist/serializeError.js +3 -54
- package/dist/sse-parser.cjs +7 -455
- package/dist/sse-parser.js +4 -426
- package/dist/transformer/TransformerChainExecutor.cjs +4 -318
- package/dist/transformer/TransformerChainExecutor.js +4 -291
- package/dist/transformer/TransformerService.cjs +5 -289
- package/dist/transformer/TransformerService.js +3 -262
- package/dist/transformer/anthropicBetaInject.cjs +7 -50
- package/dist/transformer/anthropicBetaInject.js +4 -21
- package/dist/transformer/transformers/AnthropicTransformer.cjs +3 -1014
- package/dist/transformer/transformers/AnthropicTransformer.js +3 -987
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.cjs +4 -1106
- package/dist/transformer/transformers/GeminiCodeAssistTransformer.js +7 -1079
- package/dist/transformer/transformers/GeminiTransformer.cjs +4 -1010
- package/dist/transformer/transformers/GeminiTransformer.js +4 -983
- package/dist/transformer/transformers/OpenAIResponseTransformer.cjs +3 -535
- package/dist/transformer/transformers/OpenAIResponseTransformer.js +3 -510
- package/dist/transformer/transformers/OpenCodeGoTransformer.cjs +5 -72
- package/dist/transformer/transformers/OpenCodeGoTransformer.js +3 -45
- package/dist/transformer/transformers/ReasoningTransformer.cjs +3 -270
- package/dist/transformer/transformers/ReasoningTransformer.js +2 -249
- package/dist/transformer/transformers.cjs +10 -3177
- package/dist/transformer/transformers.js +23 -3158
- package/dist/transformer/types.cjs +1 -18
- package/dist/transformer.cjs +13 -3726
- package/dist/transformer.js +17 -3706
- package/dist/types-6OUY_xfA.d.ts +830 -0
- package/dist/types-aBFFXoBz.d.cts +830 -0
- package/dist/usage/pricing-engine.cjs +6 -0
- package/dist/usage/pricing-engine.d.cts +83 -0
- package/dist/usage/pricing-engine.d.ts +83 -0
- package/dist/usage/pricing-engine.js +6 -0
- package/dist/usage/usage-recorder.cjs +6 -0
- package/dist/usage/usage-recorder.d.cts +91 -0
- package/dist/usage/usage-recorder.d.ts +91 -0
- package/dist/usage/usage-recorder.js +6 -0
- package/dist/usage.cjs +11 -0
- package/dist/usage.d.cts +8 -0
- package/dist/usage.d.ts +8 -0
- package/dist/usage.js +11 -0
- package/package.json +4 -2
- package/dist/ApiKeyPoolService-BmMkau07.d.cts +0 -170
- package/dist/ApiKeyPoolService-BmMkau07.d.ts +0 -170
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
// src/sse-parser.ts
|
|
2
|
+
var DEBUG_SSE = true;
|
|
3
|
+
function debugSSE(prefix, ...args) {
|
|
4
|
+
if (DEBUG_SSE) {
|
|
5
|
+
console.log(`[SSE-Parser] ${prefix}`, ...args);
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
function createSSEParser(format, callbacks) {
|
|
9
|
+
const state = {
|
|
10
|
+
buffer: "",
|
|
11
|
+
content: "",
|
|
12
|
+
reasoning: "",
|
|
13
|
+
usage: void 0,
|
|
14
|
+
isDone: false,
|
|
15
|
+
streamStartTime: void 0,
|
|
16
|
+
firstTokenTime: void 0,
|
|
17
|
+
streamEndTime: void 0,
|
|
18
|
+
blocks: [],
|
|
19
|
+
currentBlockIndex: -1,
|
|
20
|
+
currentBlockType: "",
|
|
21
|
+
inputJsonBuffer: "",
|
|
22
|
+
audios: [],
|
|
23
|
+
videos: []
|
|
24
|
+
};
|
|
25
|
+
function parseOpenAIEvent(data) {
|
|
26
|
+
if (data === "[DONE]") {
|
|
27
|
+
debugSSE("OpenAI [DONE] received, content length:", state.content.length);
|
|
28
|
+
state.isDone = true;
|
|
29
|
+
callbacks.onDone?.();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const json = JSON.parse(data);
|
|
34
|
+
callbacks.onRawEvent?.({ data: json, raw: data });
|
|
35
|
+
const delta = json.choices?.[0]?.delta;
|
|
36
|
+
const finishReason = json.choices?.[0]?.finish_reason;
|
|
37
|
+
if (finishReason) {
|
|
38
|
+
debugSSE("OpenAI finish_reason:", finishReason, "content length so far:", state.content.length);
|
|
39
|
+
}
|
|
40
|
+
if (delta?.content) {
|
|
41
|
+
if (!state.firstTokenTime) {
|
|
42
|
+
state.firstTokenTime = Date.now();
|
|
43
|
+
}
|
|
44
|
+
state.content += delta.content;
|
|
45
|
+
callbacks.onDelta?.(delta.content);
|
|
46
|
+
}
|
|
47
|
+
if (delta?.reasoning_content) {
|
|
48
|
+
state.reasoning += delta.reasoning_content;
|
|
49
|
+
callbacks.onReasoning?.(delta.reasoning_content);
|
|
50
|
+
}
|
|
51
|
+
if (delta?.audio) {
|
|
52
|
+
const audioData = delta.audio;
|
|
53
|
+
if (audioData.data) {
|
|
54
|
+
const mimeType = audioData.format ? `audio/${audioData.format}` : "audio/wav";
|
|
55
|
+
const audio = {
|
|
56
|
+
url: audioData.data.startsWith("data:") ? audioData.data : `data:${mimeType};base64,${audioData.data}`,
|
|
57
|
+
mimeType
|
|
58
|
+
};
|
|
59
|
+
state.audios.push(audio);
|
|
60
|
+
callbacks.onAudio?.(audio);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (json.usage) {
|
|
64
|
+
debugSSE("OpenAI usage received:", JSON.stringify(json.usage));
|
|
65
|
+
debugSSE("OpenAI final chunk full data:", JSON.stringify(json));
|
|
66
|
+
state.usage = {
|
|
67
|
+
promptTokens: json.usage.prompt_tokens || 0,
|
|
68
|
+
completionTokens: json.usage.completion_tokens || 0,
|
|
69
|
+
totalTokens: json.usage.total_tokens || 0
|
|
70
|
+
};
|
|
71
|
+
callbacks.onUsage?.(state.usage);
|
|
72
|
+
}
|
|
73
|
+
if (finishReason === "stop" || finishReason === "end_turn" || finishReason === "length") {
|
|
74
|
+
debugSSE("OpenAI stream marked done due to finish_reason:", finishReason);
|
|
75
|
+
}
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function parseAnthropicEvent(data) {
|
|
80
|
+
try {
|
|
81
|
+
const json = JSON.parse(data);
|
|
82
|
+
callbacks.onRawEvent?.({ type: json.type, data: json, raw: data });
|
|
83
|
+
if (json.type === "content_block_start") {
|
|
84
|
+
const contentBlock = json.content_block;
|
|
85
|
+
const blockIndex = json.index ?? -1;
|
|
86
|
+
if (contentBlock?.type === "thinking") {
|
|
87
|
+
debugSSE("THINKING BLOCK STARTED!");
|
|
88
|
+
}
|
|
89
|
+
if (contentBlock?.type === "server_tool_use") {
|
|
90
|
+
state.currentBlockIndex = blockIndex;
|
|
91
|
+
state.currentBlockType = "server_tool_use";
|
|
92
|
+
state.inputJsonBuffer = "";
|
|
93
|
+
const toolUseBlock = {
|
|
94
|
+
id: contentBlock.id || `block_${Date.now()}`,
|
|
95
|
+
type: "tool_use",
|
|
96
|
+
toolId: contentBlock.id || "",
|
|
97
|
+
toolName: contentBlock.name || "web_search",
|
|
98
|
+
input: contentBlock.input || {},
|
|
99
|
+
status: "running"
|
|
100
|
+
};
|
|
101
|
+
state.blocks.push(toolUseBlock);
|
|
102
|
+
callbacks.onBlock?.(toolUseBlock);
|
|
103
|
+
}
|
|
104
|
+
if (contentBlock?.type === "web_search_tool_result") {
|
|
105
|
+
state.currentBlockIndex = blockIndex;
|
|
106
|
+
state.currentBlockType = "web_search_tool_result";
|
|
107
|
+
const searchResults = contentBlock.content;
|
|
108
|
+
let output = "";
|
|
109
|
+
if (Array.isArray(searchResults)) {
|
|
110
|
+
output = searchResults.filter((r) => r.type === "web_search_result").map(
|
|
111
|
+
(r) => `**${r.title || "Untitled"}**
|
|
112
|
+
${r.url || ""}
|
|
113
|
+
${r.encrypted_content ? "(encrypted)" : r.page_content || r.snippet || ""}`
|
|
114
|
+
).join("\n\n");
|
|
115
|
+
}
|
|
116
|
+
const lastToolUse = [...state.blocks].reverse().find(
|
|
117
|
+
(b) => b.type === "tool_use"
|
|
118
|
+
);
|
|
119
|
+
const toolResultBlock = {
|
|
120
|
+
id: `result_${Date.now()}`,
|
|
121
|
+
type: "tool_result",
|
|
122
|
+
toolId: lastToolUse?.toolId || "",
|
|
123
|
+
toolName: lastToolUse?.toolName || "web_search",
|
|
124
|
+
output: output || "(no results)"
|
|
125
|
+
};
|
|
126
|
+
state.blocks.push(toolResultBlock);
|
|
127
|
+
callbacks.onBlock?.(toolResultBlock);
|
|
128
|
+
if (lastToolUse) {
|
|
129
|
+
lastToolUse.status = "completed";
|
|
130
|
+
callbacks.onBlock?.(lastToolUse);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
if (json.type === "content_block_delta") {
|
|
135
|
+
const delta = json.delta;
|
|
136
|
+
if (delta?.type === "text_delta" && delta?.text) {
|
|
137
|
+
if (!state.firstTokenTime) {
|
|
138
|
+
state.firstTokenTime = Date.now();
|
|
139
|
+
}
|
|
140
|
+
state.content += delta.text;
|
|
141
|
+
callbacks.onDelta?.(delta.text);
|
|
142
|
+
}
|
|
143
|
+
if (delta?.type === "thinking_delta" && delta?.thinking) {
|
|
144
|
+
state.reasoning += delta.thinking;
|
|
145
|
+
callbacks.onReasoning?.(delta.thinking);
|
|
146
|
+
}
|
|
147
|
+
if (delta?.type === "input_json_delta" && delta?.partial_json) {
|
|
148
|
+
state.inputJsonBuffer += delta.partial_json;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (json.type === "content_block_stop") {
|
|
152
|
+
if (state.currentBlockType === "server_tool_use" && state.inputJsonBuffer) {
|
|
153
|
+
const lastToolUse = [...state.blocks].reverse().find(
|
|
154
|
+
(b) => b.type === "tool_use"
|
|
155
|
+
);
|
|
156
|
+
if (lastToolUse) {
|
|
157
|
+
try {
|
|
158
|
+
lastToolUse.input = JSON.parse(state.inputJsonBuffer);
|
|
159
|
+
} catch {
|
|
160
|
+
lastToolUse.input = { raw: state.inputJsonBuffer };
|
|
161
|
+
}
|
|
162
|
+
callbacks.onBlock?.(lastToolUse);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
state.currentBlockIndex = -1;
|
|
166
|
+
state.currentBlockType = "";
|
|
167
|
+
state.inputJsonBuffer = "";
|
|
168
|
+
}
|
|
169
|
+
if (json.type === "message_delta" && json.usage) {
|
|
170
|
+
state.usage = {
|
|
171
|
+
promptTokens: json.usage.input_tokens || 0,
|
|
172
|
+
completionTokens: json.usage.output_tokens || 0,
|
|
173
|
+
totalTokens: (json.usage.input_tokens || 0) + (json.usage.output_tokens || 0)
|
|
174
|
+
};
|
|
175
|
+
callbacks.onUsage?.(state.usage);
|
|
176
|
+
}
|
|
177
|
+
if (json.type === "message_stop") {
|
|
178
|
+
state.isDone = true;
|
|
179
|
+
callbacks.onDone?.();
|
|
180
|
+
}
|
|
181
|
+
if (json.type === "error") {
|
|
182
|
+
callbacks.onError?.(json.error?.message || "Unknown error");
|
|
183
|
+
}
|
|
184
|
+
} catch {
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
function parseGeminiEvent(data) {
|
|
188
|
+
try {
|
|
189
|
+
const json = JSON.parse(data);
|
|
190
|
+
callbacks.onRawEvent?.({ data: json, raw: data });
|
|
191
|
+
const candidates = json.candidates;
|
|
192
|
+
if (candidates && candidates.length > 0) {
|
|
193
|
+
const candidate = candidates[0];
|
|
194
|
+
const content = candidate.content;
|
|
195
|
+
if (content?.parts) {
|
|
196
|
+
for (const part of content.parts) {
|
|
197
|
+
if (part.thought === true && part.text) {
|
|
198
|
+
state.reasoning += part.text;
|
|
199
|
+
callbacks.onReasoning?.(part.text);
|
|
200
|
+
} else if (part.text) {
|
|
201
|
+
if (!state.firstTokenTime) {
|
|
202
|
+
state.firstTokenTime = Date.now();
|
|
203
|
+
}
|
|
204
|
+
state.content += part.text;
|
|
205
|
+
callbacks.onDelta?.(part.text);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
const finishReason = candidate.finishReason;
|
|
210
|
+
if (finishReason === "STOP" || finishReason === "MAX_TOKENS" || finishReason === "SAFETY") {
|
|
211
|
+
debugSSE("Gemini finish reason:", finishReason);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
const usage = json.usageMetadata;
|
|
215
|
+
if (usage) {
|
|
216
|
+
state.usage = {
|
|
217
|
+
promptTokens: usage.promptTokenCount || 0,
|
|
218
|
+
completionTokens: usage.candidatesTokenCount || 0,
|
|
219
|
+
totalTokens: usage.totalTokenCount || 0
|
|
220
|
+
};
|
|
221
|
+
callbacks.onUsage?.(state.usage);
|
|
222
|
+
debugSSE("Gemini usage:", state.usage);
|
|
223
|
+
}
|
|
224
|
+
if (json.error) {
|
|
225
|
+
callbacks.onError?.(json.error.message || "Gemini API error");
|
|
226
|
+
}
|
|
227
|
+
} catch {
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
function parseOpenAIResponseEvent(data) {
|
|
231
|
+
try {
|
|
232
|
+
const json = JSON.parse(data);
|
|
233
|
+
callbacks.onRawEvent?.({ type: json.type, data: json, raw: data });
|
|
234
|
+
switch (json.type) {
|
|
235
|
+
case "response.output_text.delta":
|
|
236
|
+
if (json.delta) {
|
|
237
|
+
if (!state.firstTokenTime) {
|
|
238
|
+
state.firstTokenTime = Date.now();
|
|
239
|
+
}
|
|
240
|
+
state.content += json.delta;
|
|
241
|
+
callbacks.onDelta?.(json.delta);
|
|
242
|
+
}
|
|
243
|
+
break;
|
|
244
|
+
case "response.reasoning_summary_text.delta":
|
|
245
|
+
if (json.delta) {
|
|
246
|
+
state.reasoning += json.delta;
|
|
247
|
+
callbacks.onReasoning?.(json.delta);
|
|
248
|
+
}
|
|
249
|
+
break;
|
|
250
|
+
case "response.completed": {
|
|
251
|
+
const response = json.response;
|
|
252
|
+
if (response?.usage) {
|
|
253
|
+
state.usage = {
|
|
254
|
+
promptTokens: response.usage.input_tokens || 0,
|
|
255
|
+
completionTokens: response.usage.output_tokens || 0,
|
|
256
|
+
totalTokens: (response.usage.input_tokens || 0) + (response.usage.output_tokens || 0)
|
|
257
|
+
};
|
|
258
|
+
callbacks.onUsage?.(state.usage);
|
|
259
|
+
}
|
|
260
|
+
state.isDone = true;
|
|
261
|
+
callbacks.onDone?.();
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
case "error":
|
|
265
|
+
callbacks.onError?.(json.error?.message || json.message || "Unknown error");
|
|
266
|
+
break;
|
|
267
|
+
// Informational events — no-op
|
|
268
|
+
// response.created, response.in_progress, response.output_item.added,
|
|
269
|
+
// response.content_part.added, response.output_text.done,
|
|
270
|
+
// response.content_part.done, response.output_item.done, etc.
|
|
271
|
+
default:
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
} catch {
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function processEventBlock(eventBlock) {
|
|
278
|
+
const lines = eventBlock.split("\n");
|
|
279
|
+
const dataLines = [];
|
|
280
|
+
for (const line of lines) {
|
|
281
|
+
if (line.startsWith("data: ")) {
|
|
282
|
+
dataLines.push(line.slice(6));
|
|
283
|
+
} else if (line.trim() !== "" && !line.startsWith(":")) {
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (dataLines.length > 0) {
|
|
287
|
+
const data = dataLines.join("\n");
|
|
288
|
+
if (format === "openai") {
|
|
289
|
+
parseOpenAIEvent(data);
|
|
290
|
+
} else if (format === "gemini") {
|
|
291
|
+
parseGeminiEvent(data);
|
|
292
|
+
} else if (format === "openai-response") {
|
|
293
|
+
parseOpenAIResponseEvent(data);
|
|
294
|
+
} else {
|
|
295
|
+
parseAnthropicEvent(data);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
return {
|
|
300
|
+
/**
|
|
301
|
+
* Push a chunk of data to the parser
|
|
302
|
+
* @param chunk - Raw SSE chunk from response stream
|
|
303
|
+
*/
|
|
304
|
+
push(chunk) {
|
|
305
|
+
if (state.isDone) return;
|
|
306
|
+
if (!state.streamStartTime) {
|
|
307
|
+
state.streamStartTime = Date.now();
|
|
308
|
+
}
|
|
309
|
+
state.buffer += chunk;
|
|
310
|
+
const events = state.buffer.split("\n\n");
|
|
311
|
+
state.buffer = events.pop() || "";
|
|
312
|
+
for (const eventBlock of events) {
|
|
313
|
+
processEventBlock(eventBlock);
|
|
314
|
+
if (state.isDone) break;
|
|
315
|
+
}
|
|
316
|
+
},
|
|
317
|
+
/**
|
|
318
|
+
* Flush any remaining data in the buffer
|
|
319
|
+
*/
|
|
320
|
+
flush() {
|
|
321
|
+
debugSSE("flush() called, buffer length:", state.buffer.length, "isDone:", state.isDone);
|
|
322
|
+
if (state.buffer.trim()) {
|
|
323
|
+
debugSSE("flush() processing remaining buffer:", state.buffer.substring(0, 200));
|
|
324
|
+
processEventBlock(state.buffer);
|
|
325
|
+
state.buffer = "";
|
|
326
|
+
}
|
|
327
|
+
state.streamEndTime = Date.now();
|
|
328
|
+
if (!state.isDone) {
|
|
329
|
+
debugSSE("flush() marking stream as done, final content length:", state.content.length);
|
|
330
|
+
state.isDone = true;
|
|
331
|
+
callbacks.onDone?.();
|
|
332
|
+
}
|
|
333
|
+
},
|
|
334
|
+
/**
|
|
335
|
+
* Get accumulated results
|
|
336
|
+
*/
|
|
337
|
+
getResult() {
|
|
338
|
+
let metrics;
|
|
339
|
+
if (state.usage && state.firstTokenTime && state.streamEndTime) {
|
|
340
|
+
const timeCompletionMs = state.streamEndTime - state.firstTokenTime;
|
|
341
|
+
const timeFirstTokenMs = state.streamStartTime ? state.firstTokenTime - state.streamStartTime : void 0;
|
|
342
|
+
metrics = {
|
|
343
|
+
completionTokens: state.usage.completionTokens,
|
|
344
|
+
timeCompletionMs: timeCompletionMs > 0 ? timeCompletionMs : 1,
|
|
345
|
+
// Ensure at least 1ms
|
|
346
|
+
timeFirstTokenMs
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
if (state.reasoning) {
|
|
350
|
+
const thinkingBlock = {
|
|
351
|
+
id: `thinking_${Date.now()}`,
|
|
352
|
+
type: "thinking",
|
|
353
|
+
content: state.reasoning
|
|
354
|
+
};
|
|
355
|
+
state.blocks.unshift(thinkingBlock);
|
|
356
|
+
}
|
|
357
|
+
return {
|
|
358
|
+
content: state.content,
|
|
359
|
+
reasoning: state.reasoning,
|
|
360
|
+
usage: state.usage,
|
|
361
|
+
metrics,
|
|
362
|
+
blocks: state.blocks,
|
|
363
|
+
audios: state.audios,
|
|
364
|
+
videos: state.videos
|
|
365
|
+
};
|
|
366
|
+
},
|
|
367
|
+
/**
|
|
368
|
+
* Check if stream is complete
|
|
369
|
+
*/
|
|
370
|
+
isDone() {
|
|
371
|
+
return state.isDone;
|
|
372
|
+
},
|
|
373
|
+
/**
|
|
374
|
+
* Reset parser state for reuse
|
|
375
|
+
*/
|
|
376
|
+
reset() {
|
|
377
|
+
state.buffer = "";
|
|
378
|
+
state.content = "";
|
|
379
|
+
state.reasoning = "";
|
|
380
|
+
state.usage = void 0;
|
|
381
|
+
state.isDone = false;
|
|
382
|
+
state.streamStartTime = void 0;
|
|
383
|
+
state.firstTokenTime = void 0;
|
|
384
|
+
state.streamEndTime = void 0;
|
|
385
|
+
state.blocks = [];
|
|
386
|
+
state.currentBlockIndex = -1;
|
|
387
|
+
state.currentBlockType = "";
|
|
388
|
+
state.inputJsonBuffer = "";
|
|
389
|
+
state.audios = [];
|
|
390
|
+
state.videos = [];
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
async function streamSSEResponse(response, format, callbacks) {
|
|
395
|
+
debugSSE("streamSSEResponse started, format:", format);
|
|
396
|
+
const reader = response.body?.getReader();
|
|
397
|
+
if (!reader) {
|
|
398
|
+
callbacks.onError?.("No response body");
|
|
399
|
+
return { content: "", reasoning: "", blocks: [], audios: [], videos: [] };
|
|
400
|
+
}
|
|
401
|
+
const decoder = new TextDecoder();
|
|
402
|
+
const parser = createSSEParser(format, callbacks);
|
|
403
|
+
let chunkCount = 0;
|
|
404
|
+
try {
|
|
405
|
+
while (true) {
|
|
406
|
+
const { done, value } = await reader.read();
|
|
407
|
+
if (done) {
|
|
408
|
+
debugSSE("Reader done signal received after", chunkCount, "chunks");
|
|
409
|
+
break;
|
|
410
|
+
}
|
|
411
|
+
const chunk = decoder.decode(value, { stream: true });
|
|
412
|
+
chunkCount++;
|
|
413
|
+
parser.push(chunk);
|
|
414
|
+
if (parser.isDone()) {
|
|
415
|
+
debugSSE("Parser isDone after", chunkCount, "chunks");
|
|
416
|
+
break;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
parser.flush();
|
|
420
|
+
const result = parser.getResult();
|
|
421
|
+
debugSSE("streamSSEResponse complete, content length:", result.content.length, "completionTokens:", result.usage?.completionTokens, "usage:", result.usage);
|
|
422
|
+
return result;
|
|
423
|
+
} finally {
|
|
424
|
+
reader.releaseLock();
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
export {
|
|
429
|
+
createSSEParser,
|
|
430
|
+
streamSSEResponse
|
|
431
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/pipeline/auditSink.ts
|
|
2
|
+
var sink = null;
|
|
3
|
+
var captureConfig = null;
|
|
4
|
+
function setAuditSink(fn) {
|
|
5
|
+
sink = fn;
|
|
6
|
+
}
|
|
7
|
+
function setAuditCaptureConfig(config) {
|
|
8
|
+
captureConfig = config && config.enabled ? config : null;
|
|
9
|
+
}
|
|
10
|
+
function getAuditCaptureConfig() {
|
|
11
|
+
return captureConfig;
|
|
12
|
+
}
|
|
13
|
+
function recordAudit(record) {
|
|
14
|
+
const active = sink;
|
|
15
|
+
if (!active) return;
|
|
16
|
+
try {
|
|
17
|
+
active(record);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function __resetAuditSinkForTests() {
|
|
22
|
+
sink = null;
|
|
23
|
+
captureConfig = null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export {
|
|
27
|
+
setAuditSink,
|
|
28
|
+
setAuditCaptureConfig,
|
|
29
|
+
getAuditCaptureConfig,
|
|
30
|
+
recordAudit,
|
|
31
|
+
__resetAuditSinkForTests
|
|
32
|
+
};
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import {
|
|
2
|
+
refreshNonStainless,
|
|
3
|
+
sanitizeFrozenHeaders
|
|
4
|
+
} from "./chunk-XX6NQJMA.js";
|
|
5
|
+
|
|
6
|
+
// src/provider-proxy/identity/SubscriptionIdentityStore.ts
|
|
7
|
+
var CC_HEADER_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
8
|
+
var KEY_SEP = "\0";
|
|
9
|
+
function normalizeUa(ua) {
|
|
10
|
+
if (typeof ua !== "string") return void 0;
|
|
11
|
+
const trimmed = ua.trim();
|
|
12
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
13
|
+
}
|
|
14
|
+
var SubscriptionIdentityStore = class {
|
|
15
|
+
identities = /* @__PURE__ */ new Map();
|
|
16
|
+
now;
|
|
17
|
+
enabled;
|
|
18
|
+
ua;
|
|
19
|
+
ccHeaderTtlMs;
|
|
20
|
+
persistence = null;
|
|
21
|
+
constructor(opts = {}) {
|
|
22
|
+
this.now = opts.now ?? Date.now;
|
|
23
|
+
this.enabled = opts.enabled ?? false;
|
|
24
|
+
this.ua = normalizeUa(opts.ua);
|
|
25
|
+
this.ccHeaderTtlMs = opts.ccHeaderTtlMs ?? CC_HEADER_TTL_MS;
|
|
26
|
+
}
|
|
27
|
+
/** Whether capture/replay is engaged (config flag). */
|
|
28
|
+
isEnabled() {
|
|
29
|
+
return this.enabled;
|
|
30
|
+
}
|
|
31
|
+
/** The operator UA baseline (piece 4), or undefined when unset. */
|
|
32
|
+
uaBaseline() {
|
|
33
|
+
return this.ua;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Re-apply config to the LIVE shared instance (bootstrap, mirroring the health
|
|
37
|
+
* tracker's `configure`). Only defined fields override; `ua: null` clears the
|
|
38
|
+
* baseline.
|
|
39
|
+
*/
|
|
40
|
+
configure(opts) {
|
|
41
|
+
if (opts.enabled !== void 0) this.enabled = opts.enabled;
|
|
42
|
+
if (opts.ua !== void 0) this.ua = normalizeUa(opts.ua ?? void 0);
|
|
43
|
+
}
|
|
44
|
+
/** Install (or clear) the write-through persistence port (P2). */
|
|
45
|
+
setPersistence(port) {
|
|
46
|
+
this.persistence = port;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Boot seed (P2, D5): install a PERSISTED identity for an account, but NEVER
|
|
50
|
+
* over a live in-memory capture (a re-captured identity from this session wins).
|
|
51
|
+
* A no-op for an empty/absent identity. Does NOT write back through the port.
|
|
52
|
+
*/
|
|
53
|
+
seed(providerId, accountId, identity) {
|
|
54
|
+
if (!accountId || !identity) return;
|
|
55
|
+
const headers = sanitizeFrozenHeaders(identity.headers ?? {});
|
|
56
|
+
if (Object.keys(headers).length === 0) return;
|
|
57
|
+
const key = this.key(providerId, accountId);
|
|
58
|
+
if (this.identities.has(key)) return;
|
|
59
|
+
this.identities.set(key, {
|
|
60
|
+
headers,
|
|
61
|
+
capturedAt: typeof identity.capturedAt === "number" ? identity.capturedAt : this.now()
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Capture a real client's fingerprint headers for an account. First-seen ⇒
|
|
66
|
+
* FREEZE the whole (sanitized) bag. Already-frozen ⇒ within the TTL, no change
|
|
67
|
+
* (stable identity); past the TTL, refresh the NON-stainless headers from the
|
|
68
|
+
* new observation while keeping stainless frozen-stable (P2). An empty/absent
|
|
69
|
+
* account id or an empty sanitized bag is a no-op (so an account with no
|
|
70
|
+
* fingerprint headers never freezes an empty identity → the caller falls back
|
|
71
|
+
* to the UA baseline). Fires the persistence port on a freeze/refresh.
|
|
72
|
+
*/
|
|
73
|
+
capture(providerId, accountId, incoming, now = this.now()) {
|
|
74
|
+
if (!accountId) return;
|
|
75
|
+
const clean = sanitizeFrozenHeaders(incoming);
|
|
76
|
+
if (Object.keys(clean).length === 0) return;
|
|
77
|
+
const key = this.key(providerId, accountId);
|
|
78
|
+
const existing = this.identities.get(key);
|
|
79
|
+
if (!existing) {
|
|
80
|
+
const frozen = { headers: clean, capturedAt: now };
|
|
81
|
+
this.identities.set(key, frozen);
|
|
82
|
+
this.emitPersist(providerId, accountId, frozen);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (now - existing.capturedAt < this.ccHeaderTtlMs) return;
|
|
86
|
+
const refreshed = {
|
|
87
|
+
headers: refreshNonStainless(existing.headers, clean),
|
|
88
|
+
capturedAt: now
|
|
89
|
+
};
|
|
90
|
+
this.identities.set(key, refreshed);
|
|
91
|
+
this.emitPersist(providerId, accountId, refreshed);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The frozen identity headers for an account, or `undefined` when none is
|
|
95
|
+
* frozen (or the frozen set is empty). Returns a COPY (the caller merges it into
|
|
96
|
+
* a mutable outbound header bag).
|
|
97
|
+
*/
|
|
98
|
+
replay(providerId, accountId) {
|
|
99
|
+
if (!accountId) return void 0;
|
|
100
|
+
const frozen = this.identities.get(this.key(providerId, accountId));
|
|
101
|
+
if (!frozen || Object.keys(frozen.headers).length === 0) return void 0;
|
|
102
|
+
return { ...frozen.headers };
|
|
103
|
+
}
|
|
104
|
+
/** Whether an identity is frozen for an account (admin coarse status — D7). */
|
|
105
|
+
hasIdentity(providerId, accountId) {
|
|
106
|
+
const frozen = this.identities.get(this.key(providerId, accountId));
|
|
107
|
+
return !!frozen && Object.keys(frozen.headers).length > 0;
|
|
108
|
+
}
|
|
109
|
+
/** The freeze/refresh time for an account's identity (admin coarse status). */
|
|
110
|
+
capturedAt(providerId, accountId) {
|
|
111
|
+
return this.identities.get(this.key(providerId, accountId))?.capturedAt;
|
|
112
|
+
}
|
|
113
|
+
emitPersist(providerId, accountId, identity) {
|
|
114
|
+
if (!this.persistence) return;
|
|
115
|
+
try {
|
|
116
|
+
this.persistence.persist(providerId, accountId, {
|
|
117
|
+
headers: { ...identity.headers },
|
|
118
|
+
capturedAt: identity.capturedAt
|
|
119
|
+
});
|
|
120
|
+
} catch {
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
key(providerId, accountId) {
|
|
124
|
+
return `${providerId}${KEY_SEP}${accountId}`;
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
var _shared = null;
|
|
128
|
+
function getSharedIdentityStore() {
|
|
129
|
+
if (!_shared) _shared = new SubscriptionIdentityStore();
|
|
130
|
+
return _shared;
|
|
131
|
+
}
|
|
132
|
+
function setSharedIdentityStore(instance) {
|
|
133
|
+
_shared = instance;
|
|
134
|
+
}
|
|
135
|
+
function __resetSharedIdentityStoreForTests() {
|
|
136
|
+
_shared = null;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export {
|
|
140
|
+
CC_HEADER_TTL_MS,
|
|
141
|
+
SubscriptionIdentityStore,
|
|
142
|
+
getSharedIdentityStore,
|
|
143
|
+
setSharedIdentityStore,
|
|
144
|
+
__resetSharedIdentityStoreForTests
|
|
145
|
+
};
|