@posthog/ai 8.6.2 → 8.6.4
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/anthropic/index.cjs +415 -115
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.d.ts +2 -3
- package/dist/anthropic/index.mjs +414 -114
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +122 -114
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +122 -114
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +122 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +122 -114
- package/dist/index.mjs.map +1 -1
- package/dist/langchain/index.cjs +10 -3
- package/dist/langchain/index.cjs.map +1 -1
- package/dist/langchain/index.d.ts +1 -0
- package/dist/langchain/index.mjs +10 -3
- package/dist/langchain/index.mjs.map +1 -1
- package/dist/openai/index.cjs +508 -219
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.d.ts +2 -2
- package/dist/openai/index.mjs +508 -219
- package/dist/openai/index.mjs.map +1 -1
- package/dist/openai-agents/index.cjs +1 -1
- package/dist/openai-agents/index.mjs +1 -1
- package/dist/vercel/index.cjs +122 -114
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +122 -114
- package/dist/vercel/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/anthropic/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var AnthropicOriginal = require('@anthropic-ai/sdk');
|
|
6
6
|
var uuid = require('uuid');
|
|
7
7
|
var core = require('@posthog/core');
|
|
8
|
+
var streaming = require('@anthropic-ai/sdk/streaming');
|
|
8
9
|
|
|
9
10
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
11
|
|
|
@@ -299,7 +300,7 @@ function addDefaults(params) {
|
|
|
299
300
|
};
|
|
300
301
|
}
|
|
301
302
|
|
|
302
|
-
var version = "8.6.
|
|
303
|
+
var version = "8.6.4";
|
|
303
304
|
|
|
304
305
|
const DEFAULT_MAX_DEPTH = 3;
|
|
305
306
|
const MAX_STACK_LINES = 20;
|
|
@@ -410,127 +411,420 @@ const warnIfPostHogAiGateway = baseURL => {
|
|
|
410
411
|
* so callers can re-throw the original error reference safely.
|
|
411
412
|
*/
|
|
412
413
|
const captureAiGeneration = async (client, options) => {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
warnIfPostHogAiGateway(options.baseURL);
|
|
417
|
-
const traceId = options.traceId ?? uuid.v4();
|
|
418
|
-
const eventType = options.eventType ?? AIEvent.Generation;
|
|
419
|
-
const privacyMode = options.privacyMode ?? false;
|
|
420
|
-
const usage = options.usage ?? {};
|
|
421
|
-
|
|
422
|
-
// Check privacy before reading or traversing input/output. Besides avoiding
|
|
423
|
-
// needless work, this ensures hostile getters/proxies cannot observe a value
|
|
424
|
-
// that the caller explicitly requested us to redact.
|
|
425
|
-
const shouldRedact = withPrivacyMode(client, privacyMode, false) === null;
|
|
426
|
-
const safeInput = shouldRedact ? null : core.toJsonSafeValue(options.input);
|
|
427
|
-
const safeOutput = shouldRedact ? null : core.toJsonSafeValue(options.output);
|
|
428
|
-
let httpStatus = options.httpStatus;
|
|
429
|
-
let errorData = {};
|
|
430
|
-
if (options.error) {
|
|
431
|
-
if (httpStatus === undefined) {
|
|
432
|
-
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
433
|
-
httpStatus = options.error.status;
|
|
434
|
-
} else {
|
|
435
|
-
httpStatus = 500;
|
|
436
|
-
}
|
|
414
|
+
try {
|
|
415
|
+
if (!client.capture) {
|
|
416
|
+
return;
|
|
437
417
|
}
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
418
|
+
warnIfPostHogAiGateway(options.baseURL);
|
|
419
|
+
const traceId = options.traceId ?? uuid.v4();
|
|
420
|
+
const eventType = options.eventType ?? AIEvent.Generation;
|
|
421
|
+
const privacyMode = options.privacyMode ?? false;
|
|
422
|
+
const usage = options.usage ?? {};
|
|
423
|
+
|
|
424
|
+
// Check privacy before reading or traversing input/output. Besides avoiding
|
|
425
|
+
// needless work, this ensures hostile getters/proxies cannot observe a value
|
|
426
|
+
// that the caller explicitly requested us to redact.
|
|
427
|
+
const shouldRedact = withPrivacyMode(client, privacyMode, false) === null;
|
|
428
|
+
const safeInput = shouldRedact ? null : core.toJsonSafeValue(options.input);
|
|
429
|
+
const safeOutput = shouldRedact ? null : core.toJsonSafeValue(options.output);
|
|
430
|
+
let httpStatus = options.httpStatus;
|
|
431
|
+
let errorData = {};
|
|
432
|
+
if (options.error) {
|
|
433
|
+
if (httpStatus === undefined) {
|
|
434
|
+
if (typeof options.error === 'object' && 'status' in options.error && typeof options.error.status === 'number') {
|
|
435
|
+
httpStatus = options.error.status;
|
|
436
|
+
} else if (typeof options.error === 'object' && 'statusCode' in options.error && typeof options.error.statusCode === 'number') {
|
|
437
|
+
httpStatus = options.error.statusCode;
|
|
438
|
+
} else {
|
|
439
|
+
httpStatus = 500;
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
let exceptionId;
|
|
443
|
+
if (client.options?.enableExceptionAutocapture) {
|
|
444
|
+
exceptionId = core.uuidv7();
|
|
445
|
+
client.captureException(options.error, undefined, {
|
|
446
|
+
$ai_trace_id: traceId
|
|
447
|
+
}, exceptionId);
|
|
448
|
+
if (typeof options.error === 'object') {
|
|
449
|
+
;
|
|
450
|
+
options.error.__posthog_previously_captured_error = true;
|
|
451
|
+
}
|
|
446
452
|
}
|
|
453
|
+
errorData = {
|
|
454
|
+
$ai_is_error: true,
|
|
455
|
+
$ai_error: stringifyError(options.error),
|
|
456
|
+
$exception_event_id: exceptionId
|
|
457
|
+
};
|
|
447
458
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
459
|
+
httpStatus = httpStatus ?? 200;
|
|
460
|
+
let costOverrideData = {};
|
|
461
|
+
if (options.costOverride) {
|
|
462
|
+
const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
463
|
+
const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
464
|
+
costOverrideData = {
|
|
465
|
+
$ai_input_cost_usd: inputCostUSD,
|
|
466
|
+
$ai_output_cost_usd: outputCostUSD,
|
|
467
|
+
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
const additionalTokenValues = {
|
|
471
|
+
...(usage.reasoningTokens ? {
|
|
472
|
+
$ai_reasoning_tokens: usage.reasoningTokens
|
|
473
|
+
} : {}),
|
|
474
|
+
...(usage.cacheReadInputTokens ? {
|
|
475
|
+
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
476
|
+
} : {}),
|
|
477
|
+
...(usage.cacheCreationInputTokens ? {
|
|
478
|
+
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
479
|
+
} : {}),
|
|
480
|
+
...(usage.webSearchCount ? {
|
|
481
|
+
$ai_web_search_count: usage.webSearchCount
|
|
482
|
+
} : {}),
|
|
483
|
+
...(usage.rawUsage ? {
|
|
484
|
+
$ai_usage: usage.rawUsage
|
|
485
|
+
} : {})
|
|
486
|
+
};
|
|
487
|
+
const properties = {
|
|
488
|
+
$ai_lib: 'posthog-ai',
|
|
489
|
+
$ai_lib_version: version,
|
|
490
|
+
$ai_provider: options.providerOverride ?? options.provider,
|
|
491
|
+
$ai_model: options.modelOverride ?? options.model,
|
|
492
|
+
$ai_model_parameters: options.modelParameters ?? {},
|
|
493
|
+
$ai_input: safeInput,
|
|
494
|
+
$ai_output_choices: safeOutput,
|
|
495
|
+
$ai_http_status: httpStatus,
|
|
496
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
497
|
+
...(usage.outputTokens !== undefined ? {
|
|
498
|
+
$ai_output_tokens: usage.outputTokens
|
|
499
|
+
} : {}),
|
|
500
|
+
...additionalTokenValues,
|
|
501
|
+
$ai_latency: options.latency ?? 0,
|
|
502
|
+
...(options.timeToFirstToken !== undefined ? {
|
|
503
|
+
$ai_time_to_first_token: options.timeToFirstToken
|
|
504
|
+
} : {}),
|
|
505
|
+
$ai_trace_id: traceId,
|
|
506
|
+
$ai_base_url: options.baseURL ?? '',
|
|
507
|
+
...options.properties,
|
|
508
|
+
$ai_tokens_source: getTokensSource(options.properties),
|
|
509
|
+
...(options.distinctId ? {} : {
|
|
510
|
+
$process_person_profile: false
|
|
511
|
+
}),
|
|
512
|
+
...(options.stopReason ? {
|
|
513
|
+
$ai_stop_reason: options.stopReason
|
|
514
|
+
} : {}),
|
|
515
|
+
...(options.tools ? {
|
|
516
|
+
$ai_tools: options.tools
|
|
517
|
+
} : {}),
|
|
518
|
+
...(options.completionId ? {
|
|
519
|
+
$ai_completion_id: options.completionId
|
|
520
|
+
} : {}),
|
|
521
|
+
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
522
|
+
$ai_provider_metadata: options.providerMetadata
|
|
523
|
+
} : {}),
|
|
524
|
+
...errorData,
|
|
525
|
+
...costOverrideData
|
|
526
|
+
};
|
|
527
|
+
const event = {
|
|
528
|
+
distinctId: options.distinctId ?? traceId,
|
|
529
|
+
event: eventType,
|
|
530
|
+
properties,
|
|
531
|
+
groups: options.groups
|
|
532
|
+
};
|
|
533
|
+
if (options.captureImmediate) {
|
|
534
|
+
await client.captureImmediate(event);
|
|
535
|
+
} else {
|
|
536
|
+
client.capture(event);
|
|
537
|
+
}
|
|
538
|
+
} catch (error) {
|
|
539
|
+
// Telemetry failures must never affect the instrumented provider call.
|
|
540
|
+
console.warn('[PostHog AI] Failed to capture generation telemetry:', error);
|
|
541
|
+
}
|
|
542
|
+
};
|
|
543
|
+
|
|
544
|
+
function addRequestId(result, response, requestIdHeader) {
|
|
545
|
+
if (!result || typeof result !== 'object' || Array.isArray(result)) {
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
548
|
+
return Object.defineProperty(result, '_request_id', {
|
|
549
|
+
value: response.headers.get(requestIdHeader),
|
|
550
|
+
enumerable: false
|
|
551
|
+
});
|
|
552
|
+
}
|
|
553
|
+
function getResponsePropsPromise(parentPromise) {
|
|
554
|
+
const responsePromise = parentPromise.responsePromise;
|
|
555
|
+
if (!responsePromise || typeof responsePromise.then !== 'function') {
|
|
556
|
+
return undefined;
|
|
557
|
+
}
|
|
558
|
+
return responsePromise;
|
|
559
|
+
}
|
|
560
|
+
function decorateProviderPromise(wrappedPromise, responsePropsPromise, requestIdHeader, preserveThenUnwrap) {
|
|
561
|
+
const providerPromise = wrappedPromise;
|
|
562
|
+
if (responsePropsPromise) {
|
|
563
|
+
providerPromise.asResponse = async () => (await responsePropsPromise).response;
|
|
564
|
+
providerPromise.withResponse = async () => {
|
|
565
|
+
const [props, data] = await Promise.all([responsePropsPromise, wrappedPromise]);
|
|
566
|
+
return {
|
|
567
|
+
response: props.response,
|
|
568
|
+
data,
|
|
569
|
+
request_id: props.response.headers.get(requestIdHeader)
|
|
570
|
+
};
|
|
452
571
|
};
|
|
453
572
|
}
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
$ai_output_cost_usd: outputCostUSD,
|
|
462
|
-
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
573
|
+
if (preserveThenUnwrap) {
|
|
574
|
+
providerPromise._thenUnwrap = transform => {
|
|
575
|
+
if (!responsePropsPromise) {
|
|
576
|
+
throw new Error('The provider promise response metadata is unavailable');
|
|
577
|
+
}
|
|
578
|
+
const transformedPromise = Promise.all([wrappedPromise, responsePropsPromise]).then(([data, props]) => addRequestId(transform(data, props), props.response, requestIdHeader));
|
|
579
|
+
return decorateProviderPromise(transformedPromise, responsePropsPromise, requestIdHeader, true);
|
|
463
580
|
};
|
|
464
581
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
582
|
+
return providerPromise;
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Keep the provider SDK helpers on a promise whose resolved value is instrumented.
|
|
587
|
+
* OpenAI's parse helpers compose create calls through `_thenUnwrap`, while both
|
|
588
|
+
* OpenAI and Anthropic expose the raw response through `asResponse` and
|
|
589
|
+
* `withResponse`.
|
|
590
|
+
*/
|
|
591
|
+
|
|
592
|
+
function preserveProviderPromise(parentPromise, wrappedPromise, options = {}) {
|
|
593
|
+
const responsePropsPromise = getResponsePropsPromise(parentPromise);
|
|
594
|
+
const preserveThenUnwrap = typeof parentPromise._thenUnwrap === 'function';
|
|
595
|
+
const providerPromise = decorateProviderPromise(wrappedPromise, responsePropsPromise, options.requestIdHeader ?? 'x-request-id', preserveThenUnwrap);
|
|
596
|
+
if (!responsePropsPromise) {
|
|
597
|
+
const asResponse = parentPromise.asResponse?.bind(parentPromise);
|
|
598
|
+
if (asResponse) {
|
|
599
|
+
providerPromise.asResponse = asResponse;
|
|
600
|
+
}
|
|
601
|
+
const withResponse = parentPromise.withResponse?.bind(parentPromise);
|
|
602
|
+
if (withResponse) {
|
|
603
|
+
providerPromise.withResponse = async () => {
|
|
604
|
+
const [response, data] = await Promise.all([withResponse(), wrappedPromise]);
|
|
605
|
+
return {
|
|
606
|
+
...response,
|
|
607
|
+
data
|
|
608
|
+
};
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
return providerPromise;
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Splits an SDK stream into a monitoring branch and a caller branch without
|
|
617
|
+
* allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
|
|
618
|
+
* implementations, this keeps at most one result in flight and makes caller
|
|
619
|
+
* cancellation terminate the monitoring branch and the source iterator.
|
|
620
|
+
*/
|
|
621
|
+
function monitoredStreamTee(source, createStream) {
|
|
622
|
+
const controller = source.controller ?? new AbortController();
|
|
623
|
+
const sourceIterator = source[Symbol.asyncIterator]();
|
|
624
|
+
const callerQueue = [];
|
|
625
|
+
let monitorPending;
|
|
626
|
+
let monitorActive = true;
|
|
627
|
+
let operationInFlight = false;
|
|
628
|
+
let terminalResult;
|
|
629
|
+
let bufferedMonitorResult;
|
|
630
|
+
let terminalError;
|
|
631
|
+
let hasTerminalError = false;
|
|
632
|
+
let cancellationPromise;
|
|
633
|
+
let abortListener;
|
|
634
|
+
const removeAbortListener = () => {
|
|
635
|
+
if (abortListener) {
|
|
636
|
+
controller.signal.removeEventListener('abort', abortListener);
|
|
637
|
+
abortListener = undefined;
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
const settleMonitorTerminal = () => {
|
|
641
|
+
if (!monitorPending) {
|
|
642
|
+
return;
|
|
643
|
+
}
|
|
644
|
+
const pending = monitorPending;
|
|
645
|
+
monitorPending = undefined;
|
|
646
|
+
if (hasTerminalError) {
|
|
647
|
+
pending.reject(terminalError);
|
|
648
|
+
} else if (terminalResult) {
|
|
649
|
+
pending.resolve(terminalResult);
|
|
650
|
+
}
|
|
481
651
|
};
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
652
|
+
const settleCallersTerminal = () => {
|
|
653
|
+
while (callerQueue.length > 0) {
|
|
654
|
+
const pending = callerQueue.shift();
|
|
655
|
+
if (hasTerminalError) {
|
|
656
|
+
pending.reject(terminalError);
|
|
657
|
+
} else if (terminalResult) {
|
|
658
|
+
pending.resolve(terminalResult);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
};
|
|
662
|
+
const pump = () => {
|
|
663
|
+
if (operationInFlight || callerQueue.length === 0 || monitorActive && !monitorPending) {
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
const pendingCaller = callerQueue.shift();
|
|
667
|
+
const pendingMonitor = monitorPending;
|
|
668
|
+
monitorPending = undefined;
|
|
669
|
+
operationInFlight = true;
|
|
670
|
+
void sourceIterator.next().then(result => {
|
|
671
|
+
operationInFlight = false;
|
|
672
|
+
if (result.done) {
|
|
673
|
+
terminalResult = result;
|
|
674
|
+
removeAbortListener();
|
|
675
|
+
}
|
|
676
|
+
pendingCaller.resolve(result);
|
|
677
|
+
pendingMonitor?.resolve(result);
|
|
678
|
+
if (result.done) {
|
|
679
|
+
settleCallersTerminal();
|
|
680
|
+
} else {
|
|
681
|
+
pump();
|
|
682
|
+
}
|
|
683
|
+
}, error => {
|
|
684
|
+
operationInFlight = false;
|
|
685
|
+
terminalError = error;
|
|
686
|
+
hasTerminalError = true;
|
|
687
|
+
removeAbortListener();
|
|
688
|
+
pendingCaller.reject(error);
|
|
689
|
+
pendingMonitor?.reject(error);
|
|
690
|
+
settleCallersTerminal();
|
|
691
|
+
});
|
|
692
|
+
};
|
|
693
|
+
const monitoringStream = {
|
|
694
|
+
[Symbol.asyncIterator]() {
|
|
695
|
+
return {
|
|
696
|
+
next: () => {
|
|
697
|
+
if (hasTerminalError) {
|
|
698
|
+
return Promise.reject(terminalError);
|
|
699
|
+
}
|
|
700
|
+
if (terminalResult) {
|
|
701
|
+
return Promise.resolve(terminalResult);
|
|
702
|
+
}
|
|
703
|
+
if (bufferedMonitorResult) {
|
|
704
|
+
const result = bufferedMonitorResult;
|
|
705
|
+
bufferedMonitorResult = undefined;
|
|
706
|
+
return Promise.resolve(result);
|
|
707
|
+
}
|
|
708
|
+
return new Promise((resolve, reject) => {
|
|
709
|
+
monitorPending = {
|
|
710
|
+
resolve,
|
|
711
|
+
reject
|
|
712
|
+
};
|
|
713
|
+
pump();
|
|
714
|
+
});
|
|
715
|
+
},
|
|
716
|
+
return: async value => {
|
|
717
|
+
monitorActive = false;
|
|
718
|
+
monitorPending = undefined;
|
|
719
|
+
pump();
|
|
720
|
+
return {
|
|
721
|
+
done: true,
|
|
722
|
+
value: value
|
|
723
|
+
};
|
|
724
|
+
}
|
|
725
|
+
};
|
|
726
|
+
}
|
|
727
|
+
};
|
|
728
|
+
const cancelSource = value => {
|
|
729
|
+
if (cancellationPromise) {
|
|
730
|
+
return cancellationPromise;
|
|
731
|
+
}
|
|
732
|
+
removeAbortListener();
|
|
733
|
+
if (!controller.signal.aborted) {
|
|
734
|
+
controller.abort();
|
|
735
|
+
}
|
|
736
|
+
cancellationPromise = (async () => {
|
|
737
|
+
try {
|
|
738
|
+
const defaultResult = {
|
|
739
|
+
done: true,
|
|
740
|
+
value
|
|
741
|
+
};
|
|
742
|
+
const result = sourceIterator.return ? await sourceIterator.return(value) : defaultResult;
|
|
743
|
+
if (result.done) {
|
|
744
|
+
terminalResult = result;
|
|
745
|
+
removeAbortListener();
|
|
746
|
+
settleMonitorTerminal();
|
|
747
|
+
settleCallersTerminal();
|
|
748
|
+
} else if (monitorPending) {
|
|
749
|
+
monitorPending.resolve(result);
|
|
750
|
+
monitorPending = undefined;
|
|
751
|
+
cancellationPromise = undefined;
|
|
752
|
+
} else {
|
|
753
|
+
bufferedMonitorResult = result;
|
|
754
|
+
cancellationPromise = undefined;
|
|
755
|
+
}
|
|
756
|
+
return result;
|
|
757
|
+
} catch (error) {
|
|
758
|
+
terminalError = error;
|
|
759
|
+
hasTerminalError = true;
|
|
760
|
+
removeAbortListener();
|
|
761
|
+
settleMonitorTerminal();
|
|
762
|
+
settleCallersTerminal();
|
|
763
|
+
throw error;
|
|
764
|
+
}
|
|
765
|
+
})();
|
|
766
|
+
// An AbortController cancellation has no caller awaiting this promise.
|
|
767
|
+
void cancellationPromise.catch(() => undefined);
|
|
768
|
+
return cancellationPromise;
|
|
521
769
|
};
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
event: eventType,
|
|
525
|
-
properties,
|
|
526
|
-
groups: options.groups
|
|
770
|
+
abortListener = () => {
|
|
771
|
+
void cancelSource();
|
|
527
772
|
};
|
|
528
|
-
if (
|
|
529
|
-
|
|
773
|
+
if (controller.signal.aborted) {
|
|
774
|
+
abortListener();
|
|
530
775
|
} else {
|
|
531
|
-
|
|
776
|
+
controller.signal.addEventListener('abort', abortListener, {
|
|
777
|
+
once: true
|
|
778
|
+
});
|
|
532
779
|
}
|
|
533
|
-
|
|
780
|
+
const callerStream = createStream(() => ({
|
|
781
|
+
next: () => {
|
|
782
|
+
if (hasTerminalError) {
|
|
783
|
+
return Promise.reject(terminalError);
|
|
784
|
+
}
|
|
785
|
+
if (terminalResult) {
|
|
786
|
+
return Promise.resolve(terminalResult);
|
|
787
|
+
}
|
|
788
|
+
return new Promise((resolve, reject) => {
|
|
789
|
+
callerQueue.push({
|
|
790
|
+
resolve,
|
|
791
|
+
reject
|
|
792
|
+
});
|
|
793
|
+
pump();
|
|
794
|
+
});
|
|
795
|
+
},
|
|
796
|
+
return: value => cancelSource(value),
|
|
797
|
+
throw: async error => {
|
|
798
|
+
if (!sourceIterator.throw) {
|
|
799
|
+
await cancelSource();
|
|
800
|
+
throw error;
|
|
801
|
+
}
|
|
802
|
+
try {
|
|
803
|
+
const result = await sourceIterator.throw(error);
|
|
804
|
+
if (result.done) {
|
|
805
|
+
terminalResult = result;
|
|
806
|
+
removeAbortListener();
|
|
807
|
+
settleCallersTerminal();
|
|
808
|
+
}
|
|
809
|
+
if (monitorPending) {
|
|
810
|
+
monitorPending.resolve(result);
|
|
811
|
+
monitorPending = undefined;
|
|
812
|
+
} else {
|
|
813
|
+
bufferedMonitorResult = result;
|
|
814
|
+
}
|
|
815
|
+
return result;
|
|
816
|
+
} catch (sourceError) {
|
|
817
|
+
terminalError = sourceError;
|
|
818
|
+
hasTerminalError = true;
|
|
819
|
+
removeAbortListener();
|
|
820
|
+
settleMonitorTerminal();
|
|
821
|
+
settleCallersTerminal();
|
|
822
|
+
throw sourceError;
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
}), controller);
|
|
826
|
+
return [monitoringStream, callerStream];
|
|
827
|
+
}
|
|
534
828
|
|
|
535
829
|
class PostHogAnthropic extends AnthropicOriginal__default.default {
|
|
536
830
|
constructor(config) {
|
|
@@ -555,9 +849,9 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
555
849
|
posthogParams
|
|
556
850
|
} = extractPosthogParams(body);
|
|
557
851
|
const startTime = Date.now();
|
|
558
|
-
const parentPromise = super.create(anthropicParams, options);
|
|
559
852
|
if (anthropicParams.stream) {
|
|
560
|
-
|
|
853
|
+
const parentPromise = super.create(anthropicParams, options);
|
|
854
|
+
const wrappedPromise = parentPromise.then(value => {
|
|
561
855
|
let accumulatedContent = '';
|
|
562
856
|
const contentBlocks = [];
|
|
563
857
|
const toolsInProgress = new Map();
|
|
@@ -572,8 +866,8 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
572
866
|
webSearchCount: 0
|
|
573
867
|
};
|
|
574
868
|
let lastRawUsage;
|
|
575
|
-
if (
|
|
576
|
-
const [stream1, stream2] = value.
|
|
869
|
+
if (Symbol.asyncIterator in value) {
|
|
870
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
577
871
|
(async () => {
|
|
578
872
|
try {
|
|
579
873
|
for await (const chunk of stream1) {
|
|
@@ -734,7 +1028,11 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
734
1028
|
}
|
|
735
1029
|
return value;
|
|
736
1030
|
});
|
|
1031
|
+
return preserveProviderPromise(parentPromise, wrappedPromise, {
|
|
1032
|
+
requestIdHeader: 'request-id'
|
|
1033
|
+
});
|
|
737
1034
|
} else {
|
|
1035
|
+
const parentPromise = super.create(anthropicParams, options);
|
|
738
1036
|
const wrappedPromise = parentPromise.then(async result => {
|
|
739
1037
|
if ('content' in result) {
|
|
740
1038
|
const latency = (Date.now() - startTime) / 1000;
|
|
@@ -781,7 +1079,9 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
781
1079
|
});
|
|
782
1080
|
throw error;
|
|
783
1081
|
});
|
|
784
|
-
return wrappedPromise
|
|
1082
|
+
return preserveProviderPromise(parentPromise, wrappedPromise, {
|
|
1083
|
+
requestIdHeader: 'request-id'
|
|
1084
|
+
});
|
|
785
1085
|
}
|
|
786
1086
|
}
|
|
787
1087
|
}
|