bitfab 0.53.0 → 0.53.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/dist/{chunk-6IMGAODW.js → chunk-ASMHSKFS.js} +542 -32
- package/dist/chunk-ASMHSKFS.js.map +1 -0
- package/dist/{chunk-SJKWUQ3G.js → chunk-MMT5MWG5.js} +2 -2
- package/dist/{chunk-SCXR43UF.js → chunk-ZCOZHNAA.js} +101 -42
- package/dist/chunk-ZCOZHNAA.js.map +1 -0
- package/dist/{chunk-DTC6SIXW.js → chunk-ZEGNMZU7.js} +3 -3
- package/dist/{chunk-CBRO6BP7.js → chunk-ZNY2HZT3.js} +141 -29
- package/dist/chunk-ZNY2HZT3.js.map +1 -0
- package/dist/{http-SEN3PUXX.js → http-2OOKOZQ3.js} +2 -2
- package/dist/{http-KP7DVTOD.js → http-7QLUPC6F.js} +2 -2
- package/dist/index.cjs +681 -88
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -8
- package/dist/index.d.ts +25 -8
- package/dist/index.js +3 -3
- package/dist/node.cjs +681 -88
- package/dist/node.cjs.map +1 -1
- package/dist/node.js +3 -3
- package/dist/{replay-Y5RIJOWE.js → replay-KJKIGXRH.js} +3 -3
- package/dist/replayCli.js +2 -2
- package/dist/seedCli.js +2 -2
- package/package.json +1 -1
- package/dist/chunk-6IMGAODW.js.map +0 -1
- package/dist/chunk-CBRO6BP7.js.map +0 -1
- package/dist/chunk-SCXR43UF.js.map +0 -1
- /package/dist/{chunk-SJKWUQ3G.js.map → chunk-MMT5MWG5.js.map} +0 -0
- /package/dist/{chunk-DTC6SIXW.js.map → chunk-ZEGNMZU7.js.map} +0 -0
- /package/dist/{http-KP7DVTOD.js.map → http-2OOKOZQ3.js.map} +0 -0
- /package/dist/{http-SEN3PUXX.js.map → http-7QLUPC6F.js.map} +0 -0
- /package/dist/{replay-Y5RIJOWE.js.map → replay-KJKIGXRH.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -51,7 +51,7 @@ var __version__, __packageName__;
|
|
|
51
51
|
var init_version_generated = __esm({
|
|
52
52
|
"src/version.generated.ts"() {
|
|
53
53
|
"use strict";
|
|
54
|
-
__version__ = "0.53.
|
|
54
|
+
__version__ = "0.53.1";
|
|
55
55
|
__packageName__ = "bitfab";
|
|
56
56
|
}
|
|
57
57
|
});
|
|
@@ -516,8 +516,8 @@ function encodePayloadBody(payload) {
|
|
|
516
516
|
const marker = { error: `payload_serialize_failed: ${message}` };
|
|
517
517
|
return { body: JSON.stringify(marker), dropped, value: marker };
|
|
518
518
|
}
|
|
519
|
-
const
|
|
520
|
-
if (dropped.length > 0 &&
|
|
519
|
+
const isRecord4 = typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized);
|
|
520
|
+
if (dropped.length > 0 && isRecord4) {
|
|
521
521
|
const obj = sanitized;
|
|
522
522
|
const existing = Array.isArray(obj.errors) ? obj.errors : [];
|
|
523
523
|
obj.errors = [
|
|
@@ -534,7 +534,7 @@ function encodePayloadBody(payload) {
|
|
|
534
534
|
return {
|
|
535
535
|
body: JSON.stringify(sanitized),
|
|
536
536
|
dropped,
|
|
537
|
-
value:
|
|
537
|
+
value: isRecord4 ? sanitized : void 0
|
|
538
538
|
};
|
|
539
539
|
}
|
|
540
540
|
}
|
|
@@ -546,6 +546,456 @@ var init_serializePayload = __esm({
|
|
|
546
546
|
}
|
|
547
547
|
});
|
|
548
548
|
|
|
549
|
+
// src/policyRefresh.ts
|
|
550
|
+
var PolicyRefresh;
|
|
551
|
+
var init_policyRefresh = __esm({
|
|
552
|
+
"src/policyRefresh.ts"() {
|
|
553
|
+
"use strict";
|
|
554
|
+
PolicyRefresh = class {
|
|
555
|
+
constructor() {
|
|
556
|
+
this.refreshAfter = 0;
|
|
557
|
+
}
|
|
558
|
+
due() {
|
|
559
|
+
return this.inFlight === void 0 && Date.now() >= this.refreshAfter;
|
|
560
|
+
}
|
|
561
|
+
hold(durationMs) {
|
|
562
|
+
this.refreshAfter = Date.now() + durationMs;
|
|
563
|
+
}
|
|
564
|
+
releaseHold() {
|
|
565
|
+
this.refreshAfter = 0;
|
|
566
|
+
}
|
|
567
|
+
run(read2, onLoaded, onFailed) {
|
|
568
|
+
if (!this.due()) {
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
let request;
|
|
572
|
+
try {
|
|
573
|
+
request = read2().then(onLoaded).catch(onFailed).finally(() => {
|
|
574
|
+
this.inFlight = void 0;
|
|
575
|
+
});
|
|
576
|
+
} catch (error) {
|
|
577
|
+
onFailed(error);
|
|
578
|
+
return;
|
|
579
|
+
}
|
|
580
|
+
this.inFlight = request;
|
|
581
|
+
}
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
// src/spanOrigin.ts
|
|
587
|
+
function isFrameworkInstrumentation(value) {
|
|
588
|
+
return typeof value === "string" && FRAMEWORK_INSTRUMENTATION_SET.has(value);
|
|
589
|
+
}
|
|
590
|
+
function makeSpanOrigin(instrumentation) {
|
|
591
|
+
return {
|
|
592
|
+
name: SPAN_ORIGIN_NAME,
|
|
593
|
+
version: __version__,
|
|
594
|
+
instrumentation: { name: instrumentation }
|
|
595
|
+
};
|
|
596
|
+
}
|
|
597
|
+
function isRecord(value) {
|
|
598
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
599
|
+
}
|
|
600
|
+
function spanOriginOf(payload) {
|
|
601
|
+
const rawSpan = payload.rawSpan;
|
|
602
|
+
if (!isRecord(rawSpan)) {
|
|
603
|
+
return void 0;
|
|
604
|
+
}
|
|
605
|
+
const origin = rawSpan.span_origin;
|
|
606
|
+
if (!isRecord(origin) || !isRecord(origin.instrumentation)) {
|
|
607
|
+
return void 0;
|
|
608
|
+
}
|
|
609
|
+
const { name, version } = origin;
|
|
610
|
+
const instrumentation = origin.instrumentation.name;
|
|
611
|
+
if (typeof name !== "string" || typeof version !== "string" || typeof instrumentation !== "string" || !SPAN_INSTRUMENTATIONS.includes(instrumentation)) {
|
|
612
|
+
return void 0;
|
|
613
|
+
}
|
|
614
|
+
return {
|
|
615
|
+
name,
|
|
616
|
+
version,
|
|
617
|
+
instrumentation: { name: instrumentation }
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
function spanInstrumentationOf(payload) {
|
|
621
|
+
return spanOriginOf(payload)?.instrumentation.name;
|
|
622
|
+
}
|
|
623
|
+
function recordedByFramework(payload) {
|
|
624
|
+
return isFrameworkInstrumentation(spanInstrumentationOf(payload));
|
|
625
|
+
}
|
|
626
|
+
var SPAN_ORIGIN_NAME, SPAN_INSTRUMENTATIONS, FRAMEWORK_INSTRUMENTATIONS, FRAMEWORK_INSTRUMENTATION_SET;
|
|
627
|
+
var init_spanOrigin = __esm({
|
|
628
|
+
"src/spanOrigin.ts"() {
|
|
629
|
+
"use strict";
|
|
630
|
+
init_constants();
|
|
631
|
+
SPAN_ORIGIN_NAME = "bitfab.sdk.typescript";
|
|
632
|
+
SPAN_INSTRUMENTATIONS = [
|
|
633
|
+
"span",
|
|
634
|
+
"trace",
|
|
635
|
+
"openai-agents",
|
|
636
|
+
"langgraph",
|
|
637
|
+
"claude-agent-sdk",
|
|
638
|
+
"vercel-ai"
|
|
639
|
+
];
|
|
640
|
+
FRAMEWORK_INSTRUMENTATIONS = [
|
|
641
|
+
"openai-agents",
|
|
642
|
+
"langgraph",
|
|
643
|
+
"claude-agent-sdk",
|
|
644
|
+
"vercel-ai"
|
|
645
|
+
];
|
|
646
|
+
FRAMEWORK_INSTRUMENTATION_SET = new Set(
|
|
647
|
+
FRAMEWORK_INSTRUMENTATIONS
|
|
648
|
+
);
|
|
649
|
+
}
|
|
650
|
+
});
|
|
651
|
+
|
|
652
|
+
// src/unrefTimer.ts
|
|
653
|
+
function unrefTimer(timer) {
|
|
654
|
+
const handle = timer;
|
|
655
|
+
if (typeof handle.unref === "function") {
|
|
656
|
+
handle.unref();
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
var init_unrefTimer = __esm({
|
|
660
|
+
"src/unrefTimer.ts"() {
|
|
661
|
+
"use strict";
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// src/simulationPlan.ts
|
|
666
|
+
function planWaitSliceMs(timeoutMs) {
|
|
667
|
+
return Math.min(SIMULATION_PLAN_READ_TIMEOUT_MS, Math.max(timeoutMs, 0) / 2);
|
|
668
|
+
}
|
|
669
|
+
function parseSimulationPlan(body) {
|
|
670
|
+
if (typeof body !== "object" || body === null) {
|
|
671
|
+
return null;
|
|
672
|
+
}
|
|
673
|
+
const nodes = body.nodes;
|
|
674
|
+
if (!Array.isArray(nodes)) {
|
|
675
|
+
return null;
|
|
676
|
+
}
|
|
677
|
+
const contentOff = /* @__PURE__ */ new Map();
|
|
678
|
+
for (const node of nodes) {
|
|
679
|
+
if (typeof node !== "object" || node === null) {
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
const { traceFunctionKey, name, captureContent } = node;
|
|
683
|
+
if (typeof traceFunctionKey !== "string" || typeof name !== "string" || typeof captureContent !== "boolean") {
|
|
684
|
+
continue;
|
|
685
|
+
}
|
|
686
|
+
if (captureContent) {
|
|
687
|
+
continue;
|
|
688
|
+
}
|
|
689
|
+
const names = contentOff.get(traceFunctionKey) ?? /* @__PURE__ */ new Set();
|
|
690
|
+
names.add(name);
|
|
691
|
+
contentOff.set(traceFunctionKey, names);
|
|
692
|
+
}
|
|
693
|
+
return contentOff;
|
|
694
|
+
}
|
|
695
|
+
function traceIdOf(payload) {
|
|
696
|
+
const traceId = payload.traceId;
|
|
697
|
+
if (typeof traceId === "string") {
|
|
698
|
+
return traceId;
|
|
699
|
+
}
|
|
700
|
+
const id = payload.id;
|
|
701
|
+
return typeof id === "string" ? id : void 0;
|
|
702
|
+
}
|
|
703
|
+
function isRecord2(value) {
|
|
704
|
+
return typeof value === "object" && value !== null;
|
|
705
|
+
}
|
|
706
|
+
function rawSpanOf(payload) {
|
|
707
|
+
return isRecord2(payload.rawSpan) ? payload.rawSpan : void 0;
|
|
708
|
+
}
|
|
709
|
+
function spanDataOf(payload) {
|
|
710
|
+
const spanData = rawSpanOf(payload)?.span_data;
|
|
711
|
+
return isRecord2(spanData) ? spanData : void 0;
|
|
712
|
+
}
|
|
713
|
+
function spanNameOf(payload) {
|
|
714
|
+
const name = spanDataOf(payload)?.name;
|
|
715
|
+
return typeof name === "string" ? name : void 0;
|
|
716
|
+
}
|
|
717
|
+
function stripContent(payload) {
|
|
718
|
+
const rawSpan = rawSpanOf(payload);
|
|
719
|
+
const spanData = spanDataOf(payload);
|
|
720
|
+
if (rawSpan === void 0 || spanData === void 0) {
|
|
721
|
+
return payload;
|
|
722
|
+
}
|
|
723
|
+
const kept = { ...spanData };
|
|
724
|
+
for (const key of CONTENT_KEYS) {
|
|
725
|
+
delete kept[key];
|
|
726
|
+
}
|
|
727
|
+
kept[CONTENT_OFF_KEY] = true;
|
|
728
|
+
return { ...payload, rawSpan: { ...rawSpan, span_data: kept } };
|
|
729
|
+
}
|
|
730
|
+
function simulationPlanEnvDisabled() {
|
|
731
|
+
const value = readEnv(DISABLE_SIMULATION_PLAN_ENV);
|
|
732
|
+
return typeof value === "string" && value.trim() !== "";
|
|
733
|
+
}
|
|
734
|
+
function missingSimulationPlanEndpoint(error) {
|
|
735
|
+
return error instanceof BitfabError && error.status === 404;
|
|
736
|
+
}
|
|
737
|
+
var SIMULATION_PLAN_REFRESH_MS, SIMULATION_PLAN_RETRY_MS, SIMULATION_PLAN_READ_TIMEOUT_MS, SIMULATION_PLAN_MAX_HELD, DISABLE_SIMULATION_PLAN_ENV, ROOT_TRACE_FUNCTION_KEY_FIELD, CONTENT_OFF_KEY, CONTENT_KEYS, SimulationPlan;
|
|
738
|
+
var init_simulationPlan = __esm({
|
|
739
|
+
"src/simulationPlan.ts"() {
|
|
740
|
+
"use strict";
|
|
741
|
+
init_errors();
|
|
742
|
+
init_policyRefresh();
|
|
743
|
+
init_readEnv();
|
|
744
|
+
init_spanOrigin();
|
|
745
|
+
init_unrefTimer();
|
|
746
|
+
init_warnOnce();
|
|
747
|
+
SIMULATION_PLAN_REFRESH_MS = 6e4;
|
|
748
|
+
SIMULATION_PLAN_RETRY_MS = 1e4;
|
|
749
|
+
SIMULATION_PLAN_READ_TIMEOUT_MS = 5e3;
|
|
750
|
+
SIMULATION_PLAN_MAX_HELD = 1e3;
|
|
751
|
+
DISABLE_SIMULATION_PLAN_ENV = "BITFAB_DISABLE_SIM_PLAN";
|
|
752
|
+
ROOT_TRACE_FUNCTION_KEY_FIELD = "rootTraceFunctionKey";
|
|
753
|
+
CONTENT_OFF_KEY = "content_off_by_simulation_plan";
|
|
754
|
+
CONTENT_KEYS = ["input", "input_meta", "output", "output_meta"];
|
|
755
|
+
SimulationPlan = class {
|
|
756
|
+
constructor(source, enabled = true) {
|
|
757
|
+
this.source = source;
|
|
758
|
+
this.enabled = enabled;
|
|
759
|
+
this.policyRefresh = new PolicyRefresh();
|
|
760
|
+
this.retryPending = false;
|
|
761
|
+
this.waitingForFirstLoad = 0;
|
|
762
|
+
this.held = [];
|
|
763
|
+
this.droppedWhileHolding = 0;
|
|
764
|
+
this.stopped = false;
|
|
765
|
+
this.loaded = new Promise((resolve) => {
|
|
766
|
+
this.resolveLoaded = resolve;
|
|
767
|
+
});
|
|
768
|
+
}
|
|
769
|
+
disabled() {
|
|
770
|
+
return !this.enabled || simulationPlanEnvDisabled();
|
|
771
|
+
}
|
|
772
|
+
refresh() {
|
|
773
|
+
if (this.stopped || this.disabled()) {
|
|
774
|
+
return;
|
|
775
|
+
}
|
|
776
|
+
this.policyRefresh.run(
|
|
777
|
+
() => this.source.getSimulationPlan(),
|
|
778
|
+
(body) => {
|
|
779
|
+
const parsed = parseSimulationPlan(body);
|
|
780
|
+
if (parsed === null) {
|
|
781
|
+
this.scheduleRetry(
|
|
782
|
+
"sim-plan-unreadable",
|
|
783
|
+
"the sim plan response was not understood"
|
|
784
|
+
);
|
|
785
|
+
return;
|
|
786
|
+
}
|
|
787
|
+
this.markLoaded(parsed);
|
|
788
|
+
},
|
|
789
|
+
(error) => {
|
|
790
|
+
if (missingSimulationPlanEndpoint(error)) {
|
|
791
|
+
this.markLoaded(/* @__PURE__ */ new Map());
|
|
792
|
+
return;
|
|
793
|
+
}
|
|
794
|
+
this.scheduleRetry(
|
|
795
|
+
"sim-plan-unavailable",
|
|
796
|
+
`could not read the sim plan: ${error instanceof Error ? error.message : String(error)}`
|
|
797
|
+
);
|
|
798
|
+
}
|
|
799
|
+
);
|
|
800
|
+
}
|
|
801
|
+
markLoaded(parsed) {
|
|
802
|
+
if (this.stopped) {
|
|
803
|
+
return;
|
|
804
|
+
}
|
|
805
|
+
this.contentOffByKey = parsed;
|
|
806
|
+
this.policyRefresh.hold(SIMULATION_PLAN_REFRESH_MS);
|
|
807
|
+
this.retryPending = false;
|
|
808
|
+
this.clearRetryTimer();
|
|
809
|
+
this.resolveLoaded?.();
|
|
810
|
+
this.resolveLoaded = void 0;
|
|
811
|
+
this.releaseHeld();
|
|
812
|
+
}
|
|
813
|
+
scheduleRetry(warnKey, reason) {
|
|
814
|
+
if (this.stopped) {
|
|
815
|
+
return;
|
|
816
|
+
}
|
|
817
|
+
this.policyRefresh.hold(SIMULATION_PLAN_RETRY_MS);
|
|
818
|
+
if (this.contentOffByKey !== void 0) {
|
|
819
|
+
return;
|
|
820
|
+
}
|
|
821
|
+
this.retryPending = true;
|
|
822
|
+
warnOnce(
|
|
823
|
+
warnKey,
|
|
824
|
+
`${reason}. Spans are held until the first read succeeds; while a record is held it is retried every ${SIMULATION_PLAN_RETRY_MS / 1e3}s, otherwise on the next span.`
|
|
825
|
+
);
|
|
826
|
+
this.armRetry();
|
|
827
|
+
}
|
|
828
|
+
holdsWork() {
|
|
829
|
+
return this.held.length > 0 || this.waitingForFirstLoad > 0;
|
|
830
|
+
}
|
|
831
|
+
armRetry() {
|
|
832
|
+
if (this.stopped || !this.retryPending || this.retryTimer !== void 0 || !this.holdsWork()) {
|
|
833
|
+
return;
|
|
834
|
+
}
|
|
835
|
+
const timer = setTimeout(() => {
|
|
836
|
+
this.retryTimer = void 0;
|
|
837
|
+
this.policyRefresh.releaseHold();
|
|
838
|
+
this.refresh();
|
|
839
|
+
}, SIMULATION_PLAN_RETRY_MS);
|
|
840
|
+
unrefTimer(timer);
|
|
841
|
+
this.retryTimer = timer;
|
|
842
|
+
}
|
|
843
|
+
clearRetryTimer() {
|
|
844
|
+
if (this.retryTimer !== void 0) {
|
|
845
|
+
clearTimeout(this.retryTimer);
|
|
846
|
+
this.retryTimer = void 0;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
syncRetryTimer() {
|
|
850
|
+
if (this.holdsWork()) {
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
853
|
+
this.clearRetryTimer();
|
|
854
|
+
}
|
|
855
|
+
firstLoad() {
|
|
856
|
+
if (this.contentOffByKey !== void 0 || this.stopped || this.disabled()) {
|
|
857
|
+
return void 0;
|
|
858
|
+
}
|
|
859
|
+
return this.loaded;
|
|
860
|
+
}
|
|
861
|
+
send(payload, traceFunctionKey, submit) {
|
|
862
|
+
this.refresh();
|
|
863
|
+
if (this.stopped || this.disabled() || traceFunctionKey === void 0 || spanNameOf(payload) === void 0 || recordedByFramework(payload)) {
|
|
864
|
+
submit(payload);
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
if (this.contentOffByKey === void 0) {
|
|
868
|
+
this.hold({ payload, traceFunctionKey, submit });
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
this.submitEntry({ payload, traceFunctionKey, submit });
|
|
872
|
+
}
|
|
873
|
+
sendTrace(payload, submit) {
|
|
874
|
+
this.refresh();
|
|
875
|
+
if (this.stopped || this.disabled() || this.contentOffByKey !== void 0 || !this.holdsSpanOfTrace(traceIdOf(payload))) {
|
|
876
|
+
submit(payload);
|
|
877
|
+
return;
|
|
878
|
+
}
|
|
879
|
+
this.hold({ payload, traceFunctionKey: void 0, submit });
|
|
880
|
+
}
|
|
881
|
+
holdsSpanOfTrace(traceId) {
|
|
882
|
+
if (traceId === void 0) {
|
|
883
|
+
return false;
|
|
884
|
+
}
|
|
885
|
+
return this.held.some(
|
|
886
|
+
(entry) => entry.traceFunctionKey !== void 0 && traceIdOf(entry.payload) === traceId
|
|
887
|
+
);
|
|
888
|
+
}
|
|
889
|
+
hold(entry) {
|
|
890
|
+
this.held.push(entry);
|
|
891
|
+
while (this.held.length > SIMULATION_PLAN_MAX_HELD) {
|
|
892
|
+
this.held.shift();
|
|
893
|
+
this.droppedWhileHolding += 1;
|
|
894
|
+
}
|
|
895
|
+
this.armRetry();
|
|
896
|
+
}
|
|
897
|
+
submitEntry(entry) {
|
|
898
|
+
try {
|
|
899
|
+
entry.submit(
|
|
900
|
+
entry.traceFunctionKey === void 0 ? entry.payload : this.apply(entry.payload, entry.traceFunctionKey)
|
|
901
|
+
);
|
|
902
|
+
} catch (error) {
|
|
903
|
+
warnOnce(
|
|
904
|
+
"sim-plan-held-span-dropped",
|
|
905
|
+
`a span held for the sim plan was dropped when released: ${error instanceof Error ? error.message : String(error)}`
|
|
906
|
+
);
|
|
907
|
+
}
|
|
908
|
+
}
|
|
909
|
+
releaseHeld() {
|
|
910
|
+
const held = this.held;
|
|
911
|
+
this.held = [];
|
|
912
|
+
this.syncRetryTimer();
|
|
913
|
+
this.warnDropped();
|
|
914
|
+
for (const entry of held) {
|
|
915
|
+
this.submitEntry(entry);
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
warnDropped() {
|
|
919
|
+
if (this.droppedWhileHolding === 0) {
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
const dropped = this.droppedWhileHolding;
|
|
923
|
+
this.droppedWhileHolding = 0;
|
|
924
|
+
warnOnce(
|
|
925
|
+
"sim-plan-held-overflow",
|
|
926
|
+
`${dropped} record(s) were dropped while the sim plan was still loading; at most ${SIMULATION_PLAN_MAX_HELD} are held per client.`
|
|
927
|
+
);
|
|
928
|
+
}
|
|
929
|
+
warnNeverLoaded() {
|
|
930
|
+
if (this.held.length === 0) {
|
|
931
|
+
return;
|
|
932
|
+
}
|
|
933
|
+
warnOnce(
|
|
934
|
+
"sim-plan-never-loaded",
|
|
935
|
+
`${this.held.length} record(s) were not sent because the sim plan never loaded`
|
|
936
|
+
);
|
|
937
|
+
}
|
|
938
|
+
async release(timeoutMs) {
|
|
939
|
+
this.refresh();
|
|
940
|
+
if (this.holdsWork()) {
|
|
941
|
+
await this.waitForFirstLoad(timeoutMs);
|
|
942
|
+
}
|
|
943
|
+
this.warnNeverLoaded();
|
|
944
|
+
this.warnDropped();
|
|
945
|
+
}
|
|
946
|
+
waitForFirstLoad(timeoutMs) {
|
|
947
|
+
const firstLoad = this.firstLoad();
|
|
948
|
+
if (firstLoad === void 0) {
|
|
949
|
+
return Promise.resolve();
|
|
950
|
+
}
|
|
951
|
+
this.waitingForFirstLoad += 1;
|
|
952
|
+
this.armRetry();
|
|
953
|
+
return new Promise((resolve) => {
|
|
954
|
+
let settled2 = false;
|
|
955
|
+
const finish = () => {
|
|
956
|
+
if (settled2) {
|
|
957
|
+
return;
|
|
958
|
+
}
|
|
959
|
+
settled2 = true;
|
|
960
|
+
this.waitingForFirstLoad -= 1;
|
|
961
|
+
this.syncRetryTimer();
|
|
962
|
+
resolve();
|
|
963
|
+
};
|
|
964
|
+
const timer = setTimeout(finish, Math.max(timeoutMs, 0));
|
|
965
|
+
void firstLoad.then(() => {
|
|
966
|
+
clearTimeout(timer);
|
|
967
|
+
finish();
|
|
968
|
+
});
|
|
969
|
+
});
|
|
970
|
+
}
|
|
971
|
+
stop() {
|
|
972
|
+
if (this.stopped) {
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
this.stopped = true;
|
|
976
|
+
this.retryPending = false;
|
|
977
|
+
this.clearRetryTimer();
|
|
978
|
+
this.warnNeverLoaded();
|
|
979
|
+
this.held = [];
|
|
980
|
+
this.warnDropped();
|
|
981
|
+
}
|
|
982
|
+
contentOff(traceFunctionKey, spanName) {
|
|
983
|
+
return this.contentOffByKey?.get(traceFunctionKey)?.has(spanName) === true;
|
|
984
|
+
}
|
|
985
|
+
apply(payload, traceFunctionKey) {
|
|
986
|
+
if (recordedByFramework(payload)) {
|
|
987
|
+
return payload;
|
|
988
|
+
}
|
|
989
|
+
const name = spanNameOf(payload);
|
|
990
|
+
if (name === void 0 || !this.contentOff(traceFunctionKey, name)) {
|
|
991
|
+
return payload;
|
|
992
|
+
}
|
|
993
|
+
return stripContent(payload);
|
|
994
|
+
}
|
|
995
|
+
};
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
|
|
549
999
|
// src/traceMetadata.ts
|
|
550
1000
|
function findRecord(traceId) {
|
|
551
1001
|
return activeRecords.get(traceId) ?? completedRecords.get(traceId);
|
|
@@ -662,19 +1112,6 @@ var init_transportTypes = __esm({
|
|
|
662
1112
|
}
|
|
663
1113
|
});
|
|
664
1114
|
|
|
665
|
-
// src/unrefTimer.ts
|
|
666
|
-
function unrefTimer(timer) {
|
|
667
|
-
const handle = timer;
|
|
668
|
-
if (typeof handle.unref === "function") {
|
|
669
|
-
handle.unref();
|
|
670
|
-
}
|
|
671
|
-
}
|
|
672
|
-
var init_unrefTimer = __esm({
|
|
673
|
-
"src/unrefTimer.ts"() {
|
|
674
|
-
"use strict";
|
|
675
|
-
}
|
|
676
|
-
});
|
|
677
|
-
|
|
678
1115
|
// src/otel.ts
|
|
679
1116
|
function readBoundedIntEnv(name, max, fallback, warnKey) {
|
|
680
1117
|
const raw = readEnv(name);
|
|
@@ -1325,6 +1762,17 @@ __export(http_exports, {
|
|
|
1325
1762
|
parseRetryAfterMs: () => parseRetryAfterMs,
|
|
1326
1763
|
serializePayloadBody: () => serializePayloadBody
|
|
1327
1764
|
});
|
|
1765
|
+
async function releaseHeldExternalSpans(timeoutMs) {
|
|
1766
|
+
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1767
|
+
for (const client of [...liveHttpClients]) {
|
|
1768
|
+
await client.releaseHeldExternalSpans?.(Math.max(0, deadline - Date.now()));
|
|
1769
|
+
}
|
|
1770
|
+
}
|
|
1771
|
+
function stopSimulationPlans() {
|
|
1772
|
+
for (const client of [...liveHttpClients]) {
|
|
1773
|
+
client.stopSimulationPlan?.();
|
|
1774
|
+
}
|
|
1775
|
+
}
|
|
1328
1776
|
function awaitOnExit(promise) {
|
|
1329
1777
|
pendingTracePromises.add(promise);
|
|
1330
1778
|
void promise.finally(() => {
|
|
@@ -1335,7 +1783,10 @@ function awaitOnExit(promise) {
|
|
|
1335
1783
|
}
|
|
1336
1784
|
async function flushTraces(timeoutMs = 5e3) {
|
|
1337
1785
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1338
|
-
|
|
1786
|
+
await releaseHeldExternalSpans(planWaitSliceMs(timeoutMs));
|
|
1787
|
+
const requestsFlushed = await awaitPendingRequests(
|
|
1788
|
+
Math.max(0, deadline - Date.now())
|
|
1789
|
+
);
|
|
1339
1790
|
const transportsFlushed = await flushTraceTransports(
|
|
1340
1791
|
Math.max(0, deadline - Date.now())
|
|
1341
1792
|
);
|
|
@@ -1454,7 +1905,22 @@ function sourceTraceIdOf(payload) {
|
|
|
1454
1905
|
const id = rawTrace?.id;
|
|
1455
1906
|
return typeof id === "string" ? id : void 0;
|
|
1456
1907
|
}
|
|
1457
|
-
|
|
1908
|
+
function describeError(error) {
|
|
1909
|
+
return error instanceof Error ? error.message : String(error);
|
|
1910
|
+
}
|
|
1911
|
+
function warnDroppedExternalSpan(error) {
|
|
1912
|
+
warnOnce(
|
|
1913
|
+
"external-span-dropped",
|
|
1914
|
+
`a span was dropped because the send step failed: ${describeError(error)}`
|
|
1915
|
+
);
|
|
1916
|
+
}
|
|
1917
|
+
function warnDroppedExternalTrace(error) {
|
|
1918
|
+
warnOnce(
|
|
1919
|
+
"external-trace-dropped",
|
|
1920
|
+
`a trace was dropped because the send step failed: ${describeError(error)}`
|
|
1921
|
+
);
|
|
1922
|
+
}
|
|
1923
|
+
var REPLAY_DB_BRANCH_REQUEST_TIMEOUT_MS, REPLAY_COMPLETE_REQUEST_TIMEOUT_MS, OTLP_TRACES_ENDPOINT, RETRYABLE_STATUSES, EXIT_FLUSH_TIMEOUT_MS, DEFAULT_LIFECYCLE_TIMEOUT_MS2, pendingTracePromises, liveHttpClients, carrierSeq, HttpClient;
|
|
1458
1924
|
var init_http = __esm({
|
|
1459
1925
|
"src/http.ts"() {
|
|
1460
1926
|
"use strict";
|
|
@@ -1463,6 +1929,7 @@ var init_http = __esm({
|
|
|
1463
1929
|
init_errors();
|
|
1464
1930
|
init_replayContext();
|
|
1465
1931
|
init_serializePayload();
|
|
1932
|
+
init_simulationPlan();
|
|
1466
1933
|
init_traceMetadata();
|
|
1467
1934
|
init_transport();
|
|
1468
1935
|
init_transportTypes();
|
|
@@ -1475,6 +1942,7 @@ var init_http = __esm({
|
|
|
1475
1942
|
EXIT_FLUSH_TIMEOUT_MS = 5e3;
|
|
1476
1943
|
DEFAULT_LIFECYCLE_TIMEOUT_MS2 = 3e4;
|
|
1477
1944
|
pendingTracePromises = /* @__PURE__ */ new Set();
|
|
1945
|
+
liveHttpClients = /* @__PURE__ */ new Set();
|
|
1478
1946
|
if (typeof process !== "undefined" && process.versions != null && process.versions.node != null) {
|
|
1479
1947
|
let isFlushing = false;
|
|
1480
1948
|
process.on("beforeExit", () => {
|
|
@@ -1482,12 +1950,27 @@ var init_http = __esm({
|
|
|
1482
1950
|
return;
|
|
1483
1951
|
}
|
|
1484
1952
|
isFlushing = true;
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
})),
|
|
1488
|
-
shutdownTraceTransports(EXIT_FLUSH_TIMEOUT_MS).catch(() => false)
|
|
1489
|
-
]).then(() => {
|
|
1953
|
+
const planWaitMs = SIMULATION_PLAN_READ_TIMEOUT_MS;
|
|
1954
|
+
const stopFlushing = () => {
|
|
1490
1955
|
isFlushing = false;
|
|
1956
|
+
};
|
|
1957
|
+
const deadline = setTimeout(
|
|
1958
|
+
stopFlushing,
|
|
1959
|
+
EXIT_FLUSH_TIMEOUT_MS + planWaitMs
|
|
1960
|
+
);
|
|
1961
|
+
unrefTimer(deadline);
|
|
1962
|
+
void releaseHeldExternalSpans(planWaitMs).catch(() => {
|
|
1963
|
+
}).then(() => {
|
|
1964
|
+
stopSimulationPlans();
|
|
1965
|
+
}).then(
|
|
1966
|
+
() => Promise.allSettled([
|
|
1967
|
+
...Array.from(pendingTracePromises).map((p) => p.catch(() => {
|
|
1968
|
+
})),
|
|
1969
|
+
shutdownTraceTransports(EXIT_FLUSH_TIMEOUT_MS).catch(() => false)
|
|
1970
|
+
])
|
|
1971
|
+
).then(() => {
|
|
1972
|
+
clearTimeout(deadline);
|
|
1973
|
+
stopFlushing();
|
|
1491
1974
|
});
|
|
1492
1975
|
});
|
|
1493
1976
|
}
|
|
@@ -1506,6 +1989,7 @@ var init_http = __esm({
|
|
|
1506
1989
|
this.apiKey = config.apiKey;
|
|
1507
1990
|
this.serviceUrl = config.serviceUrl;
|
|
1508
1991
|
this.timeout = config.timeout ?? 12e4;
|
|
1992
|
+
liveHttpClients.add(this);
|
|
1509
1993
|
}
|
|
1510
1994
|
/**
|
|
1511
1995
|
* Resolve the API key at the moment it is needed (request time), invoking
|
|
@@ -1703,9 +2187,14 @@ var init_http = __esm({
|
|
|
1703
2187
|
* attributing its timeout here would fail a client whose own work succeeded.
|
|
1704
2188
|
*/
|
|
1705
2189
|
async settleDeferredWork(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
|
|
2190
|
+
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
2191
|
+
await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
|
|
1706
2192
|
await replayContextReady.catch(() => {
|
|
1707
2193
|
});
|
|
1708
|
-
return waitForPromises(
|
|
2194
|
+
return waitForPromises(
|
|
2195
|
+
Array.from(this.deferredWork),
|
|
2196
|
+
Math.max(0, deadline - Date.now())
|
|
2197
|
+
);
|
|
1709
2198
|
}
|
|
1710
2199
|
/**
|
|
1711
2200
|
* Wait for spans queued by this client to be delivered, within one deadline.
|
|
@@ -1713,7 +2202,9 @@ var init_http = __esm({
|
|
|
1713
2202
|
*/
|
|
1714
2203
|
async waitForPendingRequests(timeoutMs = DEFAULT_LIFECYCLE_TIMEOUT_MS2) {
|
|
1715
2204
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1716
|
-
const settled2 = await this.settleDeferredWork(
|
|
2205
|
+
const settled2 = await this.settleDeferredWork(
|
|
2206
|
+
Math.max(0, deadline - Date.now())
|
|
2207
|
+
);
|
|
1717
2208
|
const flushed = await this.traceTransport?.flush(Math.max(0, deadline - Date.now())) ?? true;
|
|
1718
2209
|
return settled2 && flushed;
|
|
1719
2210
|
}
|
|
@@ -1728,6 +2219,13 @@ var init_http = __esm({
|
|
|
1728
2219
|
}
|
|
1729
2220
|
const deadline = Date.now() + Math.max(timeoutMs, 0);
|
|
1730
2221
|
this.closing = (async () => {
|
|
2222
|
+
await this.releaseHeldExternalSpans?.(planWaitSliceMs(timeoutMs));
|
|
2223
|
+
this.stopSimulationPlan?.();
|
|
2224
|
+
this.externalSpanTransform = void 0;
|
|
2225
|
+
this.externalTraceTransform = void 0;
|
|
2226
|
+
this.releaseHeldExternalSpans = void 0;
|
|
2227
|
+
this.stopSimulationPlan = void 0;
|
|
2228
|
+
liveHttpClients.delete(this);
|
|
1731
2229
|
const settled2 = await this.settleDeferredWork(
|
|
1732
2230
|
Math.max(0, deadline - Date.now())
|
|
1733
2231
|
);
|
|
@@ -1839,6 +2337,13 @@ var init_http = __esm({
|
|
|
1839
2337
|
protocol
|
|
1840
2338
|
});
|
|
1841
2339
|
}
|
|
2340
|
+
async getSimulationPlan() {
|
|
2341
|
+
return this.get(
|
|
2342
|
+
"/api/sdk/sim-plan",
|
|
2343
|
+
SIMULATION_PLAN_READ_TIMEOUT_MS,
|
|
2344
|
+
{ Connection: "close" }
|
|
2345
|
+
);
|
|
2346
|
+
}
|
|
1842
2347
|
async getTraceSpan(traceId, lookup) {
|
|
1843
2348
|
const searchParams = new URLSearchParams();
|
|
1844
2349
|
if (lookup.id !== void 0) {
|
|
@@ -1855,14 +2360,18 @@ var init_http = __esm({
|
|
|
1855
2360
|
* GET a JSON endpoint on the service with the client's API key. Throws a
|
|
1856
2361
|
* `BitfabError` carrying the status text for any non-2xx response.
|
|
1857
2362
|
*/
|
|
1858
|
-
async get(endpoint) {
|
|
2363
|
+
async get(endpoint, timeoutMs, extraHeaders) {
|
|
1859
2364
|
const url = `${this.serviceUrl}${endpoint}`;
|
|
2365
|
+
const timeout = timeoutMs ?? this.timeout;
|
|
1860
2366
|
const controller = new AbortController();
|
|
1861
|
-
const timeoutId = setTimeout(() => controller.abort(),
|
|
2367
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1862
2368
|
try {
|
|
1863
2369
|
const response = await fetch(url, {
|
|
1864
2370
|
method: "GET",
|
|
1865
|
-
headers: {
|
|
2371
|
+
headers: {
|
|
2372
|
+
Authorization: `Bearer ${this.resolveApiKey() ?? ""}`,
|
|
2373
|
+
...extraHeaders
|
|
2374
|
+
},
|
|
1866
2375
|
signal: controller.signal
|
|
1867
2376
|
});
|
|
1868
2377
|
if (!response.ok) {
|
|
@@ -1881,7 +2390,7 @@ var init_http = __esm({
|
|
|
1881
2390
|
}
|
|
1882
2391
|
if (error instanceof Error) {
|
|
1883
2392
|
if (error.name === "AbortError") {
|
|
1884
|
-
throw new BitfabError(`Request timed out after ${
|
|
2393
|
+
throw new BitfabError(`Request timed out after ${timeout}ms`);
|
|
1885
2394
|
}
|
|
1886
2395
|
throw new BitfabError(error.message);
|
|
1887
2396
|
}
|
|
@@ -1908,16 +2417,27 @@ var init_http = __esm({
|
|
|
1908
2417
|
carrierMeta("internal_trace", body, void 0)
|
|
1909
2418
|
);
|
|
1910
2419
|
}
|
|
1911
|
-
/**
|
|
1912
|
-
* Queue an external span (from withSpan wrapper or OpenAI tracing) onto this
|
|
1913
|
-
* client's batching transport. Fire-and-forget: the transport owns delivery,
|
|
1914
|
-
* so callers await `flushTraces()` or `close()` rather than a per-span
|
|
1915
|
-
* promise.
|
|
1916
|
-
*/
|
|
1917
2420
|
sendExternalSpan(payload) {
|
|
2421
|
+
const gate = this.externalSpanTransform;
|
|
2422
|
+
if (gate === void 0) {
|
|
2423
|
+
this.submitExternalSpan(payload);
|
|
2424
|
+
return;
|
|
2425
|
+
}
|
|
2426
|
+
try {
|
|
2427
|
+
gate(payload, (ready) => this.submitExternalSpan(ready));
|
|
2428
|
+
} catch (error) {
|
|
2429
|
+
warnDroppedExternalSpan(error);
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
submitExternalSpan(payload) {
|
|
2433
|
+
const body = {
|
|
2434
|
+
...payload,
|
|
2435
|
+
sdkVersion: __version__
|
|
2436
|
+
};
|
|
2437
|
+
delete body[ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
1918
2438
|
this.getTraceTransport()?.submit(
|
|
1919
2439
|
"external_span",
|
|
1920
|
-
|
|
2440
|
+
body,
|
|
1921
2441
|
this.recordedMeta("external_span", payload, carrierRef(payload))
|
|
1922
2442
|
);
|
|
1923
2443
|
}
|
|
@@ -1929,6 +2449,18 @@ var init_http = __esm({
|
|
|
1929
2449
|
*/
|
|
1930
2450
|
sendExternalTrace(rawPayload) {
|
|
1931
2451
|
const payload = mergeCallerMetadataIntoTracePayload(rawPayload);
|
|
2452
|
+
const gate = this.externalTraceTransform;
|
|
2453
|
+
if (gate === void 0) {
|
|
2454
|
+
this.submitExternalTrace(payload);
|
|
2455
|
+
return;
|
|
2456
|
+
}
|
|
2457
|
+
try {
|
|
2458
|
+
gate(payload, (ready) => this.submitExternalTrace(ready));
|
|
2459
|
+
} catch (error) {
|
|
2460
|
+
warnDroppedExternalTrace(error);
|
|
2461
|
+
}
|
|
2462
|
+
}
|
|
2463
|
+
submitExternalTrace(payload) {
|
|
1932
2464
|
this.getTraceTransport()?.submit(
|
|
1933
2465
|
"external_trace",
|
|
1934
2466
|
{
|
|
@@ -3642,6 +4174,7 @@ function finalizeTracePayload(payload) {
|
|
|
3642
4174
|
// src/claudeAgentSdk.ts
|
|
3643
4175
|
init_randomUuid();
|
|
3644
4176
|
init_serialize();
|
|
4177
|
+
init_spanOrigin();
|
|
3645
4178
|
|
|
3646
4179
|
// src/timestamp.ts
|
|
3647
4180
|
var lastTimestampMicros = 0;
|
|
@@ -3849,6 +4382,7 @@ var BitfabClaudeAgentHandler = class {
|
|
|
3849
4382
|
trace_id: spanInfo.traceId,
|
|
3850
4383
|
started_at: spanInfo.startedAt,
|
|
3851
4384
|
ended_at: spanInfo.endedAt ?? nowIso(),
|
|
4385
|
+
span_origin: makeSpanOrigin("claude-agent-sdk"),
|
|
3852
4386
|
span_data: spanData
|
|
3853
4387
|
};
|
|
3854
4388
|
if (spanInfo.parentId !== null) {
|
|
@@ -5160,6 +5694,7 @@ init_constants();
|
|
|
5160
5694
|
init_http();
|
|
5161
5695
|
init_randomUuid();
|
|
5162
5696
|
init_serialize();
|
|
5697
|
+
init_spanOrigin();
|
|
5163
5698
|
var LANGSMITH_HIDDEN_TAG = "langsmith:hidden";
|
|
5164
5699
|
var CHAIN_RUN_TYPES = /* @__PURE__ */ new Set(["chain", "parser", "prompt"]);
|
|
5165
5700
|
var LANGGRAPH_METADATA_KEYS = [
|
|
@@ -5514,6 +6049,7 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
5514
6049
|
trace_id: spanInfo.traceId,
|
|
5515
6050
|
started_at: spanInfo.startedAt,
|
|
5516
6051
|
ended_at: spanInfo.endedAt ?? nowIso2(),
|
|
6052
|
+
span_origin: makeSpanOrigin("langgraph"),
|
|
5517
6053
|
span_data: spanData
|
|
5518
6054
|
};
|
|
5519
6055
|
if (spanInfo.parentId !== null) {
|
|
@@ -5775,14 +6311,14 @@ var BitfabLangGraphCallbackHandler = class {
|
|
|
5775
6311
|
init_http();
|
|
5776
6312
|
init_replayContext();
|
|
5777
6313
|
var TOOL_RESULT_TAG = "__bitfabLangGraphToolResult";
|
|
5778
|
-
function
|
|
6314
|
+
function isRecord3(value) {
|
|
5779
6315
|
return typeof value === "object" && value !== null;
|
|
5780
6316
|
}
|
|
5781
6317
|
function isToolMessage(value) {
|
|
5782
|
-
return
|
|
6318
|
+
return isRecord3(value) && value.lc_direct_tool_output === true && value.type === "tool" && (typeof value.content === "string" || Array.isArray(value.content));
|
|
5783
6319
|
}
|
|
5784
6320
|
function isCommand(value) {
|
|
5785
|
-
return
|
|
6321
|
+
return isRecord3(value) && value.lg_name === "Command";
|
|
5786
6322
|
}
|
|
5787
6323
|
function encodeNested(value) {
|
|
5788
6324
|
if (isToolMessage(value) || isCommand(value)) {
|
|
@@ -5791,7 +6327,7 @@ function encodeNested(value) {
|
|
|
5791
6327
|
if (Array.isArray(value)) {
|
|
5792
6328
|
return value.map(encodeNested);
|
|
5793
6329
|
}
|
|
5794
|
-
if (
|
|
6330
|
+
if (isRecord3(value)) {
|
|
5795
6331
|
return Object.fromEntries(
|
|
5796
6332
|
Object.entries(value).map(([key, entry]) => [key, encodeNested(entry)])
|
|
5797
6333
|
);
|
|
@@ -5814,17 +6350,17 @@ function encodeNativeToolResult(value) {
|
|
|
5814
6350
|
}
|
|
5815
6351
|
return {
|
|
5816
6352
|
[TOOL_RESULT_TAG]: "command",
|
|
5817
|
-
graph:
|
|
5818
|
-
update:
|
|
5819
|
-
resume:
|
|
5820
|
-
goto:
|
|
6353
|
+
graph: isRecord3(value) && typeof value.graph === "string" ? value.graph : void 0,
|
|
6354
|
+
update: isRecord3(value) ? encodeNested(value.update) : void 0,
|
|
6355
|
+
resume: isRecord3(value) ? encodeNested(value.resume) : void 0,
|
|
6356
|
+
goto: isRecord3(value) ? encodeNested(value.goto) : void 0
|
|
5821
6357
|
};
|
|
5822
6358
|
}
|
|
5823
6359
|
function finalizeToolResult(value) {
|
|
5824
6360
|
return isToolMessage(value) || isCommand(value) ? encodeNativeToolResult(value) : value;
|
|
5825
6361
|
}
|
|
5826
6362
|
function isEncodedToolResult(value) {
|
|
5827
|
-
return
|
|
6363
|
+
return isRecord3(value) && typeof value[TOOL_RESULT_TAG] === "string";
|
|
5828
6364
|
}
|
|
5829
6365
|
async function loadLangChainCore() {
|
|
5830
6366
|
try {
|
|
@@ -5860,7 +6396,7 @@ async function reviveNested(value, toolCallId) {
|
|
|
5860
6396
|
if (Array.isArray(value)) {
|
|
5861
6397
|
return Promise.all(value.map((entry) => reviveNested(entry, toolCallId)));
|
|
5862
6398
|
}
|
|
5863
|
-
if (
|
|
6399
|
+
if (isRecord3(value)) {
|
|
5864
6400
|
const entries = await Promise.all(
|
|
5865
6401
|
Object.entries(value).map(async ([key, entry]) => [
|
|
5866
6402
|
key,
|
|
@@ -5885,16 +6421,16 @@ async function reviveToolResult(value, toolCallId) {
|
|
|
5885
6421
|
...value.artifact !== void 0 && {
|
|
5886
6422
|
artifact: await reviveNested(value.artifact, toolCallId)
|
|
5887
6423
|
},
|
|
5888
|
-
...
|
|
6424
|
+
...isRecord3(value.metadata) && {
|
|
5889
6425
|
metadata: await reviveNested(value.metadata, toolCallId)
|
|
5890
6426
|
},
|
|
5891
|
-
...
|
|
6427
|
+
...isRecord3(value.additionalKwargs) && {
|
|
5892
6428
|
additional_kwargs: await reviveNested(
|
|
5893
6429
|
value.additionalKwargs,
|
|
5894
6430
|
toolCallId
|
|
5895
6431
|
)
|
|
5896
6432
|
},
|
|
5897
|
-
...
|
|
6433
|
+
...isRecord3(value.responseMetadata) && {
|
|
5898
6434
|
response_metadata: await reviveNested(
|
|
5899
6435
|
value.responseMetadata,
|
|
5900
6436
|
toolCallId
|
|
@@ -5964,8 +6500,8 @@ var BitfabLangGraphIntegration = class {
|
|
|
5964
6500
|
get: (target, property) => {
|
|
5965
6501
|
if (property === "invoke") {
|
|
5966
6502
|
return async (input, ...rest) => {
|
|
5967
|
-
const toolCallId =
|
|
5968
|
-
const args =
|
|
6503
|
+
const toolCallId = isRecord3(input) && typeof input.id === "string" ? input.id : "";
|
|
6504
|
+
const args = isRecord3(input) && "args" in input ? input.args : input;
|
|
5969
6505
|
this.assertReplayToolResultExists(toolName, shouldMock);
|
|
5970
6506
|
const execute = this.client.withSpan(
|
|
5971
6507
|
this.traceFunctionKey,
|
|
@@ -5975,7 +6511,8 @@ var BitfabLangGraphIntegration = class {
|
|
|
5975
6511
|
captureWhen: "nested",
|
|
5976
6512
|
mockOnReplay: shouldMock,
|
|
5977
6513
|
finalize: finalizeToolResult,
|
|
5978
|
-
surface: "inherit"
|
|
6514
|
+
surface: "inherit",
|
|
6515
|
+
instrumentation: "langgraph"
|
|
5979
6516
|
},
|
|
5980
6517
|
async (_args) => await originalInvoke(input, ...rest)
|
|
5981
6518
|
);
|
|
@@ -6018,7 +6555,12 @@ var BitfabLangGraphIntegration = class {
|
|
|
6018
6555
|
wrapInvoke(fn) {
|
|
6019
6556
|
return this.client.withSpan(
|
|
6020
6557
|
this.traceFunctionKey,
|
|
6021
|
-
{
|
|
6558
|
+
{
|
|
6559
|
+
name: this.traceFunctionKey,
|
|
6560
|
+
type: "agent",
|
|
6561
|
+
surface: "inherit",
|
|
6562
|
+
instrumentation: "langgraph"
|
|
6563
|
+
},
|
|
6022
6564
|
fn
|
|
6023
6565
|
);
|
|
6024
6566
|
}
|
|
@@ -6074,7 +6616,8 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
6074
6616
|
const options_ = {
|
|
6075
6617
|
type: "agent",
|
|
6076
6618
|
finalize,
|
|
6077
|
-
surface: "inherit"
|
|
6619
|
+
surface: "inherit",
|
|
6620
|
+
instrumentation: "openai-agents"
|
|
6078
6621
|
};
|
|
6079
6622
|
const traced = this.withSpanFn(
|
|
6080
6623
|
this.traceFunctionKey,
|
|
@@ -6090,6 +6633,7 @@ var BitfabOpenAIAgentHandler = class {
|
|
|
6090
6633
|
};
|
|
6091
6634
|
|
|
6092
6635
|
// src/client.ts
|
|
6636
|
+
init_policyRefresh();
|
|
6093
6637
|
init_randomUuid();
|
|
6094
6638
|
init_replay();
|
|
6095
6639
|
|
|
@@ -6173,12 +6717,15 @@ function runWithSeedContext(ctx, fn) {
|
|
|
6173
6717
|
|
|
6174
6718
|
// src/client.ts
|
|
6175
6719
|
init_serialize();
|
|
6720
|
+
init_simulationPlan();
|
|
6721
|
+
init_spanOrigin();
|
|
6176
6722
|
init_traceMetadata();
|
|
6177
6723
|
|
|
6178
6724
|
// src/tracing.ts
|
|
6179
6725
|
init_constants();
|
|
6180
6726
|
init_http();
|
|
6181
6727
|
init_randomUuid();
|
|
6728
|
+
init_spanOrigin();
|
|
6182
6729
|
var BitfabOpenAITracingProcessor = class {
|
|
6183
6730
|
/**
|
|
6184
6731
|
* Initialize the tracing processor.
|
|
@@ -6380,6 +6927,7 @@ var BitfabOpenAITracingProcessor = class {
|
|
|
6380
6927
|
* Build span payload for the external spans API.
|
|
6381
6928
|
*/
|
|
6382
6929
|
buildSpanPayload(serializedSpan, errors) {
|
|
6930
|
+
serializedSpan.span_origin = makeSpanOrigin("openai-agents");
|
|
6383
6931
|
const payload = {
|
|
6384
6932
|
id: randomUuid(),
|
|
6385
6933
|
type: "openai",
|
|
@@ -6509,7 +7057,8 @@ var BitfabVercelAiHandler = class {
|
|
|
6509
7057
|
{
|
|
6510
7058
|
type: "llm",
|
|
6511
7059
|
finalize: (result) => summarizeGenerate(result ?? {}, label),
|
|
6512
|
-
surface: "inherit"
|
|
7060
|
+
surface: "inherit",
|
|
7061
|
+
instrumentation: "vercel-ai"
|
|
6513
7062
|
},
|
|
6514
7063
|
() => doGenerate()
|
|
6515
7064
|
);
|
|
@@ -6527,7 +7076,12 @@ var BitfabVercelAiHandler = class {
|
|
|
6527
7076
|
// The wrapped fn returns immediately with the live stream, so the span
|
|
6528
7077
|
// output cannot be read from the return value. `finalize` instead
|
|
6529
7078
|
// awaits the summary the accumulator resolves once the stream drains.
|
|
6530
|
-
{
|
|
7079
|
+
{
|
|
7080
|
+
type: "llm",
|
|
7081
|
+
finalize: () => summary,
|
|
7082
|
+
surface: "inherit",
|
|
7083
|
+
instrumentation: "vercel-ai"
|
|
7084
|
+
},
|
|
6531
7085
|
async () => {
|
|
6532
7086
|
const result = await doStream();
|
|
6533
7087
|
const stream = result.stream.pipeThrough(
|
|
@@ -6545,6 +7099,19 @@ var BitfabVercelAiHandler = class {
|
|
|
6545
7099
|
// src/client.ts
|
|
6546
7100
|
init_warnOnce();
|
|
6547
7101
|
var activeTraceStates = /* @__PURE__ */ new Map();
|
|
7102
|
+
function rootTraceFunctionKeyOf(payload) {
|
|
7103
|
+
const captured = payload[ROOT_TRACE_FUNCTION_KEY_FIELD];
|
|
7104
|
+
if (typeof captured === "string") {
|
|
7105
|
+
return captured;
|
|
7106
|
+
}
|
|
7107
|
+
const traceId = payload.traceId;
|
|
7108
|
+
const live = typeof traceId === "string" ? activeTraceStates.get(traceId)?.traceFunctionKey : void 0;
|
|
7109
|
+
if (typeof live === "string") {
|
|
7110
|
+
return live;
|
|
7111
|
+
}
|
|
7112
|
+
const own = payload.traceFunctionKey;
|
|
7113
|
+
return typeof own === "string" ? own : void 0;
|
|
7114
|
+
}
|
|
6548
7115
|
var asyncLocalStorage = null;
|
|
6549
7116
|
var SPAN_CONTEXT_STORAGE_SYMBOL = /* @__PURE__ */ Symbol.for("bitfab.spanContextStorage");
|
|
6550
7117
|
var initializeAsyncContext = () => {
|
|
@@ -6949,6 +7516,14 @@ var Bitfab = class {
|
|
|
6949
7516
|
serviceUrl: this.serviceUrl,
|
|
6950
7517
|
timeout: this.timeout
|
|
6951
7518
|
});
|
|
7519
|
+
this.simulationPlan = new SimulationPlan(
|
|
7520
|
+
this.httpClient,
|
|
7521
|
+
config.simulationPlan ?? true
|
|
7522
|
+
);
|
|
7523
|
+
this.httpClient.externalSpanTransform = (payload, submit) => this.applySimulationPlan(payload, submit);
|
|
7524
|
+
this.httpClient.externalTraceTransform = (payload, submit) => this.simulationPlan.sendTrace(payload, submit);
|
|
7525
|
+
this.httpClient.releaseHeldExternalSpans = (timeoutMs) => this.simulationPlan.release(timeoutMs);
|
|
7526
|
+
this.httpClient.stopSimulationPlan = () => this.simulationPlan.stop();
|
|
6952
7527
|
this.datasets = new DatasetsClient(this.httpClient);
|
|
6953
7528
|
this.traces = new TracesClient(this.httpClient);
|
|
6954
7529
|
this.labels = new LabelsClient(this.httpClient);
|
|
@@ -7099,6 +7674,7 @@ var Bitfab = class {
|
|
|
7099
7674
|
}
|
|
7100
7675
|
createAutoTraceRoot(traceFunctionKey, name, options, fn) {
|
|
7101
7676
|
const self = this;
|
|
7677
|
+
self.simulationPlan.refresh();
|
|
7102
7678
|
const maxDepth = autoTraceLimit(
|
|
7103
7679
|
options.maxDepth,
|
|
7104
7680
|
DEFAULT_AUTO_TRACE_MAX_DEPTH
|
|
@@ -7114,7 +7690,8 @@ var Bitfab = class {
|
|
|
7114
7690
|
name: options.name,
|
|
7115
7691
|
nameFor: rootNameFor,
|
|
7116
7692
|
type: options.type ?? "custom",
|
|
7117
|
-
surface: "opt-out"
|
|
7693
|
+
surface: "opt-out",
|
|
7694
|
+
instrumentation: "trace"
|
|
7118
7695
|
};
|
|
7119
7696
|
const buildTracedRoot = (spanOptions) => this.withSpan(
|
|
7120
7697
|
traceFunctionKey,
|
|
@@ -7125,6 +7702,7 @@ var Bitfab = class {
|
|
|
7125
7702
|
traceFunctionKey
|
|
7126
7703
|
);
|
|
7127
7704
|
self.refreshAutoTraceCapturePolicy(traceFunctionKey);
|
|
7705
|
+
self.simulationPlan.refresh();
|
|
7128
7706
|
let spansUsed = 0;
|
|
7129
7707
|
let truncated = false;
|
|
7130
7708
|
const warnTruncated = () => {
|
|
@@ -7201,6 +7779,7 @@ var Bitfab = class {
|
|
|
7201
7779
|
type: nodeConfiguration?.type ?? "function",
|
|
7202
7780
|
captureWhen: "nested",
|
|
7203
7781
|
surface: "opt-out",
|
|
7782
|
+
instrumentation: "trace",
|
|
7204
7783
|
functionId: definition.id,
|
|
7205
7784
|
captureContent: nodeConfiguration !== void 0 || capturePolicy === void 0 || capturePolicy.has(definition.id),
|
|
7206
7785
|
autoTraceDefinition: definition,
|
|
@@ -7232,6 +7811,7 @@ var Bitfab = class {
|
|
|
7232
7811
|
type: "function",
|
|
7233
7812
|
captureWhen: "nested",
|
|
7234
7813
|
surface: "opt-out",
|
|
7814
|
+
instrumentation: "trace",
|
|
7235
7815
|
captureContent: true,
|
|
7236
7816
|
...link !== void 0 && { nestedTrace: link }
|
|
7237
7817
|
};
|
|
@@ -7297,38 +7877,36 @@ var Bitfab = class {
|
|
|
7297
7877
|
Object.defineProperty(autoTraceRoot, "_bitfabWrappedFn", { value: fn });
|
|
7298
7878
|
return autoTraceRoot;
|
|
7299
7879
|
}
|
|
7880
|
+
applySimulationPlan(payload, submit) {
|
|
7881
|
+
this.simulationPlan.send(payload, rootTraceFunctionKeyOf(payload), submit);
|
|
7882
|
+
}
|
|
7300
7883
|
refreshAutoTraceCapturePolicy(traceFunctionKey) {
|
|
7301
|
-
const
|
|
7302
|
-
const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? {
|
|
7303
|
-
refreshAfter: 0
|
|
7304
|
-
};
|
|
7305
|
-
if (state.inFlight || now < state.refreshAfter) {
|
|
7306
|
-
return;
|
|
7307
|
-
}
|
|
7308
|
-
const request = this.httpClient.getAutoTracePolicy(
|
|
7309
|
-
traceFunctionKey,
|
|
7310
|
-
AUTO_TRACE_PROTOCOL
|
|
7311
|
-
).then((policy) => {
|
|
7312
|
-
if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
|
|
7313
|
-
state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
|
|
7314
|
-
return;
|
|
7315
|
-
}
|
|
7316
|
-
const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
|
|
7317
|
-
(id) => typeof id === "string" && id.startsWith(`${AUTO_TRACE_PROTOCOL}:`)
|
|
7318
|
-
).slice(0, DEFAULT_AUTO_TRACE_MAX_SPANS) : [];
|
|
7319
|
-
__setBitfabAutoTraceCapturePolicy(
|
|
7320
|
-
this,
|
|
7321
|
-
traceFunctionKey,
|
|
7322
|
-
policy.revision === null ? void 0 : functionIds
|
|
7323
|
-
);
|
|
7324
|
-
state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_REFRESH_MS;
|
|
7325
|
-
}).catch(() => {
|
|
7326
|
-
state.refreshAfter = Date.now() + AUTO_TRACE_POLICY_RETRY_MS;
|
|
7327
|
-
}).finally(() => {
|
|
7328
|
-
state.inFlight = void 0;
|
|
7329
|
-
});
|
|
7330
|
-
state.inFlight = request;
|
|
7884
|
+
const state = this.autoTracePolicyRefreshes.get(traceFunctionKey) ?? new PolicyRefresh();
|
|
7331
7885
|
this.autoTracePolicyRefreshes.set(traceFunctionKey, state);
|
|
7886
|
+
state.run(
|
|
7887
|
+
() => this.httpClient.getAutoTracePolicy(
|
|
7888
|
+
traceFunctionKey,
|
|
7889
|
+
AUTO_TRACE_PROTOCOL
|
|
7890
|
+
),
|
|
7891
|
+
(policy) => {
|
|
7892
|
+
if (policy.protocol !== AUTO_TRACE_PROTOCOL) {
|
|
7893
|
+
state.hold(AUTO_TRACE_POLICY_RETRY_MS);
|
|
7894
|
+
return;
|
|
7895
|
+
}
|
|
7896
|
+
const functionIds = Array.isArray(policy.functionIds) ? policy.functionIds.filter(
|
|
7897
|
+
(id) => typeof id === "string" && id.startsWith(`${AUTO_TRACE_PROTOCOL}:`)
|
|
7898
|
+
).slice(0, DEFAULT_AUTO_TRACE_MAX_SPANS) : [];
|
|
7899
|
+
__setBitfabAutoTraceCapturePolicy(
|
|
7900
|
+
this,
|
|
7901
|
+
traceFunctionKey,
|
|
7902
|
+
policy.revision === null ? void 0 : functionIds
|
|
7903
|
+
);
|
|
7904
|
+
state.hold(AUTO_TRACE_POLICY_REFRESH_MS);
|
|
7905
|
+
},
|
|
7906
|
+
() => {
|
|
7907
|
+
state.hold(AUTO_TRACE_POLICY_RETRY_MS);
|
|
7908
|
+
}
|
|
7909
|
+
);
|
|
7332
7910
|
}
|
|
7333
7911
|
/**
|
|
7334
7912
|
* Flush and permanently close this client's tracing resources: its pending
|
|
@@ -7812,6 +8390,7 @@ var Bitfab = class {
|
|
|
7812
8390
|
* @returns A wrapped function with the same signature that creates spans for inputs and outputs
|
|
7813
8391
|
*/
|
|
7814
8392
|
withSpan(traceFunctionKey, optionsOrFn, maybeFn) {
|
|
8393
|
+
this.simulationPlan.refresh();
|
|
7815
8394
|
const options = typeof optionsOrFn === "function" ? {} : optionsOrFn;
|
|
7816
8395
|
const fn = typeof optionsOrFn === "function" ? optionsOrFn : maybeFn;
|
|
7817
8396
|
const self = this;
|
|
@@ -7903,8 +8482,10 @@ var Bitfab = class {
|
|
|
7903
8482
|
const testRunId = replayCtxAtStart?.testRunId ?? options.testRunId;
|
|
7904
8483
|
if (isRootSpan && !activeTraceStates.has(traceId)) {
|
|
7905
8484
|
const dbSnapshotRef = buildSnapshotRef(self.dbSnapshot, startedAt);
|
|
8485
|
+
self.simulationPlan.refresh();
|
|
7906
8486
|
activeTraceStates.set(traceId, {
|
|
7907
8487
|
traceId,
|
|
8488
|
+
traceFunctionKey,
|
|
7908
8489
|
startedAt,
|
|
7909
8490
|
contexts: [],
|
|
7910
8491
|
...testRunId !== void 0 && { testRunId },
|
|
@@ -7919,8 +8500,10 @@ var Bitfab = class {
|
|
|
7919
8500
|
registeredTraceId = traceId;
|
|
7920
8501
|
}
|
|
7921
8502
|
const functionName = fn.name !== "" ? fn.name : void 0;
|
|
8503
|
+
const rootTraceFunctionKey = activeTraceStates.get(traceId)?.traceFunctionKey ?? traceFunctionKey;
|
|
7922
8504
|
const baseSpanParams = {
|
|
7923
8505
|
traceFunctionKey,
|
|
8506
|
+
rootTraceFunctionKey,
|
|
7924
8507
|
functionName,
|
|
7925
8508
|
spanName: options.name ?? options.nameFor?.(this) ?? qualifiedSpanName(this, functionName) ?? traceFunctionKey,
|
|
7926
8509
|
traceId,
|
|
@@ -7929,6 +8512,7 @@ var Bitfab = class {
|
|
|
7929
8512
|
inputs,
|
|
7930
8513
|
startedAt,
|
|
7931
8514
|
spanType: options.type ?? "custom",
|
|
8515
|
+
instrumentation: options.instrumentation ?? "span",
|
|
7932
8516
|
functionId: options.functionId,
|
|
7933
8517
|
captureContent: options.captureContent ?? true,
|
|
7934
8518
|
autoTraceDefinition: options.autoTraceDefinition,
|
|
@@ -8344,6 +8928,7 @@ var Bitfab = class {
|
|
|
8344
8928
|
* @returns A BitfabFunction instance for wrapping functions
|
|
8345
8929
|
*/
|
|
8346
8930
|
getFunction(traceFunctionKey) {
|
|
8931
|
+
this.simulationPlan.refresh();
|
|
8347
8932
|
return new BitfabFunction(this, traceFunctionKey);
|
|
8348
8933
|
}
|
|
8349
8934
|
/**
|
|
@@ -8431,6 +9016,7 @@ var Bitfab = class {
|
|
|
8431
9016
|
trace_id: params.traceId,
|
|
8432
9017
|
started_at: params.startedAt,
|
|
8433
9018
|
ended_at: params.endedAt,
|
|
9019
|
+
span_origin: makeSpanOrigin(params.instrumentation),
|
|
8434
9020
|
span_data: {
|
|
8435
9021
|
name: params.spanName,
|
|
8436
9022
|
type: params.spanType,
|
|
@@ -8491,6 +9077,9 @@ var Bitfab = class {
|
|
|
8491
9077
|
source: "typescript-sdk-function",
|
|
8492
9078
|
sourceTraceId: params.traceId,
|
|
8493
9079
|
traceFunctionKey: params.traceFunctionKey,
|
|
9080
|
+
...params.rootTraceFunctionKey !== void 0 && {
|
|
9081
|
+
[ROOT_TRACE_FUNCTION_KEY_FIELD]: params.rootTraceFunctionKey
|
|
9082
|
+
},
|
|
8494
9083
|
rawSpan: externalSpan,
|
|
8495
9084
|
...params.testRunId && { testRunId: params.testRunId },
|
|
8496
9085
|
...params.mocked && { mocked: true },
|
|
@@ -8559,6 +9148,7 @@ var Bitfab = class {
|
|
|
8559
9148
|
}
|
|
8560
9149
|
activeTraceStates.set(traceId, {
|
|
8561
9150
|
traceId,
|
|
9151
|
+
traceFunctionKey,
|
|
8562
9152
|
startedAt,
|
|
8563
9153
|
contexts: [],
|
|
8564
9154
|
ingestionType: "seeded",
|
|
@@ -8568,6 +9158,7 @@ var Bitfab = class {
|
|
|
8568
9158
|
try {
|
|
8569
9159
|
this.sendWrapperSpan({
|
|
8570
9160
|
traceFunctionKey,
|
|
9161
|
+
rootTraceFunctionKey: traceFunctionKey,
|
|
8571
9162
|
spanName: options.spanName ?? traceFunctionKey,
|
|
8572
9163
|
traceId,
|
|
8573
9164
|
spanId: randomUuid(),
|
|
@@ -8577,6 +9168,7 @@ var Bitfab = class {
|
|
|
8577
9168
|
startedAt,
|
|
8578
9169
|
endedAt: startedAt,
|
|
8579
9170
|
spanType: options.spanType ?? "agent",
|
|
9171
|
+
instrumentation: "span",
|
|
8580
9172
|
captureContent: true
|
|
8581
9173
|
});
|
|
8582
9174
|
this.sendTraceCompletion({
|
|
@@ -8622,6 +9214,7 @@ var Bitfab = class {
|
|
|
8622
9214
|
}
|
|
8623
9215
|
activeTraceStates.set(traceId, {
|
|
8624
9216
|
traceId,
|
|
9217
|
+
traceFunctionKey,
|
|
8625
9218
|
startedAt: nowIsoTimestamp(),
|
|
8626
9219
|
contexts: [],
|
|
8627
9220
|
ingestionType: "seeded",
|