@posthog/ai 8.6.2 → 8.6.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/anthropic/index.cjs +333 -112
- package/dist/anthropic/index.cjs.map +1 -1
- package/dist/anthropic/index.mjs +333 -112
- package/dist/anthropic/index.mjs.map +1 -1
- package/dist/gemini/index.cjs +120 -114
- package/dist/gemini/index.cjs.map +1 -1
- package/dist/gemini/index.mjs +120 -114
- package/dist/gemini/index.mjs.map +1 -1
- package/dist/index.cjs +120 -114
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +120 -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 +351 -130
- package/dist/openai/index.cjs.map +1 -1
- package/dist/openai/index.mjs +351 -130
- 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 +120 -114
- package/dist/vercel/index.cjs.map +1 -1
- package/dist/vercel/index.mjs +120 -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.3";
|
|
303
304
|
|
|
304
305
|
const DEFAULT_MAX_DEPTH = 3;
|
|
305
306
|
const MAX_STACK_LINES = 20;
|
|
@@ -410,127 +411,347 @@ 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
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
414
|
+
try {
|
|
415
|
+
if (!client.capture) {
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
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 ?? {};
|
|
421
423
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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 {
|
|
437
|
+
httpStatus = 500;
|
|
438
|
+
}
|
|
436
439
|
}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
440
|
+
let exceptionId;
|
|
441
|
+
if (client.options?.enableExceptionAutocapture) {
|
|
442
|
+
exceptionId = core.uuidv7();
|
|
443
|
+
client.captureException(options.error, undefined, {
|
|
444
|
+
$ai_trace_id: traceId
|
|
445
|
+
}, exceptionId);
|
|
446
|
+
if (typeof options.error === 'object') {
|
|
447
|
+
;
|
|
448
|
+
options.error.__posthog_previously_captured_error = true;
|
|
449
|
+
}
|
|
446
450
|
}
|
|
451
|
+
errorData = {
|
|
452
|
+
$ai_is_error: true,
|
|
453
|
+
$ai_error: stringifyError(options.error),
|
|
454
|
+
$exception_event_id: exceptionId
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
httpStatus = httpStatus ?? 200;
|
|
458
|
+
let costOverrideData = {};
|
|
459
|
+
if (options.costOverride) {
|
|
460
|
+
const inputCostUSD = (options.costOverride.inputCost ?? 0) * (usage.inputTokens ?? 0);
|
|
461
|
+
const outputCostUSD = (options.costOverride.outputCost ?? 0) * (usage.outputTokens ?? 0);
|
|
462
|
+
costOverrideData = {
|
|
463
|
+
$ai_input_cost_usd: inputCostUSD,
|
|
464
|
+
$ai_output_cost_usd: outputCostUSD,
|
|
465
|
+
$ai_total_cost_usd: inputCostUSD + outputCostUSD
|
|
466
|
+
};
|
|
447
467
|
}
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
468
|
+
const additionalTokenValues = {
|
|
469
|
+
...(usage.reasoningTokens ? {
|
|
470
|
+
$ai_reasoning_tokens: usage.reasoningTokens
|
|
471
|
+
} : {}),
|
|
472
|
+
...(usage.cacheReadInputTokens ? {
|
|
473
|
+
$ai_cache_read_input_tokens: usage.cacheReadInputTokens
|
|
474
|
+
} : {}),
|
|
475
|
+
...(usage.cacheCreationInputTokens ? {
|
|
476
|
+
$ai_cache_creation_input_tokens: usage.cacheCreationInputTokens
|
|
477
|
+
} : {}),
|
|
478
|
+
...(usage.webSearchCount ? {
|
|
479
|
+
$ai_web_search_count: usage.webSearchCount
|
|
480
|
+
} : {}),
|
|
481
|
+
...(usage.rawUsage ? {
|
|
482
|
+
$ai_usage: usage.rawUsage
|
|
483
|
+
} : {})
|
|
452
484
|
};
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
$
|
|
461
|
-
$
|
|
462
|
-
$
|
|
485
|
+
const properties = {
|
|
486
|
+
$ai_lib: 'posthog-ai',
|
|
487
|
+
$ai_lib_version: version,
|
|
488
|
+
$ai_provider: options.providerOverride ?? options.provider,
|
|
489
|
+
$ai_model: options.modelOverride ?? options.model,
|
|
490
|
+
$ai_model_parameters: options.modelParameters ?? {},
|
|
491
|
+
$ai_input: safeInput,
|
|
492
|
+
$ai_output_choices: safeOutput,
|
|
493
|
+
$ai_http_status: httpStatus,
|
|
494
|
+
$ai_input_tokens: usage.inputTokens ?? 0,
|
|
495
|
+
...(usage.outputTokens !== undefined ? {
|
|
496
|
+
$ai_output_tokens: usage.outputTokens
|
|
497
|
+
} : {}),
|
|
498
|
+
...additionalTokenValues,
|
|
499
|
+
$ai_latency: options.latency ?? 0,
|
|
500
|
+
...(options.timeToFirstToken !== undefined ? {
|
|
501
|
+
$ai_time_to_first_token: options.timeToFirstToken
|
|
502
|
+
} : {}),
|
|
503
|
+
$ai_trace_id: traceId,
|
|
504
|
+
$ai_base_url: options.baseURL ?? '',
|
|
505
|
+
...options.properties,
|
|
506
|
+
$ai_tokens_source: getTokensSource(options.properties),
|
|
507
|
+
...(options.distinctId ? {} : {
|
|
508
|
+
$process_person_profile: false
|
|
509
|
+
}),
|
|
510
|
+
...(options.stopReason ? {
|
|
511
|
+
$ai_stop_reason: options.stopReason
|
|
512
|
+
} : {}),
|
|
513
|
+
...(options.tools ? {
|
|
514
|
+
$ai_tools: options.tools
|
|
515
|
+
} : {}),
|
|
516
|
+
...(options.completionId ? {
|
|
517
|
+
$ai_completion_id: options.completionId
|
|
518
|
+
} : {}),
|
|
519
|
+
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
520
|
+
$ai_provider_metadata: options.providerMetadata
|
|
521
|
+
} : {}),
|
|
522
|
+
...errorData,
|
|
523
|
+
...costOverrideData
|
|
463
524
|
};
|
|
525
|
+
const event = {
|
|
526
|
+
distinctId: options.distinctId ?? traceId,
|
|
527
|
+
event: eventType,
|
|
528
|
+
properties,
|
|
529
|
+
groups: options.groups
|
|
530
|
+
};
|
|
531
|
+
if (options.captureImmediate) {
|
|
532
|
+
await client.captureImmediate(event);
|
|
533
|
+
} else {
|
|
534
|
+
client.capture(event);
|
|
535
|
+
}
|
|
536
|
+
} catch (error) {
|
|
537
|
+
// Telemetry failures must never affect the instrumented provider call.
|
|
538
|
+
console.warn('[PostHog AI] Failed to capture generation telemetry:', error);
|
|
464
539
|
}
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
540
|
+
};
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Splits an SDK stream into a monitoring branch and a caller branch without
|
|
544
|
+
* allowing either branch to read ahead of the other. Unlike the SDKs' `tee()`
|
|
545
|
+
* implementations, this keeps at most one result in flight and makes caller
|
|
546
|
+
* cancellation terminate the monitoring branch and the source iterator.
|
|
547
|
+
*/
|
|
548
|
+
function monitoredStreamTee(source, createStream) {
|
|
549
|
+
const controller = source.controller ?? new AbortController();
|
|
550
|
+
const sourceIterator = source[Symbol.asyncIterator]();
|
|
551
|
+
const callerQueue = [];
|
|
552
|
+
let monitorPending;
|
|
553
|
+
let monitorActive = true;
|
|
554
|
+
let operationInFlight = false;
|
|
555
|
+
let terminalResult;
|
|
556
|
+
let bufferedMonitorResult;
|
|
557
|
+
let terminalError;
|
|
558
|
+
let hasTerminalError = false;
|
|
559
|
+
let cancellationPromise;
|
|
560
|
+
let abortListener;
|
|
561
|
+
const removeAbortListener = () => {
|
|
562
|
+
if (abortListener) {
|
|
563
|
+
controller.signal.removeEventListener('abort', abortListener);
|
|
564
|
+
abortListener = undefined;
|
|
565
|
+
}
|
|
481
566
|
};
|
|
482
|
-
const
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
$ai_output_tokens: usage.outputTokens
|
|
494
|
-
} : {}),
|
|
495
|
-
...additionalTokenValues,
|
|
496
|
-
$ai_latency: options.latency ?? 0,
|
|
497
|
-
...(options.timeToFirstToken !== undefined ? {
|
|
498
|
-
$ai_time_to_first_token: options.timeToFirstToken
|
|
499
|
-
} : {}),
|
|
500
|
-
$ai_trace_id: traceId,
|
|
501
|
-
$ai_base_url: options.baseURL ?? '',
|
|
502
|
-
...options.properties,
|
|
503
|
-
$ai_tokens_source: getTokensSource(options.properties),
|
|
504
|
-
...(options.distinctId ? {} : {
|
|
505
|
-
$process_person_profile: false
|
|
506
|
-
}),
|
|
507
|
-
...(options.stopReason ? {
|
|
508
|
-
$ai_stop_reason: options.stopReason
|
|
509
|
-
} : {}),
|
|
510
|
-
...(options.tools ? {
|
|
511
|
-
$ai_tools: options.tools
|
|
512
|
-
} : {}),
|
|
513
|
-
...(options.completionId ? {
|
|
514
|
-
$ai_completion_id: options.completionId
|
|
515
|
-
} : {}),
|
|
516
|
-
...(options.providerMetadata && Object.keys(options.providerMetadata).length > 0 ? {
|
|
517
|
-
$ai_provider_metadata: options.providerMetadata
|
|
518
|
-
} : {}),
|
|
519
|
-
...errorData,
|
|
520
|
-
...costOverrideData
|
|
567
|
+
const settleMonitorTerminal = () => {
|
|
568
|
+
if (!monitorPending) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
const pending = monitorPending;
|
|
572
|
+
monitorPending = undefined;
|
|
573
|
+
if (hasTerminalError) {
|
|
574
|
+
pending.reject(terminalError);
|
|
575
|
+
} else if (terminalResult) {
|
|
576
|
+
pending.resolve(terminalResult);
|
|
577
|
+
}
|
|
521
578
|
};
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
579
|
+
const settleCallersTerminal = () => {
|
|
580
|
+
while (callerQueue.length > 0) {
|
|
581
|
+
const pending = callerQueue.shift();
|
|
582
|
+
if (hasTerminalError) {
|
|
583
|
+
pending.reject(terminalError);
|
|
584
|
+
} else if (terminalResult) {
|
|
585
|
+
pending.resolve(terminalResult);
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
};
|
|
589
|
+
const pump = () => {
|
|
590
|
+
if (operationInFlight || callerQueue.length === 0 || monitorActive && !monitorPending) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
const pendingCaller = callerQueue.shift();
|
|
594
|
+
const pendingMonitor = monitorPending;
|
|
595
|
+
monitorPending = undefined;
|
|
596
|
+
operationInFlight = true;
|
|
597
|
+
void sourceIterator.next().then(result => {
|
|
598
|
+
operationInFlight = false;
|
|
599
|
+
if (result.done) {
|
|
600
|
+
terminalResult = result;
|
|
601
|
+
removeAbortListener();
|
|
602
|
+
}
|
|
603
|
+
pendingCaller.resolve(result);
|
|
604
|
+
pendingMonitor?.resolve(result);
|
|
605
|
+
if (result.done) {
|
|
606
|
+
settleCallersTerminal();
|
|
607
|
+
} else {
|
|
608
|
+
pump();
|
|
609
|
+
}
|
|
610
|
+
}, error => {
|
|
611
|
+
operationInFlight = false;
|
|
612
|
+
terminalError = error;
|
|
613
|
+
hasTerminalError = true;
|
|
614
|
+
removeAbortListener();
|
|
615
|
+
pendingCaller.reject(error);
|
|
616
|
+
pendingMonitor?.reject(error);
|
|
617
|
+
settleCallersTerminal();
|
|
618
|
+
});
|
|
527
619
|
};
|
|
528
|
-
|
|
529
|
-
|
|
620
|
+
const monitoringStream = {
|
|
621
|
+
[Symbol.asyncIterator]() {
|
|
622
|
+
return {
|
|
623
|
+
next: () => {
|
|
624
|
+
if (hasTerminalError) {
|
|
625
|
+
return Promise.reject(terminalError);
|
|
626
|
+
}
|
|
627
|
+
if (terminalResult) {
|
|
628
|
+
return Promise.resolve(terminalResult);
|
|
629
|
+
}
|
|
630
|
+
if (bufferedMonitorResult) {
|
|
631
|
+
const result = bufferedMonitorResult;
|
|
632
|
+
bufferedMonitorResult = undefined;
|
|
633
|
+
return Promise.resolve(result);
|
|
634
|
+
}
|
|
635
|
+
return new Promise((resolve, reject) => {
|
|
636
|
+
monitorPending = {
|
|
637
|
+
resolve,
|
|
638
|
+
reject
|
|
639
|
+
};
|
|
640
|
+
pump();
|
|
641
|
+
});
|
|
642
|
+
},
|
|
643
|
+
return: async value => {
|
|
644
|
+
monitorActive = false;
|
|
645
|
+
monitorPending = undefined;
|
|
646
|
+
pump();
|
|
647
|
+
return {
|
|
648
|
+
done: true,
|
|
649
|
+
value: value
|
|
650
|
+
};
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
};
|
|
655
|
+
const cancelSource = value => {
|
|
656
|
+
if (cancellationPromise) {
|
|
657
|
+
return cancellationPromise;
|
|
658
|
+
}
|
|
659
|
+
removeAbortListener();
|
|
660
|
+
if (!controller.signal.aborted) {
|
|
661
|
+
controller.abort();
|
|
662
|
+
}
|
|
663
|
+
cancellationPromise = (async () => {
|
|
664
|
+
try {
|
|
665
|
+
const defaultResult = {
|
|
666
|
+
done: true,
|
|
667
|
+
value
|
|
668
|
+
};
|
|
669
|
+
const result = sourceIterator.return ? await sourceIterator.return(value) : defaultResult;
|
|
670
|
+
if (result.done) {
|
|
671
|
+
terminalResult = result;
|
|
672
|
+
removeAbortListener();
|
|
673
|
+
settleMonitorTerminal();
|
|
674
|
+
settleCallersTerminal();
|
|
675
|
+
} else if (monitorPending) {
|
|
676
|
+
monitorPending.resolve(result);
|
|
677
|
+
monitorPending = undefined;
|
|
678
|
+
cancellationPromise = undefined;
|
|
679
|
+
} else {
|
|
680
|
+
bufferedMonitorResult = result;
|
|
681
|
+
cancellationPromise = undefined;
|
|
682
|
+
}
|
|
683
|
+
return result;
|
|
684
|
+
} catch (error) {
|
|
685
|
+
terminalError = error;
|
|
686
|
+
hasTerminalError = true;
|
|
687
|
+
removeAbortListener();
|
|
688
|
+
settleMonitorTerminal();
|
|
689
|
+
settleCallersTerminal();
|
|
690
|
+
throw error;
|
|
691
|
+
}
|
|
692
|
+
})();
|
|
693
|
+
// An AbortController cancellation has no caller awaiting this promise.
|
|
694
|
+
void cancellationPromise.catch(() => undefined);
|
|
695
|
+
return cancellationPromise;
|
|
696
|
+
};
|
|
697
|
+
abortListener = () => {
|
|
698
|
+
void cancelSource();
|
|
699
|
+
};
|
|
700
|
+
if (controller.signal.aborted) {
|
|
701
|
+
abortListener();
|
|
530
702
|
} else {
|
|
531
|
-
|
|
703
|
+
controller.signal.addEventListener('abort', abortListener, {
|
|
704
|
+
once: true
|
|
705
|
+
});
|
|
532
706
|
}
|
|
533
|
-
|
|
707
|
+
const callerStream = createStream(() => ({
|
|
708
|
+
next: () => {
|
|
709
|
+
if (hasTerminalError) {
|
|
710
|
+
return Promise.reject(terminalError);
|
|
711
|
+
}
|
|
712
|
+
if (terminalResult) {
|
|
713
|
+
return Promise.resolve(terminalResult);
|
|
714
|
+
}
|
|
715
|
+
return new Promise((resolve, reject) => {
|
|
716
|
+
callerQueue.push({
|
|
717
|
+
resolve,
|
|
718
|
+
reject
|
|
719
|
+
});
|
|
720
|
+
pump();
|
|
721
|
+
});
|
|
722
|
+
},
|
|
723
|
+
return: value => cancelSource(value),
|
|
724
|
+
throw: async error => {
|
|
725
|
+
if (!sourceIterator.throw) {
|
|
726
|
+
await cancelSource();
|
|
727
|
+
throw error;
|
|
728
|
+
}
|
|
729
|
+
try {
|
|
730
|
+
const result = await sourceIterator.throw(error);
|
|
731
|
+
if (result.done) {
|
|
732
|
+
terminalResult = result;
|
|
733
|
+
removeAbortListener();
|
|
734
|
+
settleCallersTerminal();
|
|
735
|
+
}
|
|
736
|
+
if (monitorPending) {
|
|
737
|
+
monitorPending.resolve(result);
|
|
738
|
+
monitorPending = undefined;
|
|
739
|
+
} else {
|
|
740
|
+
bufferedMonitorResult = result;
|
|
741
|
+
}
|
|
742
|
+
return result;
|
|
743
|
+
} catch (sourceError) {
|
|
744
|
+
terminalError = sourceError;
|
|
745
|
+
hasTerminalError = true;
|
|
746
|
+
removeAbortListener();
|
|
747
|
+
settleMonitorTerminal();
|
|
748
|
+
settleCallersTerminal();
|
|
749
|
+
throw sourceError;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}), controller);
|
|
753
|
+
return [monitoringStream, callerStream];
|
|
754
|
+
}
|
|
534
755
|
|
|
535
756
|
class PostHogAnthropic extends AnthropicOriginal__default.default {
|
|
536
757
|
constructor(config) {
|
|
@@ -572,8 +793,8 @@ class WrappedMessages extends AnthropicOriginal__default.default.Messages {
|
|
|
572
793
|
webSearchCount: 0
|
|
573
794
|
};
|
|
574
795
|
let lastRawUsage;
|
|
575
|
-
if (
|
|
576
|
-
const [stream1, stream2] = value.
|
|
796
|
+
if (Symbol.asyncIterator in value) {
|
|
797
|
+
const [stream1, stream2] = monitoredStreamTee(value, (iterator, controller) => new streaming.Stream(iterator, controller));
|
|
577
798
|
(async () => {
|
|
578
799
|
try {
|
|
579
800
|
for await (const chunk of stream1) {
|