@aui-x/prism 0.0.1
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/LICENSE +11 -0
- package/README.md +195 -0
- package/dist/client-B9WXHjpz.cjs +192 -0
- package/dist/client-B9WXHjpz.cjs.map +1 -0
- package/dist/client-BSsSpkZY.d.cts +157 -0
- package/dist/client-BSsSpkZY.d.cts.map +1 -0
- package/dist/client-BrZstMQX.d.ts +157 -0
- package/dist/client-BrZstMQX.d.ts.map +1 -0
- package/dist/client-C7RiAn7a.js +174 -0
- package/dist/client-C7RiAn7a.js.map +1 -0
- package/dist/core.cjs +6 -0
- package/dist/core.d.cts +2 -0
- package/dist/core.d.ts +2 -0
- package/dist/core.js +3 -0
- package/dist/index.cjs +12 -0
- package/dist/index.d.cts +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +6 -0
- package/dist/integrations/ai-sdk.cjs +26 -0
- package/dist/integrations/ai-sdk.cjs.map +1 -0
- package/dist/integrations/ai-sdk.d.cts +18 -0
- package/dist/integrations/ai-sdk.d.cts.map +1 -0
- package/dist/integrations/ai-sdk.d.ts +18 -0
- package/dist/integrations/ai-sdk.d.ts.map +1 -0
- package/dist/integrations/ai-sdk.js +25 -0
- package/dist/integrations/ai-sdk.js.map +1 -0
- package/dist/integrations/anthropic.cjs +226 -0
- package/dist/integrations/anthropic.cjs.map +1 -0
- package/dist/integrations/anthropic.d.cts +20 -0
- package/dist/integrations/anthropic.d.cts.map +1 -0
- package/dist/integrations/anthropic.d.ts +20 -0
- package/dist/integrations/anthropic.d.ts.map +1 -0
- package/dist/integrations/anthropic.js +224 -0
- package/dist/integrations/anthropic.js.map +1 -0
- package/dist/integrations/openai.cjs +227 -0
- package/dist/integrations/openai.cjs.map +1 -0
- package/dist/integrations/openai.d.cts +20 -0
- package/dist/integrations/openai.d.cts.map +1 -0
- package/dist/integrations/openai.d.ts +20 -0
- package/dist/integrations/openai.d.ts.map +1 -0
- package/dist/integrations/openai.js +225 -0
- package/dist/integrations/openai.js.map +1 -0
- package/dist/wrapper-7jRyp54U.js +242 -0
- package/dist/wrapper-7jRyp54U.js.map +1 -0
- package/dist/wrapper-ByspXfxS.cjs +247 -0
- package/dist/wrapper-ByspXfxS.cjs.map +1 -0
- package/package.json +103 -0
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/anthropic.ts
|
|
4
|
+
function truncateInput(messages, maxBytes = 32768) {
|
|
5
|
+
let json = JSON.stringify(messages);
|
|
6
|
+
if (new TextEncoder().encode(json).length <= maxBytes) return messages;
|
|
7
|
+
if (!Array.isArray(messages)) return messages;
|
|
8
|
+
const arr = [...messages];
|
|
9
|
+
while (arr.length > 1) {
|
|
10
|
+
arr.shift();
|
|
11
|
+
json = JSON.stringify(arr);
|
|
12
|
+
if (new TextEncoder().encode(json).length <= maxBytes) return arr;
|
|
13
|
+
}
|
|
14
|
+
return arr;
|
|
15
|
+
}
|
|
16
|
+
function createRootHandle(tracer, opts, model, input, metadata) {
|
|
17
|
+
const parentTraceId = opts?.parentTraceId;
|
|
18
|
+
if (parentTraceId) return {
|
|
19
|
+
isSpanMode: true,
|
|
20
|
+
traceId: parentTraceId,
|
|
21
|
+
handle: tracer.startSpanOnTrace(parentTraceId, {
|
|
22
|
+
name: opts?.name ?? model,
|
|
23
|
+
type: "llm",
|
|
24
|
+
input,
|
|
25
|
+
model,
|
|
26
|
+
provider: "anthropic",
|
|
27
|
+
metadata
|
|
28
|
+
})
|
|
29
|
+
};
|
|
30
|
+
const handle = tracer.startTrace({
|
|
31
|
+
name: opts?.name ?? model,
|
|
32
|
+
model,
|
|
33
|
+
provider: "anthropic",
|
|
34
|
+
input,
|
|
35
|
+
metadata,
|
|
36
|
+
tags: opts?.tags,
|
|
37
|
+
endUserId: opts?.endUserId
|
|
38
|
+
});
|
|
39
|
+
return {
|
|
40
|
+
isSpanMode: false,
|
|
41
|
+
traceId: handle.traceId,
|
|
42
|
+
handle
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function createToolSpan(tracer, root, toolCall) {
|
|
46
|
+
if (root.isSpanMode) return tracer.startSpanOnTrace(root.traceId, {
|
|
47
|
+
name: toolCall.name,
|
|
48
|
+
type: "tool",
|
|
49
|
+
input: toolCall.arguments,
|
|
50
|
+
parentSpanId: root.handle.spanId
|
|
51
|
+
});
|
|
52
|
+
return root.handle.startSpan({
|
|
53
|
+
name: toolCall.name,
|
|
54
|
+
type: "tool",
|
|
55
|
+
input: toolCall.arguments
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function endRootHandle(root, result) {
|
|
59
|
+
root.handle.end({
|
|
60
|
+
output: result.output,
|
|
61
|
+
status: "completed",
|
|
62
|
+
totalTokens: result.inputTokens + result.outputTokens,
|
|
63
|
+
promptTokens: result.inputTokens,
|
|
64
|
+
completionTokens: result.outputTokens,
|
|
65
|
+
ttftMs: result.ttftMs
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function cleanupOnError(root, error) {
|
|
69
|
+
root.handle.end({
|
|
70
|
+
status: "error",
|
|
71
|
+
error: error instanceof Error ? error.message : String(error)
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Wraps an Anthropic client to automatically trace `messages.create` calls.
|
|
76
|
+
*
|
|
77
|
+
* Returns a proxy that behaves identically to the original client, but emits
|
|
78
|
+
* trace events for both streaming and non-streaming message calls.
|
|
79
|
+
*/
|
|
80
|
+
function prismAnthropic(tracer, client, opts) {
|
|
81
|
+
return new Proxy(client, { get(target, prop, receiver) {
|
|
82
|
+
if (prop === "messages") {
|
|
83
|
+
const messages = Reflect.get(target, prop, receiver);
|
|
84
|
+
return new Proxy(messages, { get(msgTarget, msgProp, msgReceiver) {
|
|
85
|
+
if (msgProp === "create") return createInterceptor(tracer, Reflect.get(msgTarget, msgProp, msgReceiver).bind(msgTarget), opts);
|
|
86
|
+
return Reflect.get(msgTarget, msgProp, msgReceiver);
|
|
87
|
+
} });
|
|
88
|
+
}
|
|
89
|
+
return Reflect.get(target, prop, receiver);
|
|
90
|
+
} });
|
|
91
|
+
}
|
|
92
|
+
function createInterceptor(tracer, originalCreate, opts) {
|
|
93
|
+
return async (params, ...rest) => {
|
|
94
|
+
const model = params.model ?? "unknown";
|
|
95
|
+
const input = truncateInput(params.messages);
|
|
96
|
+
const metadata = opts?.metadata;
|
|
97
|
+
const isStream = !!params.stream;
|
|
98
|
+
const root = createRootHandle(tracer, opts, model, input, metadata);
|
|
99
|
+
if (!isStream) return handleNonStreaming(tracer, root, originalCreate, params, rest);
|
|
100
|
+
return handleStreaming(tracer, root, originalCreate, params, rest);
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
async function handleNonStreaming(tracer, root, originalCreate, params, rest) {
|
|
104
|
+
try {
|
|
105
|
+
const result = await originalCreate(params, ...rest);
|
|
106
|
+
const content = result.content ?? [];
|
|
107
|
+
const output = content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
108
|
+
const inputTokens = result.usage?.input_tokens ?? 0;
|
|
109
|
+
const outputTokens = result.usage?.output_tokens ?? 0;
|
|
110
|
+
const toolUseBlocks = content.filter((b) => b.type === "tool_use");
|
|
111
|
+
for (const tc of toolUseBlocks) createToolSpan(tracer, root, {
|
|
112
|
+
id: tc.id,
|
|
113
|
+
name: tc.name,
|
|
114
|
+
arguments: JSON.stringify(tc.input)
|
|
115
|
+
}).end({ status: "completed" });
|
|
116
|
+
endRootHandle(root, {
|
|
117
|
+
output,
|
|
118
|
+
inputTokens,
|
|
119
|
+
outputTokens
|
|
120
|
+
});
|
|
121
|
+
return result;
|
|
122
|
+
} catch (error) {
|
|
123
|
+
cleanupOnError(root, error);
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async function handleStreaming(tracer, root, originalCreate, params, rest) {
|
|
128
|
+
try {
|
|
129
|
+
const streamStart = Date.now();
|
|
130
|
+
const stream = await originalCreate(params, ...rest);
|
|
131
|
+
let output = "";
|
|
132
|
+
let inputTokens = 0;
|
|
133
|
+
let outputTokens = 0;
|
|
134
|
+
let ttftMs;
|
|
135
|
+
let firstTextDelta = true;
|
|
136
|
+
let finalized = false;
|
|
137
|
+
const toolCallAccum = /* @__PURE__ */ new Map();
|
|
138
|
+
let currentToolIndex = -1;
|
|
139
|
+
const processEvent = (event) => {
|
|
140
|
+
switch (event.type) {
|
|
141
|
+
case "message_start":
|
|
142
|
+
inputTokens = event.message?.usage?.input_tokens ?? 0;
|
|
143
|
+
break;
|
|
144
|
+
case "content_block_start":
|
|
145
|
+
if (event.content_block?.type === "tool_use") {
|
|
146
|
+
currentToolIndex = event.index ?? currentToolIndex + 1;
|
|
147
|
+
toolCallAccum.set(currentToolIndex, {
|
|
148
|
+
id: event.content_block.id ?? "",
|
|
149
|
+
name: event.content_block.name ?? "",
|
|
150
|
+
input: ""
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
break;
|
|
154
|
+
case "content_block_delta":
|
|
155
|
+
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
156
|
+
if (firstTextDelta) {
|
|
157
|
+
ttftMs = Date.now() - streamStart;
|
|
158
|
+
firstTextDelta = false;
|
|
159
|
+
}
|
|
160
|
+
output += event.delta.text;
|
|
161
|
+
}
|
|
162
|
+
if (event.delta?.type === "input_json_delta" && event.delta.partial_json) {
|
|
163
|
+
const idx = event.index ?? currentToolIndex;
|
|
164
|
+
const accum = toolCallAccum.get(idx);
|
|
165
|
+
if (accum) accum.input += event.delta.partial_json;
|
|
166
|
+
}
|
|
167
|
+
break;
|
|
168
|
+
case "message_delta":
|
|
169
|
+
outputTokens = event.usage?.output_tokens ?? outputTokens;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const finalizeStream = () => {
|
|
174
|
+
if (finalized) return;
|
|
175
|
+
finalized = true;
|
|
176
|
+
for (const tc of Array.from(toolCallAccum.values())) createToolSpan(tracer, root, {
|
|
177
|
+
id: tc.id,
|
|
178
|
+
name: tc.name,
|
|
179
|
+
arguments: tc.input
|
|
180
|
+
}).end({ status: "completed" });
|
|
181
|
+
endRootHandle(root, {
|
|
182
|
+
output,
|
|
183
|
+
inputTokens,
|
|
184
|
+
outputTokens,
|
|
185
|
+
ttftMs
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
const originalIterator = stream[Symbol.asyncIterator].bind(stream);
|
|
189
|
+
return new Proxy(stream, { get(target, prop, receiver) {
|
|
190
|
+
if (prop === Symbol.asyncIterator) return () => {
|
|
191
|
+
const iter = originalIterator();
|
|
192
|
+
return {
|
|
193
|
+
async next() {
|
|
194
|
+
const result = await iter.next();
|
|
195
|
+
if (!result.done) processEvent(result.value);
|
|
196
|
+
if (result.done) finalizeStream();
|
|
197
|
+
return result;
|
|
198
|
+
},
|
|
199
|
+
async return(value) {
|
|
200
|
+
finalizeStream();
|
|
201
|
+
return iter.return?.(value) ?? {
|
|
202
|
+
done: true,
|
|
203
|
+
value: void 0
|
|
204
|
+
};
|
|
205
|
+
},
|
|
206
|
+
async throw(err) {
|
|
207
|
+
cleanupOnError(root, err);
|
|
208
|
+
return iter.throw?.(err) ?? {
|
|
209
|
+
done: true,
|
|
210
|
+
value: void 0
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
};
|
|
215
|
+
if (prop === "tee") return;
|
|
216
|
+
return Reflect.get(target, prop, receiver);
|
|
217
|
+
} });
|
|
218
|
+
} catch (error) {
|
|
219
|
+
cleanupOnError(root, error);
|
|
220
|
+
throw error;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
//#endregion
|
|
225
|
+
exports.prismAnthropic = prismAnthropic;
|
|
226
|
+
//# sourceMappingURL=anthropic.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.cjs","names":[],"sources":["../../src/integrations/anthropic.ts"],"sourcesContent":["import type { AuixPrism, SpanHandle, TraceHandle } from \"../client\";\n\nexport interface AnthropicPrismOptions {\n name?: string;\n tags?: string[];\n metadata?: Record<string, unknown>;\n parentTraceId?: string;\n endUserId?: string;\n}\n\ntype RootHandle =\n | { isSpanMode: true; traceId: string; handle: SpanHandle }\n | { isSpanMode: false; traceId: string; handle: TraceHandle };\n\nfunction truncateInput(messages: unknown, maxBytes = 32768): unknown {\n let json = JSON.stringify(messages);\n if (new TextEncoder().encode(json).length <= maxBytes) {\n return messages;\n }\n\n if (!Array.isArray(messages)) return messages;\n const arr = [...messages];\n while (arr.length > 1) {\n arr.shift();\n json = JSON.stringify(arr);\n if (new TextEncoder().encode(json).length <= maxBytes) {\n return arr;\n }\n }\n return arr;\n}\n\nfunction createRootHandle(\n tracer: AuixPrism,\n opts: AnthropicPrismOptions | undefined,\n model: string,\n input: unknown,\n metadata: Record<string, unknown> | undefined,\n): RootHandle {\n const parentTraceId = opts?.parentTraceId;\n\n if (parentTraceId) {\n const handle = tracer.startSpanOnTrace(parentTraceId, {\n name: opts?.name ?? model,\n type: \"llm\",\n input,\n model,\n provider: \"anthropic\",\n metadata,\n });\n return { isSpanMode: true, traceId: parentTraceId, handle };\n }\n\n const handle = tracer.startTrace({\n name: opts?.name ?? model,\n model,\n provider: \"anthropic\",\n input,\n metadata,\n tags: opts?.tags,\n endUserId: opts?.endUserId,\n });\n return { isSpanMode: false, traceId: handle.traceId, handle };\n}\n\nfunction createToolSpan(\n tracer: AuixPrism,\n root: RootHandle,\n toolCall: { id: string; name: string; arguments: string },\n): SpanHandle {\n if (root.isSpanMode) {\n return tracer.startSpanOnTrace(root.traceId, {\n name: toolCall.name,\n type: \"tool\",\n input: toolCall.arguments,\n parentSpanId: root.handle.spanId,\n });\n }\n return root.handle.startSpan({\n name: toolCall.name,\n type: \"tool\",\n input: toolCall.arguments,\n });\n}\n\nfunction endRootHandle(\n root: RootHandle,\n result: {\n output: string;\n inputTokens: number;\n outputTokens: number;\n ttftMs?: number;\n },\n): void {\n root.handle.end({\n output: result.output,\n status: \"completed\",\n totalTokens: result.inputTokens + result.outputTokens,\n promptTokens: result.inputTokens,\n completionTokens: result.outputTokens,\n ttftMs: result.ttftMs,\n });\n}\n\nfunction cleanupOnError(root: RootHandle, error: unknown): void {\n root.handle.end({\n status: \"error\",\n error: error instanceof Error ? error.message : String(error),\n });\n}\n\ninterface StreamEvent {\n type: string;\n message?: { usage?: { input_tokens?: number } };\n index?: number;\n content_block?: {\n type: string;\n id?: string;\n name?: string;\n text?: string;\n };\n delta?: {\n type: string;\n text?: string;\n partial_json?: string;\n stop_reason?: string;\n };\n usage?: { output_tokens?: number };\n}\n\ninterface AccumulatedToolCall {\n id: string;\n name: string;\n input: string;\n}\n\n/**\n * Wraps an Anthropic client to automatically trace `messages.create` calls.\n *\n * Returns a proxy that behaves identically to the original client, but emits\n * trace events for both streaming and non-streaming message calls.\n */\nexport function prismAnthropic<T extends object>(\n tracer: AuixPrism,\n client: T,\n opts?: AnthropicPrismOptions,\n): T {\n return new Proxy(client, {\n get(target, prop, receiver) {\n if (prop === \"messages\") {\n const messages = Reflect.get(target, prop, receiver) as object;\n return new Proxy(messages, {\n get(msgTarget, msgProp, msgReceiver) {\n if (msgProp === \"create\") {\n return createInterceptor(\n tracer,\n Reflect.get(msgTarget, msgProp, msgReceiver).bind(msgTarget),\n opts,\n );\n }\n return Reflect.get(msgTarget, msgProp, msgReceiver);\n },\n });\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n}\n\nfunction createInterceptor(\n tracer: AuixPrism,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n opts?: AnthropicPrismOptions,\n) {\n return async (params: Record<string, unknown>, ...rest: unknown[]) => {\n const model = (params.model as string) ?? \"unknown\";\n const input = truncateInput(params.messages);\n const metadata = opts?.metadata;\n const isStream = !!params.stream;\n\n const root = createRootHandle(tracer, opts, model, input, metadata);\n\n if (!isStream) {\n return handleNonStreaming(tracer, root, originalCreate, params, rest);\n }\n\n return handleStreaming(tracer, root, originalCreate, params, rest);\n };\n}\n\nasync function handleNonStreaming(\n tracer: AuixPrism,\n root: RootHandle,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n params: Record<string, unknown>,\n rest: unknown[],\n): Promise<unknown> {\n try {\n const result = (await originalCreate(params, ...rest)) as {\n content?: Array<\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: unknown }\n >;\n usage?: { input_tokens?: number; output_tokens?: number };\n };\n\n const content = result.content ?? [];\n const output = content\n .filter((b): b is { type: \"text\"; text: string } => b.type === \"text\")\n .map((b) => b.text)\n .join(\"\");\n\n const inputTokens = result.usage?.input_tokens ?? 0;\n const outputTokens = result.usage?.output_tokens ?? 0;\n\n const toolUseBlocks = content.filter(\n (\n b,\n ): b is { type: \"tool_use\"; id: string; name: string; input: unknown } =>\n b.type === \"tool_use\",\n );\n\n for (const tc of toolUseBlocks) {\n const span = createToolSpan(tracer, root, {\n id: tc.id,\n name: tc.name,\n arguments: JSON.stringify(tc.input),\n });\n span.end({ status: \"completed\" });\n }\n\n endRootHandle(root, { output, inputTokens, outputTokens });\n return result;\n } catch (error) {\n cleanupOnError(root, error);\n throw error;\n }\n}\n\nasync function handleStreaming(\n tracer: AuixPrism,\n root: RootHandle,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n params: Record<string, unknown>,\n rest: unknown[],\n): Promise<unknown> {\n try {\n const streamStart = Date.now();\n const stream = await originalCreate(params, ...rest);\n\n let output = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n let ttftMs: number | undefined;\n let firstTextDelta = true;\n let finalized = false;\n const toolCallAccum = new Map<number, AccumulatedToolCall>();\n let currentToolIndex = -1;\n\n const processEvent = (event: StreamEvent) => {\n switch (event.type) {\n case \"message_start\": {\n inputTokens = event.message?.usage?.input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (event.content_block?.type === \"tool_use\") {\n currentToolIndex = event.index ?? currentToolIndex + 1;\n toolCallAccum.set(currentToolIndex, {\n id: event.content_block.id ?? \"\",\n name: event.content_block.name ?? \"\",\n input: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n if (event.delta?.type === \"text_delta\" && event.delta.text) {\n if (firstTextDelta) {\n ttftMs = Date.now() - streamStart;\n firstTextDelta = false;\n }\n output += event.delta.text;\n }\n if (\n event.delta?.type === \"input_json_delta\" &&\n event.delta.partial_json\n ) {\n const idx = event.index ?? currentToolIndex;\n const accum = toolCallAccum.get(idx);\n if (accum) {\n accum.input += event.delta.partial_json;\n }\n }\n break;\n }\n case \"message_delta\": {\n outputTokens = event.usage?.output_tokens ?? outputTokens;\n break;\n }\n }\n };\n\n const finalizeStream = () => {\n if (finalized) return;\n finalized = true;\n\n for (const tc of Array.from(toolCallAccum.values())) {\n const span = createToolSpan(tracer, root, {\n id: tc.id,\n name: tc.name,\n arguments: tc.input,\n });\n span.end({ status: \"completed\" });\n }\n\n endRootHandle(root, { output, inputTokens, outputTokens, ttftMs });\n };\n\n const originalIterator = (\n stream as { [Symbol.asyncIterator](): AsyncIterator<unknown> }\n )[Symbol.asyncIterator].bind(stream);\n\n return new Proxy(stream as object, {\n get(target, prop, receiver) {\n if (prop === Symbol.asyncIterator) {\n return () => {\n const iter = originalIterator();\n return {\n async next() {\n const result = await iter.next();\n if (!result.done) {\n processEvent(result.value as StreamEvent);\n }\n if (result.done) {\n finalizeStream();\n }\n return result;\n },\n async return(value?: unknown) {\n finalizeStream();\n return iter.return?.(value) ?? { done: true, value: undefined };\n },\n async throw(err?: unknown) {\n cleanupOnError(root, err);\n return iter.throw?.(err) ?? { done: true, value: undefined };\n },\n };\n };\n }\n if (prop === \"tee\") {\n return undefined;\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n } catch (error) {\n cleanupOnError(root, error);\n throw error;\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { t as AuixPrism } from "../client-BSsSpkZY.cjs";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/anthropic.d.ts
|
|
4
|
+
interface AnthropicPrismOptions {
|
|
5
|
+
name?: string;
|
|
6
|
+
tags?: string[];
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
parentTraceId?: string;
|
|
9
|
+
endUserId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Wraps an Anthropic client to automatically trace `messages.create` calls.
|
|
13
|
+
*
|
|
14
|
+
* Returns a proxy that behaves identically to the original client, but emits
|
|
15
|
+
* trace events for both streaming and non-streaming message calls.
|
|
16
|
+
*/
|
|
17
|
+
declare function prismAnthropic<T extends object>(tracer: AuixPrism, client: T, opts?: AnthropicPrismOptions): T;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { AnthropicPrismOptions, prismAnthropic };
|
|
20
|
+
//# sourceMappingURL=anthropic.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.cts","names":[],"sources":["../../src/integrations/anthropic.ts"],"mappings":";;;UAEiB,qBAAA;EACf,IAAA;EACA,IAAA;EACA,QAAA,GAAW,MAAA;EACX,aAAA;EACA,SAAA;AAAA;;;;;;;iBAuIc,cAAA,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,CAAA,EACR,IAAA,GAAO,qBAAA,GACN,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { t as AuixPrism } from "../client-BrZstMQX.js";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/anthropic.d.ts
|
|
4
|
+
interface AnthropicPrismOptions {
|
|
5
|
+
name?: string;
|
|
6
|
+
tags?: string[];
|
|
7
|
+
metadata?: Record<string, unknown>;
|
|
8
|
+
parentTraceId?: string;
|
|
9
|
+
endUserId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Wraps an Anthropic client to automatically trace `messages.create` calls.
|
|
13
|
+
*
|
|
14
|
+
* Returns a proxy that behaves identically to the original client, but emits
|
|
15
|
+
* trace events for both streaming and non-streaming message calls.
|
|
16
|
+
*/
|
|
17
|
+
declare function prismAnthropic<T extends object>(tracer: AuixPrism, client: T, opts?: AnthropicPrismOptions): T;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { AnthropicPrismOptions, prismAnthropic };
|
|
20
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","names":[],"sources":["../../src/integrations/anthropic.ts"],"mappings":";;;UAEiB,qBAAA;EACf,IAAA;EACA,IAAA;EACA,QAAA,GAAW,MAAA;EACX,aAAA;EACA,SAAA;AAAA;;;;;;;iBAuIc,cAAA,kBAAA,CACd,MAAA,EAAQ,SAAA,EACR,MAAA,EAAQ,CAAA,EACR,IAAA,GAAO,qBAAA,GACN,CAAA"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
//#region src/integrations/anthropic.ts
|
|
2
|
+
function truncateInput(messages, maxBytes = 32768) {
|
|
3
|
+
let json = JSON.stringify(messages);
|
|
4
|
+
if (new TextEncoder().encode(json).length <= maxBytes) return messages;
|
|
5
|
+
if (!Array.isArray(messages)) return messages;
|
|
6
|
+
const arr = [...messages];
|
|
7
|
+
while (arr.length > 1) {
|
|
8
|
+
arr.shift();
|
|
9
|
+
json = JSON.stringify(arr);
|
|
10
|
+
if (new TextEncoder().encode(json).length <= maxBytes) return arr;
|
|
11
|
+
}
|
|
12
|
+
return arr;
|
|
13
|
+
}
|
|
14
|
+
function createRootHandle(tracer, opts, model, input, metadata) {
|
|
15
|
+
const parentTraceId = opts?.parentTraceId;
|
|
16
|
+
if (parentTraceId) return {
|
|
17
|
+
isSpanMode: true,
|
|
18
|
+
traceId: parentTraceId,
|
|
19
|
+
handle: tracer.startSpanOnTrace(parentTraceId, {
|
|
20
|
+
name: opts?.name ?? model,
|
|
21
|
+
type: "llm",
|
|
22
|
+
input,
|
|
23
|
+
model,
|
|
24
|
+
provider: "anthropic",
|
|
25
|
+
metadata
|
|
26
|
+
})
|
|
27
|
+
};
|
|
28
|
+
const handle = tracer.startTrace({
|
|
29
|
+
name: opts?.name ?? model,
|
|
30
|
+
model,
|
|
31
|
+
provider: "anthropic",
|
|
32
|
+
input,
|
|
33
|
+
metadata,
|
|
34
|
+
tags: opts?.tags,
|
|
35
|
+
endUserId: opts?.endUserId
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
isSpanMode: false,
|
|
39
|
+
traceId: handle.traceId,
|
|
40
|
+
handle
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function createToolSpan(tracer, root, toolCall) {
|
|
44
|
+
if (root.isSpanMode) return tracer.startSpanOnTrace(root.traceId, {
|
|
45
|
+
name: toolCall.name,
|
|
46
|
+
type: "tool",
|
|
47
|
+
input: toolCall.arguments,
|
|
48
|
+
parentSpanId: root.handle.spanId
|
|
49
|
+
});
|
|
50
|
+
return root.handle.startSpan({
|
|
51
|
+
name: toolCall.name,
|
|
52
|
+
type: "tool",
|
|
53
|
+
input: toolCall.arguments
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function endRootHandle(root, result) {
|
|
57
|
+
root.handle.end({
|
|
58
|
+
output: result.output,
|
|
59
|
+
status: "completed",
|
|
60
|
+
totalTokens: result.inputTokens + result.outputTokens,
|
|
61
|
+
promptTokens: result.inputTokens,
|
|
62
|
+
completionTokens: result.outputTokens,
|
|
63
|
+
ttftMs: result.ttftMs
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function cleanupOnError(root, error) {
|
|
67
|
+
root.handle.end({
|
|
68
|
+
status: "error",
|
|
69
|
+
error: error instanceof Error ? error.message : String(error)
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Wraps an Anthropic client to automatically trace `messages.create` calls.
|
|
74
|
+
*
|
|
75
|
+
* Returns a proxy that behaves identically to the original client, but emits
|
|
76
|
+
* trace events for both streaming and non-streaming message calls.
|
|
77
|
+
*/
|
|
78
|
+
function prismAnthropic(tracer, client, opts) {
|
|
79
|
+
return new Proxy(client, { get(target, prop, receiver) {
|
|
80
|
+
if (prop === "messages") {
|
|
81
|
+
const messages = Reflect.get(target, prop, receiver);
|
|
82
|
+
return new Proxy(messages, { get(msgTarget, msgProp, msgReceiver) {
|
|
83
|
+
if (msgProp === "create") return createInterceptor(tracer, Reflect.get(msgTarget, msgProp, msgReceiver).bind(msgTarget), opts);
|
|
84
|
+
return Reflect.get(msgTarget, msgProp, msgReceiver);
|
|
85
|
+
} });
|
|
86
|
+
}
|
|
87
|
+
return Reflect.get(target, prop, receiver);
|
|
88
|
+
} });
|
|
89
|
+
}
|
|
90
|
+
function createInterceptor(tracer, originalCreate, opts) {
|
|
91
|
+
return async (params, ...rest) => {
|
|
92
|
+
const model = params.model ?? "unknown";
|
|
93
|
+
const input = truncateInput(params.messages);
|
|
94
|
+
const metadata = opts?.metadata;
|
|
95
|
+
const isStream = !!params.stream;
|
|
96
|
+
const root = createRootHandle(tracer, opts, model, input, metadata);
|
|
97
|
+
if (!isStream) return handleNonStreaming(tracer, root, originalCreate, params, rest);
|
|
98
|
+
return handleStreaming(tracer, root, originalCreate, params, rest);
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
async function handleNonStreaming(tracer, root, originalCreate, params, rest) {
|
|
102
|
+
try {
|
|
103
|
+
const result = await originalCreate(params, ...rest);
|
|
104
|
+
const content = result.content ?? [];
|
|
105
|
+
const output = content.filter((b) => b.type === "text").map((b) => b.text).join("");
|
|
106
|
+
const inputTokens = result.usage?.input_tokens ?? 0;
|
|
107
|
+
const outputTokens = result.usage?.output_tokens ?? 0;
|
|
108
|
+
const toolUseBlocks = content.filter((b) => b.type === "tool_use");
|
|
109
|
+
for (const tc of toolUseBlocks) createToolSpan(tracer, root, {
|
|
110
|
+
id: tc.id,
|
|
111
|
+
name: tc.name,
|
|
112
|
+
arguments: JSON.stringify(tc.input)
|
|
113
|
+
}).end({ status: "completed" });
|
|
114
|
+
endRootHandle(root, {
|
|
115
|
+
output,
|
|
116
|
+
inputTokens,
|
|
117
|
+
outputTokens
|
|
118
|
+
});
|
|
119
|
+
return result;
|
|
120
|
+
} catch (error) {
|
|
121
|
+
cleanupOnError(root, error);
|
|
122
|
+
throw error;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
async function handleStreaming(tracer, root, originalCreate, params, rest) {
|
|
126
|
+
try {
|
|
127
|
+
const streamStart = Date.now();
|
|
128
|
+
const stream = await originalCreate(params, ...rest);
|
|
129
|
+
let output = "";
|
|
130
|
+
let inputTokens = 0;
|
|
131
|
+
let outputTokens = 0;
|
|
132
|
+
let ttftMs;
|
|
133
|
+
let firstTextDelta = true;
|
|
134
|
+
let finalized = false;
|
|
135
|
+
const toolCallAccum = /* @__PURE__ */ new Map();
|
|
136
|
+
let currentToolIndex = -1;
|
|
137
|
+
const processEvent = (event) => {
|
|
138
|
+
switch (event.type) {
|
|
139
|
+
case "message_start":
|
|
140
|
+
inputTokens = event.message?.usage?.input_tokens ?? 0;
|
|
141
|
+
break;
|
|
142
|
+
case "content_block_start":
|
|
143
|
+
if (event.content_block?.type === "tool_use") {
|
|
144
|
+
currentToolIndex = event.index ?? currentToolIndex + 1;
|
|
145
|
+
toolCallAccum.set(currentToolIndex, {
|
|
146
|
+
id: event.content_block.id ?? "",
|
|
147
|
+
name: event.content_block.name ?? "",
|
|
148
|
+
input: ""
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
case "content_block_delta":
|
|
153
|
+
if (event.delta?.type === "text_delta" && event.delta.text) {
|
|
154
|
+
if (firstTextDelta) {
|
|
155
|
+
ttftMs = Date.now() - streamStart;
|
|
156
|
+
firstTextDelta = false;
|
|
157
|
+
}
|
|
158
|
+
output += event.delta.text;
|
|
159
|
+
}
|
|
160
|
+
if (event.delta?.type === "input_json_delta" && event.delta.partial_json) {
|
|
161
|
+
const idx = event.index ?? currentToolIndex;
|
|
162
|
+
const accum = toolCallAccum.get(idx);
|
|
163
|
+
if (accum) accum.input += event.delta.partial_json;
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
case "message_delta":
|
|
167
|
+
outputTokens = event.usage?.output_tokens ?? outputTokens;
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
const finalizeStream = () => {
|
|
172
|
+
if (finalized) return;
|
|
173
|
+
finalized = true;
|
|
174
|
+
for (const tc of Array.from(toolCallAccum.values())) createToolSpan(tracer, root, {
|
|
175
|
+
id: tc.id,
|
|
176
|
+
name: tc.name,
|
|
177
|
+
arguments: tc.input
|
|
178
|
+
}).end({ status: "completed" });
|
|
179
|
+
endRootHandle(root, {
|
|
180
|
+
output,
|
|
181
|
+
inputTokens,
|
|
182
|
+
outputTokens,
|
|
183
|
+
ttftMs
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
const originalIterator = stream[Symbol.asyncIterator].bind(stream);
|
|
187
|
+
return new Proxy(stream, { get(target, prop, receiver) {
|
|
188
|
+
if (prop === Symbol.asyncIterator) return () => {
|
|
189
|
+
const iter = originalIterator();
|
|
190
|
+
return {
|
|
191
|
+
async next() {
|
|
192
|
+
const result = await iter.next();
|
|
193
|
+
if (!result.done) processEvent(result.value);
|
|
194
|
+
if (result.done) finalizeStream();
|
|
195
|
+
return result;
|
|
196
|
+
},
|
|
197
|
+
async return(value) {
|
|
198
|
+
finalizeStream();
|
|
199
|
+
return iter.return?.(value) ?? {
|
|
200
|
+
done: true,
|
|
201
|
+
value: void 0
|
|
202
|
+
};
|
|
203
|
+
},
|
|
204
|
+
async throw(err) {
|
|
205
|
+
cleanupOnError(root, err);
|
|
206
|
+
return iter.throw?.(err) ?? {
|
|
207
|
+
done: true,
|
|
208
|
+
value: void 0
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
};
|
|
212
|
+
};
|
|
213
|
+
if (prop === "tee") return;
|
|
214
|
+
return Reflect.get(target, prop, receiver);
|
|
215
|
+
} });
|
|
216
|
+
} catch (error) {
|
|
217
|
+
cleanupOnError(root, error);
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
//#endregion
|
|
223
|
+
export { prismAnthropic };
|
|
224
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","names":[],"sources":["../../src/integrations/anthropic.ts"],"sourcesContent":["import type { AuixPrism, SpanHandle, TraceHandle } from \"../client\";\n\nexport interface AnthropicPrismOptions {\n name?: string;\n tags?: string[];\n metadata?: Record<string, unknown>;\n parentTraceId?: string;\n endUserId?: string;\n}\n\ntype RootHandle =\n | { isSpanMode: true; traceId: string; handle: SpanHandle }\n | { isSpanMode: false; traceId: string; handle: TraceHandle };\n\nfunction truncateInput(messages: unknown, maxBytes = 32768): unknown {\n let json = JSON.stringify(messages);\n if (new TextEncoder().encode(json).length <= maxBytes) {\n return messages;\n }\n\n if (!Array.isArray(messages)) return messages;\n const arr = [...messages];\n while (arr.length > 1) {\n arr.shift();\n json = JSON.stringify(arr);\n if (new TextEncoder().encode(json).length <= maxBytes) {\n return arr;\n }\n }\n return arr;\n}\n\nfunction createRootHandle(\n tracer: AuixPrism,\n opts: AnthropicPrismOptions | undefined,\n model: string,\n input: unknown,\n metadata: Record<string, unknown> | undefined,\n): RootHandle {\n const parentTraceId = opts?.parentTraceId;\n\n if (parentTraceId) {\n const handle = tracer.startSpanOnTrace(parentTraceId, {\n name: opts?.name ?? model,\n type: \"llm\",\n input,\n model,\n provider: \"anthropic\",\n metadata,\n });\n return { isSpanMode: true, traceId: parentTraceId, handle };\n }\n\n const handle = tracer.startTrace({\n name: opts?.name ?? model,\n model,\n provider: \"anthropic\",\n input,\n metadata,\n tags: opts?.tags,\n endUserId: opts?.endUserId,\n });\n return { isSpanMode: false, traceId: handle.traceId, handle };\n}\n\nfunction createToolSpan(\n tracer: AuixPrism,\n root: RootHandle,\n toolCall: { id: string; name: string; arguments: string },\n): SpanHandle {\n if (root.isSpanMode) {\n return tracer.startSpanOnTrace(root.traceId, {\n name: toolCall.name,\n type: \"tool\",\n input: toolCall.arguments,\n parentSpanId: root.handle.spanId,\n });\n }\n return root.handle.startSpan({\n name: toolCall.name,\n type: \"tool\",\n input: toolCall.arguments,\n });\n}\n\nfunction endRootHandle(\n root: RootHandle,\n result: {\n output: string;\n inputTokens: number;\n outputTokens: number;\n ttftMs?: number;\n },\n): void {\n root.handle.end({\n output: result.output,\n status: \"completed\",\n totalTokens: result.inputTokens + result.outputTokens,\n promptTokens: result.inputTokens,\n completionTokens: result.outputTokens,\n ttftMs: result.ttftMs,\n });\n}\n\nfunction cleanupOnError(root: RootHandle, error: unknown): void {\n root.handle.end({\n status: \"error\",\n error: error instanceof Error ? error.message : String(error),\n });\n}\n\ninterface StreamEvent {\n type: string;\n message?: { usage?: { input_tokens?: number } };\n index?: number;\n content_block?: {\n type: string;\n id?: string;\n name?: string;\n text?: string;\n };\n delta?: {\n type: string;\n text?: string;\n partial_json?: string;\n stop_reason?: string;\n };\n usage?: { output_tokens?: number };\n}\n\ninterface AccumulatedToolCall {\n id: string;\n name: string;\n input: string;\n}\n\n/**\n * Wraps an Anthropic client to automatically trace `messages.create` calls.\n *\n * Returns a proxy that behaves identically to the original client, but emits\n * trace events for both streaming and non-streaming message calls.\n */\nexport function prismAnthropic<T extends object>(\n tracer: AuixPrism,\n client: T,\n opts?: AnthropicPrismOptions,\n): T {\n return new Proxy(client, {\n get(target, prop, receiver) {\n if (prop === \"messages\") {\n const messages = Reflect.get(target, prop, receiver) as object;\n return new Proxy(messages, {\n get(msgTarget, msgProp, msgReceiver) {\n if (msgProp === \"create\") {\n return createInterceptor(\n tracer,\n Reflect.get(msgTarget, msgProp, msgReceiver).bind(msgTarget),\n opts,\n );\n }\n return Reflect.get(msgTarget, msgProp, msgReceiver);\n },\n });\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n}\n\nfunction createInterceptor(\n tracer: AuixPrism,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n opts?: AnthropicPrismOptions,\n) {\n return async (params: Record<string, unknown>, ...rest: unknown[]) => {\n const model = (params.model as string) ?? \"unknown\";\n const input = truncateInput(params.messages);\n const metadata = opts?.metadata;\n const isStream = !!params.stream;\n\n const root = createRootHandle(tracer, opts, model, input, metadata);\n\n if (!isStream) {\n return handleNonStreaming(tracer, root, originalCreate, params, rest);\n }\n\n return handleStreaming(tracer, root, originalCreate, params, rest);\n };\n}\n\nasync function handleNonStreaming(\n tracer: AuixPrism,\n root: RootHandle,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n params: Record<string, unknown>,\n rest: unknown[],\n): Promise<unknown> {\n try {\n const result = (await originalCreate(params, ...rest)) as {\n content?: Array<\n | { type: \"text\"; text: string }\n | { type: \"tool_use\"; id: string; name: string; input: unknown }\n >;\n usage?: { input_tokens?: number; output_tokens?: number };\n };\n\n const content = result.content ?? [];\n const output = content\n .filter((b): b is { type: \"text\"; text: string } => b.type === \"text\")\n .map((b) => b.text)\n .join(\"\");\n\n const inputTokens = result.usage?.input_tokens ?? 0;\n const outputTokens = result.usage?.output_tokens ?? 0;\n\n const toolUseBlocks = content.filter(\n (\n b,\n ): b is { type: \"tool_use\"; id: string; name: string; input: unknown } =>\n b.type === \"tool_use\",\n );\n\n for (const tc of toolUseBlocks) {\n const span = createToolSpan(tracer, root, {\n id: tc.id,\n name: tc.name,\n arguments: JSON.stringify(tc.input),\n });\n span.end({ status: \"completed\" });\n }\n\n endRootHandle(root, { output, inputTokens, outputTokens });\n return result;\n } catch (error) {\n cleanupOnError(root, error);\n throw error;\n }\n}\n\nasync function handleStreaming(\n tracer: AuixPrism,\n root: RootHandle,\n originalCreate: (...args: unknown[]) => Promise<unknown>,\n params: Record<string, unknown>,\n rest: unknown[],\n): Promise<unknown> {\n try {\n const streamStart = Date.now();\n const stream = await originalCreate(params, ...rest);\n\n let output = \"\";\n let inputTokens = 0;\n let outputTokens = 0;\n let ttftMs: number | undefined;\n let firstTextDelta = true;\n let finalized = false;\n const toolCallAccum = new Map<number, AccumulatedToolCall>();\n let currentToolIndex = -1;\n\n const processEvent = (event: StreamEvent) => {\n switch (event.type) {\n case \"message_start\": {\n inputTokens = event.message?.usage?.input_tokens ?? 0;\n break;\n }\n case \"content_block_start\": {\n if (event.content_block?.type === \"tool_use\") {\n currentToolIndex = event.index ?? currentToolIndex + 1;\n toolCallAccum.set(currentToolIndex, {\n id: event.content_block.id ?? \"\",\n name: event.content_block.name ?? \"\",\n input: \"\",\n });\n }\n break;\n }\n case \"content_block_delta\": {\n if (event.delta?.type === \"text_delta\" && event.delta.text) {\n if (firstTextDelta) {\n ttftMs = Date.now() - streamStart;\n firstTextDelta = false;\n }\n output += event.delta.text;\n }\n if (\n event.delta?.type === \"input_json_delta\" &&\n event.delta.partial_json\n ) {\n const idx = event.index ?? currentToolIndex;\n const accum = toolCallAccum.get(idx);\n if (accum) {\n accum.input += event.delta.partial_json;\n }\n }\n break;\n }\n case \"message_delta\": {\n outputTokens = event.usage?.output_tokens ?? outputTokens;\n break;\n }\n }\n };\n\n const finalizeStream = () => {\n if (finalized) return;\n finalized = true;\n\n for (const tc of Array.from(toolCallAccum.values())) {\n const span = createToolSpan(tracer, root, {\n id: tc.id,\n name: tc.name,\n arguments: tc.input,\n });\n span.end({ status: \"completed\" });\n }\n\n endRootHandle(root, { output, inputTokens, outputTokens, ttftMs });\n };\n\n const originalIterator = (\n stream as { [Symbol.asyncIterator](): AsyncIterator<unknown> }\n )[Symbol.asyncIterator].bind(stream);\n\n return new Proxy(stream as object, {\n get(target, prop, receiver) {\n if (prop === Symbol.asyncIterator) {\n return () => {\n const iter = originalIterator();\n return {\n async next() {\n const result = await iter.next();\n if (!result.done) {\n processEvent(result.value as StreamEvent);\n }\n if (result.done) {\n finalizeStream();\n }\n return result;\n },\n async return(value?: unknown) {\n finalizeStream();\n return iter.return?.(value) ?? { done: true, value: undefined };\n },\n async throw(err?: unknown) {\n cleanupOnError(root, err);\n return iter.throw?.(err) ?? { done: true, value: undefined };\n },\n };\n };\n }\n if (prop === \"tee\") {\n return undefined;\n }\n return Reflect.get(target, prop, receiver);\n },\n });\n } catch (error) {\n cleanupOnError(root, error);\n throw error;\n }\n}\n"],"mappings":"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"}
|