@fallom/trace 0.1.12 → 0.2.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/README.md +215 -178
- package/dist/chunk-2BP4H4AD.mjs +3012 -0
- package/dist/chunk-7P6ASYW6.mjs +9 -0
- package/dist/chunk-K7HYYE4Y.mjs +2930 -0
- package/dist/chunk-KAZ5NEU2.mjs +2237 -0
- package/dist/chunk-KMA4IPED.mjs +252 -0
- package/dist/chunk-W6M2RQ3W.mjs +251 -0
- package/dist/index.d.mts +208 -256
- package/dist/index.d.ts +208 -256
- package/dist/index.js +794 -789
- package/dist/index.mjs +594 -590
- package/dist/models-2Y6DRQPS.mjs +9 -0
- package/dist/models-BUHMMTWK.mjs +9 -0
- package/dist/models-JIO5LVMB.mjs +8 -0
- package/dist/models-JKMOBZUO.mjs +8 -0
- package/dist/prompts-XSZHTCX7.mjs +15 -0
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,25 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
__export,
|
|
3
3
|
init,
|
|
4
|
-
|
|
5
|
-
} from "./chunk-
|
|
4
|
+
models_exports
|
|
5
|
+
} from "./chunk-W6M2RQ3W.mjs";
|
|
6
6
|
|
|
7
7
|
// src/trace.ts
|
|
8
8
|
var trace_exports = {};
|
|
9
9
|
__export(trace_exports, {
|
|
10
|
-
|
|
11
|
-
getSession: () => getSession,
|
|
10
|
+
FallomSession: () => FallomSession,
|
|
12
11
|
init: () => init2,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
shutdown: () => shutdown,
|
|
16
|
-
span: () => span,
|
|
17
|
-
wrapAISDK: () => wrapAISDK,
|
|
18
|
-
wrapAnthropic: () => wrapAnthropic,
|
|
19
|
-
wrapGoogleAI: () => wrapGoogleAI,
|
|
20
|
-
wrapMastraAgent: () => wrapMastraAgent,
|
|
21
|
-
wrapOpenAI: () => wrapOpenAI
|
|
12
|
+
session: () => session,
|
|
13
|
+
shutdown: () => shutdown
|
|
22
14
|
});
|
|
15
|
+
|
|
16
|
+
// src/trace/core.ts
|
|
23
17
|
import { AsyncLocalStorage } from "async_hooks";
|
|
24
18
|
import { NodeSDK } from "@opentelemetry/sdk-node";
|
|
25
19
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
@@ -621,9 +615,9 @@ var Resource = (
|
|
|
621
615
|
})()
|
|
622
616
|
);
|
|
623
617
|
|
|
624
|
-
// src/trace.ts
|
|
625
|
-
var
|
|
626
|
-
var
|
|
618
|
+
// src/trace/core.ts
|
|
619
|
+
var traceContextStorage = new AsyncLocalStorage();
|
|
620
|
+
var fallbackTraceContext = null;
|
|
627
621
|
var apiKey = null;
|
|
628
622
|
var baseUrl = "https://traces.fallom.com";
|
|
629
623
|
var initialized = false;
|
|
@@ -633,28 +627,27 @@ var sdk = null;
|
|
|
633
627
|
function log(...args) {
|
|
634
628
|
if (debugMode) console.log("[Fallom]", ...args);
|
|
635
629
|
}
|
|
630
|
+
function getTraceContextStorage() {
|
|
631
|
+
return traceContextStorage;
|
|
632
|
+
}
|
|
633
|
+
function getFallbackTraceContext() {
|
|
634
|
+
return fallbackTraceContext;
|
|
635
|
+
}
|
|
636
|
+
function isInitialized() {
|
|
637
|
+
return initialized;
|
|
638
|
+
}
|
|
639
|
+
function shouldCaptureContent() {
|
|
640
|
+
return captureContent;
|
|
641
|
+
}
|
|
642
|
+
function isDebugMode() {
|
|
643
|
+
return debugMode;
|
|
644
|
+
}
|
|
636
645
|
var fallomSpanProcessor = {
|
|
637
|
-
onStart(
|
|
638
|
-
log("\u{1F4CD} Span started:",
|
|
639
|
-
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
640
|
-
if (ctx) {
|
|
641
|
-
span2.setAttribute("fallom.config_key", ctx.configKey);
|
|
642
|
-
span2.setAttribute("fallom.session_id", ctx.sessionId);
|
|
643
|
-
if (ctx.customerId) {
|
|
644
|
-
span2.setAttribute("fallom.customer_id", ctx.customerId);
|
|
645
|
-
}
|
|
646
|
-
log(
|
|
647
|
-
" Added session context:",
|
|
648
|
-
ctx.configKey,
|
|
649
|
-
ctx.sessionId,
|
|
650
|
-
ctx.customerId
|
|
651
|
-
);
|
|
652
|
-
} else {
|
|
653
|
-
log(" No session context available");
|
|
654
|
-
}
|
|
646
|
+
onStart(span, _parentContext) {
|
|
647
|
+
log("\u{1F4CD} Span started:", span.name || "unknown");
|
|
655
648
|
},
|
|
656
|
-
onEnd(
|
|
657
|
-
log("\u2705 Span ended:",
|
|
649
|
+
onEnd(span) {
|
|
650
|
+
log("\u2705 Span ended:", span.name, "duration:", span.duration);
|
|
658
651
|
},
|
|
659
652
|
shutdown() {
|
|
660
653
|
return Promise.resolve();
|
|
@@ -663,47 +656,6 @@ var fallomSpanProcessor = {
|
|
|
663
656
|
return Promise.resolve();
|
|
664
657
|
}
|
|
665
658
|
};
|
|
666
|
-
async function init2(options = {}) {
|
|
667
|
-
if (initialized) return;
|
|
668
|
-
debugMode = options.debug ?? false;
|
|
669
|
-
log("\u{1F680} Initializing Fallom tracing...");
|
|
670
|
-
apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
671
|
-
baseUrl = options.baseUrl || process.env.FALLOM_TRACES_URL || process.env.FALLOM_BASE_URL || "https://traces.fallom.com";
|
|
672
|
-
const envCapture = process.env.FALLOM_CAPTURE_CONTENT?.toLowerCase();
|
|
673
|
-
if (envCapture === "false" || envCapture === "0" || envCapture === "no") {
|
|
674
|
-
captureContent = false;
|
|
675
|
-
} else {
|
|
676
|
-
captureContent = options.captureContent ?? true;
|
|
677
|
-
}
|
|
678
|
-
if (!apiKey) {
|
|
679
|
-
throw new Error(
|
|
680
|
-
"No API key provided. Set FALLOM_API_KEY environment variable or pass apiKey parameter."
|
|
681
|
-
);
|
|
682
|
-
}
|
|
683
|
-
initialized = true;
|
|
684
|
-
log("\u{1F4E1} Exporter URL:", `${baseUrl}/v1/traces`);
|
|
685
|
-
const exporter = new OTLPTraceExporter({
|
|
686
|
-
url: `${baseUrl}/v1/traces`,
|
|
687
|
-
headers: {
|
|
688
|
-
Authorization: `Bearer ${apiKey}`
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
const instrumentations = await getInstrumentations();
|
|
692
|
-
log("\u{1F527} Loaded instrumentations:", instrumentations.length);
|
|
693
|
-
sdk = new NodeSDK({
|
|
694
|
-
resource: new Resource({
|
|
695
|
-
"service.name": "fallom-traced-app"
|
|
696
|
-
}),
|
|
697
|
-
traceExporter: exporter,
|
|
698
|
-
spanProcessor: fallomSpanProcessor,
|
|
699
|
-
instrumentations
|
|
700
|
-
});
|
|
701
|
-
sdk.start();
|
|
702
|
-
log("\u2705 SDK started");
|
|
703
|
-
process.on("SIGTERM", () => {
|
|
704
|
-
sdk?.shutdown().catch(console.error);
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
659
|
async function getInstrumentations() {
|
|
708
660
|
const instrumentations = [];
|
|
709
661
|
await tryAddInstrumentation(
|
|
@@ -758,75 +710,90 @@ async function tryAddInstrumentation(instrumentations, pkg, className) {
|
|
|
758
710
|
Object.keys(mod)
|
|
759
711
|
);
|
|
760
712
|
}
|
|
761
|
-
} catch
|
|
713
|
+
} catch {
|
|
762
714
|
log(` \u274C ${pkg} not installed`);
|
|
763
715
|
}
|
|
764
716
|
}
|
|
765
|
-
function
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
return sessionStorage.run({ configKey, sessionId }, customerIdOrFn);
|
|
777
|
-
}
|
|
778
|
-
return sessionStorage.run(
|
|
779
|
-
{ configKey, sessionId, customerId: customerIdOrFn },
|
|
780
|
-
fn
|
|
781
|
-
);
|
|
782
|
-
}
|
|
783
|
-
function getSession() {
|
|
784
|
-
return sessionStorage.getStore() || fallbackSession || void 0;
|
|
785
|
-
}
|
|
786
|
-
function clearSession() {
|
|
787
|
-
fallbackSession = null;
|
|
788
|
-
}
|
|
789
|
-
function span(data, options = {}) {
|
|
790
|
-
if (!initialized) {
|
|
791
|
-
throw new Error("Fallom not initialized. Call trace.init() first.");
|
|
717
|
+
async function init2(options = {}) {
|
|
718
|
+
if (initialized) return;
|
|
719
|
+
debugMode = options.debug ?? false;
|
|
720
|
+
log("\u{1F680} Initializing Fallom tracing...");
|
|
721
|
+
apiKey = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
722
|
+
baseUrl = options.baseUrl || process.env.FALLOM_TRACES_URL || process.env.FALLOM_BASE_URL || "https://traces.fallom.com";
|
|
723
|
+
const envCapture = process.env.FALLOM_CAPTURE_CONTENT?.toLowerCase();
|
|
724
|
+
if (envCapture === "false" || envCapture === "0" || envCapture === "no") {
|
|
725
|
+
captureContent = false;
|
|
726
|
+
} else {
|
|
727
|
+
captureContent = options.captureContent ?? true;
|
|
792
728
|
}
|
|
793
|
-
|
|
794
|
-
const configKey = options.configKey || ctx?.configKey;
|
|
795
|
-
const sessionId = options.sessionId || ctx?.sessionId;
|
|
796
|
-
if (!configKey || !sessionId) {
|
|
729
|
+
if (!apiKey) {
|
|
797
730
|
throw new Error(
|
|
798
|
-
"No
|
|
731
|
+
"No API key provided. Set FALLOM_API_KEY environment variable or pass apiKey parameter."
|
|
799
732
|
);
|
|
800
733
|
}
|
|
801
|
-
|
|
734
|
+
initialized = true;
|
|
735
|
+
log("\u{1F4E1} Exporter URL:", `${baseUrl}/v1/traces`);
|
|
736
|
+
const exporter = new OTLPTraceExporter({
|
|
737
|
+
url: `${baseUrl}/v1/traces`,
|
|
738
|
+
headers: {
|
|
739
|
+
Authorization: `Bearer ${apiKey}`
|
|
740
|
+
}
|
|
741
|
+
});
|
|
742
|
+
const instrumentations = await getInstrumentations();
|
|
743
|
+
log("\u{1F527} Loaded instrumentations:", instrumentations.length);
|
|
744
|
+
sdk = new NodeSDK({
|
|
745
|
+
resource: new Resource({
|
|
746
|
+
"service.name": "fallom-traced-app"
|
|
747
|
+
}),
|
|
748
|
+
traceExporter: exporter,
|
|
749
|
+
spanProcessor: fallomSpanProcessor,
|
|
750
|
+
instrumentations
|
|
751
|
+
});
|
|
752
|
+
sdk.start();
|
|
753
|
+
log("\u2705 SDK started");
|
|
754
|
+
process.on("SIGTERM", () => {
|
|
755
|
+
sdk?.shutdown().catch(console.error);
|
|
802
756
|
});
|
|
803
757
|
}
|
|
804
|
-
async function
|
|
758
|
+
async function shutdown() {
|
|
759
|
+
if (sdk) {
|
|
760
|
+
await sdk.shutdown();
|
|
761
|
+
initialized = false;
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
async function sendTrace(trace) {
|
|
765
|
+
const url = `${baseUrl}/v1/traces`;
|
|
766
|
+
log("\u{1F4E4} Sending trace to:", url);
|
|
767
|
+
log(" Session:", trace.session_id, "Config:", trace.config_key);
|
|
805
768
|
try {
|
|
806
769
|
const controller = new AbortController();
|
|
807
770
|
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
808
|
-
await fetch(
|
|
771
|
+
const response = await fetch(url, {
|
|
809
772
|
method: "POST",
|
|
810
773
|
headers: {
|
|
811
774
|
Authorization: `Bearer ${apiKey}`,
|
|
812
775
|
"Content-Type": "application/json"
|
|
813
776
|
},
|
|
814
|
-
body: JSON.stringify(
|
|
815
|
-
config_key: configKey,
|
|
816
|
-
session_id: sessionId,
|
|
817
|
-
data
|
|
818
|
-
}),
|
|
777
|
+
body: JSON.stringify(trace),
|
|
819
778
|
signal: controller.signal
|
|
820
779
|
});
|
|
821
780
|
clearTimeout(timeoutId);
|
|
822
|
-
|
|
781
|
+
if (!response.ok) {
|
|
782
|
+
const text = await response.text();
|
|
783
|
+
log("\u274C Trace send failed:", response.status, text);
|
|
784
|
+
} else {
|
|
785
|
+
log("\u2705 Trace sent:", trace.name, trace.model);
|
|
786
|
+
}
|
|
787
|
+
} catch (err) {
|
|
788
|
+
log("\u274C Trace send error:", err instanceof Error ? err.message : err);
|
|
823
789
|
}
|
|
824
790
|
}
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
791
|
+
|
|
792
|
+
// src/trace/utils.ts
|
|
793
|
+
function generateHexId(length) {
|
|
794
|
+
const bytes = new Uint8Array(length / 2);
|
|
795
|
+
crypto.getRandomValues(bytes);
|
|
796
|
+
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
830
797
|
}
|
|
831
798
|
function messagesToOtelAttributes(messages, completion, model, responseId) {
|
|
832
799
|
const attrs = {};
|
|
@@ -854,65 +821,28 @@ function messagesToOtelAttributes(messages, completion, model, responseId) {
|
|
|
854
821
|
}
|
|
855
822
|
return attrs;
|
|
856
823
|
}
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
861
|
-
}
|
|
862
|
-
var traceContextStorage = new AsyncLocalStorage();
|
|
863
|
-
var fallbackTraceContext = null;
|
|
864
|
-
async function sendTrace(trace) {
|
|
865
|
-
const url = `${baseUrl}/v1/traces`;
|
|
866
|
-
log("\u{1F4E4} Sending trace to:", url);
|
|
867
|
-
log(" Session:", trace.session_id, "Config:", trace.config_key);
|
|
868
|
-
try {
|
|
869
|
-
const controller = new AbortController();
|
|
870
|
-
const timeoutId = setTimeout(() => controller.abort(), 5e3);
|
|
871
|
-
const response = await fetch(url, {
|
|
872
|
-
method: "POST",
|
|
873
|
-
headers: {
|
|
874
|
-
Authorization: `Bearer ${apiKey}`,
|
|
875
|
-
"Content-Type": "application/json"
|
|
876
|
-
},
|
|
877
|
-
body: JSON.stringify(trace),
|
|
878
|
-
signal: controller.signal
|
|
879
|
-
});
|
|
880
|
-
clearTimeout(timeoutId);
|
|
881
|
-
if (!response.ok) {
|
|
882
|
-
const text = await response.text();
|
|
883
|
-
log("\u274C Trace send failed:", response.status, text);
|
|
884
|
-
} else {
|
|
885
|
-
log("\u2705 Trace sent:", trace.name, trace.model);
|
|
886
|
-
}
|
|
887
|
-
} catch (err) {
|
|
888
|
-
log("\u274C Trace send error:", err instanceof Error ? err.message : err);
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
function wrapOpenAI(client) {
|
|
824
|
+
|
|
825
|
+
// src/trace/wrappers/openai.ts
|
|
826
|
+
function wrapOpenAI(client, sessionCtx) {
|
|
892
827
|
const originalCreate = client.chat.completions.create.bind(
|
|
893
828
|
client.chat.completions
|
|
894
829
|
);
|
|
830
|
+
const ctx = sessionCtx;
|
|
895
831
|
client.chat.completions.create = async function(...args) {
|
|
896
|
-
|
|
897
|
-
if (!ctx || !initialized) {
|
|
832
|
+
if (!isInitialized()) {
|
|
898
833
|
return originalCreate(...args);
|
|
899
834
|
}
|
|
900
|
-
|
|
901
|
-
try {
|
|
902
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
903
|
-
promptCtx = getPromptContext();
|
|
904
|
-
} catch {
|
|
905
|
-
}
|
|
906
|
-
const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
|
|
835
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
907
836
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
908
837
|
const spanId = generateHexId(16);
|
|
909
838
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
910
839
|
const params = args[0] || {};
|
|
911
840
|
const startTime = Date.now();
|
|
841
|
+
const captureContent2 = shouldCaptureContent();
|
|
912
842
|
try {
|
|
913
843
|
const response = await originalCreate(...args);
|
|
914
844
|
const endTime = Date.now();
|
|
915
|
-
const attributes =
|
|
845
|
+
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
916
846
|
params?.messages,
|
|
917
847
|
response?.choices?.[0]?.message,
|
|
918
848
|
response?.model || params?.model,
|
|
@@ -941,17 +871,13 @@ function wrapOpenAI(client) {
|
|
|
941
871
|
prompt_tokens: response?.usage?.prompt_tokens,
|
|
942
872
|
completion_tokens: response?.usage?.completion_tokens,
|
|
943
873
|
total_tokens: response?.usage?.total_tokens,
|
|
944
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
945
|
-
prompt_key: promptCtx?.promptKey,
|
|
946
|
-
prompt_version: promptCtx?.promptVersion,
|
|
947
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
948
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
874
|
+
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
949
875
|
}).catch(() => {
|
|
950
876
|
});
|
|
951
877
|
return response;
|
|
952
878
|
} catch (error) {
|
|
953
879
|
const endTime = Date.now();
|
|
954
|
-
const attributes =
|
|
880
|
+
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
955
881
|
params?.messages,
|
|
956
882
|
void 0,
|
|
957
883
|
params?.model,
|
|
@@ -975,11 +901,7 @@ function wrapOpenAI(client) {
|
|
|
975
901
|
duration_ms: endTime - startTime,
|
|
976
902
|
status: "ERROR",
|
|
977
903
|
error_message: error?.message,
|
|
978
|
-
attributes
|
|
979
|
-
prompt_key: promptCtx?.promptKey,
|
|
980
|
-
prompt_version: promptCtx?.promptVersion,
|
|
981
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
982
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
904
|
+
attributes
|
|
983
905
|
}).catch(() => {
|
|
984
906
|
});
|
|
985
907
|
throw error;
|
|
@@ -987,29 +909,26 @@ function wrapOpenAI(client) {
|
|
|
987
909
|
};
|
|
988
910
|
return client;
|
|
989
911
|
}
|
|
990
|
-
|
|
912
|
+
|
|
913
|
+
// src/trace/wrappers/anthropic.ts
|
|
914
|
+
function wrapAnthropic(client, sessionCtx) {
|
|
991
915
|
const originalCreate = client.messages.create.bind(client.messages);
|
|
916
|
+
const ctx = sessionCtx;
|
|
992
917
|
client.messages.create = async function(...args) {
|
|
993
|
-
|
|
994
|
-
if (!ctx || !initialized) {
|
|
918
|
+
if (!isInitialized()) {
|
|
995
919
|
return originalCreate(...args);
|
|
996
920
|
}
|
|
997
|
-
|
|
998
|
-
try {
|
|
999
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1000
|
-
promptCtx = getPromptContext();
|
|
1001
|
-
} catch {
|
|
1002
|
-
}
|
|
1003
|
-
const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
|
|
921
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1004
922
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1005
923
|
const spanId = generateHexId(16);
|
|
1006
924
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1007
925
|
const params = args[0] || {};
|
|
1008
926
|
const startTime = Date.now();
|
|
927
|
+
const captureContent2 = shouldCaptureContent();
|
|
1009
928
|
try {
|
|
1010
929
|
const response = await originalCreate(...args);
|
|
1011
930
|
const endTime = Date.now();
|
|
1012
|
-
const attributes =
|
|
931
|
+
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
1013
932
|
params?.messages,
|
|
1014
933
|
{ role: "assistant", content: response?.content?.[0]?.text || "" },
|
|
1015
934
|
response?.model || params?.model,
|
|
@@ -1041,17 +960,13 @@ function wrapAnthropic(client) {
|
|
|
1041
960
|
prompt_tokens: response?.usage?.input_tokens,
|
|
1042
961
|
completion_tokens: response?.usage?.output_tokens,
|
|
1043
962
|
total_tokens: (response?.usage?.input_tokens || 0) + (response?.usage?.output_tokens || 0),
|
|
1044
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
1045
|
-
prompt_key: promptCtx?.promptKey,
|
|
1046
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1047
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1048
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
963
|
+
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
1049
964
|
}).catch(() => {
|
|
1050
965
|
});
|
|
1051
966
|
return response;
|
|
1052
967
|
} catch (error) {
|
|
1053
968
|
const endTime = Date.now();
|
|
1054
|
-
const attributes =
|
|
969
|
+
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
1055
970
|
params?.messages,
|
|
1056
971
|
void 0,
|
|
1057
972
|
params?.model,
|
|
@@ -1078,11 +993,7 @@ function wrapAnthropic(client) {
|
|
|
1078
993
|
duration_ms: endTime - startTime,
|
|
1079
994
|
status: "ERROR",
|
|
1080
995
|
error_message: error?.message,
|
|
1081
|
-
attributes
|
|
1082
|
-
prompt_key: promptCtx?.promptKey,
|
|
1083
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1084
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1085
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
996
|
+
attributes
|
|
1086
997
|
}).catch(() => {
|
|
1087
998
|
});
|
|
1088
999
|
throw error;
|
|
@@ -1090,24 +1001,21 @@ function wrapAnthropic(client) {
|
|
|
1090
1001
|
};
|
|
1091
1002
|
return client;
|
|
1092
1003
|
}
|
|
1093
|
-
|
|
1004
|
+
|
|
1005
|
+
// src/trace/wrappers/google-ai.ts
|
|
1006
|
+
function wrapGoogleAI(model, sessionCtx) {
|
|
1094
1007
|
const originalGenerate = model.generateContent.bind(model);
|
|
1008
|
+
const ctx = sessionCtx;
|
|
1095
1009
|
model.generateContent = async function(...args) {
|
|
1096
|
-
|
|
1097
|
-
if (!ctx || !initialized) {
|
|
1010
|
+
if (!isInitialized()) {
|
|
1098
1011
|
return originalGenerate(...args);
|
|
1099
1012
|
}
|
|
1100
|
-
|
|
1101
|
-
try {
|
|
1102
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1103
|
-
promptCtx = getPromptContext();
|
|
1104
|
-
} catch {
|
|
1105
|
-
}
|
|
1106
|
-
const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
|
|
1013
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1107
1014
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1108
1015
|
const spanId = generateHexId(16);
|
|
1109
1016
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1110
1017
|
const startTime = Date.now();
|
|
1018
|
+
const captureContent2 = shouldCaptureContent();
|
|
1111
1019
|
try {
|
|
1112
1020
|
const response = await originalGenerate(...args);
|
|
1113
1021
|
const endTime = Date.now();
|
|
@@ -1115,7 +1023,7 @@ function wrapGoogleAI(model) {
|
|
|
1115
1023
|
const usage = result?.usageMetadata;
|
|
1116
1024
|
const modelName = model?.model || "gemini";
|
|
1117
1025
|
const attributes = {};
|
|
1118
|
-
if (
|
|
1026
|
+
if (captureContent2) {
|
|
1119
1027
|
attributes["gen_ai.request.model"] = modelName;
|
|
1120
1028
|
attributes["gen_ai.response.model"] = modelName;
|
|
1121
1029
|
const input = args[0];
|
|
@@ -1158,11 +1066,7 @@ function wrapGoogleAI(model) {
|
|
|
1158
1066
|
prompt_tokens: usage?.promptTokenCount,
|
|
1159
1067
|
completion_tokens: usage?.candidatesTokenCount,
|
|
1160
1068
|
total_tokens: usage?.totalTokenCount,
|
|
1161
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
1162
|
-
prompt_key: promptCtx?.promptKey,
|
|
1163
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1164
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1165
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1069
|
+
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
1166
1070
|
}).catch(() => {
|
|
1167
1071
|
});
|
|
1168
1072
|
return response;
|
|
@@ -1170,7 +1074,7 @@ function wrapGoogleAI(model) {
|
|
|
1170
1074
|
const endTime = Date.now();
|
|
1171
1075
|
const modelName = model?.model || "gemini";
|
|
1172
1076
|
const attributes = {};
|
|
1173
|
-
if (
|
|
1077
|
+
if (captureContent2) {
|
|
1174
1078
|
attributes["gen_ai.request.model"] = modelName;
|
|
1175
1079
|
attributes["error.message"] = error?.message;
|
|
1176
1080
|
const input = args[0];
|
|
@@ -1194,11 +1098,7 @@ function wrapGoogleAI(model) {
|
|
|
1194
1098
|
duration_ms: endTime - startTime,
|
|
1195
1099
|
status: "ERROR",
|
|
1196
1100
|
error_message: error?.message,
|
|
1197
|
-
attributes:
|
|
1198
|
-
prompt_key: promptCtx?.promptKey,
|
|
1199
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1200
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1201
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1101
|
+
attributes: captureContent2 ? attributes : void 0
|
|
1202
1102
|
}).catch(() => {
|
|
1203
1103
|
});
|
|
1204
1104
|
throw error;
|
|
@@ -1206,7 +1106,8 @@ function wrapGoogleAI(model) {
|
|
|
1206
1106
|
};
|
|
1207
1107
|
return model;
|
|
1208
1108
|
}
|
|
1209
|
-
|
|
1109
|
+
|
|
1110
|
+
// src/trace/wrappers/vercel-ai/utils.ts
|
|
1210
1111
|
function extractUsageFromResult(result, directUsage) {
|
|
1211
1112
|
let usage = directUsage ?? result?.usage;
|
|
1212
1113
|
const isValidNumber = (v) => v !== null && v !== void 0 && !Number.isNaN(v);
|
|
@@ -1234,38 +1135,25 @@ function extractUsageFromResult(result, directUsage) {
|
|
|
1234
1135
|
}
|
|
1235
1136
|
return { promptTokens, completionTokens, totalTokens, cost };
|
|
1236
1137
|
}
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
generateText: createGenerateTextWrapper(aiModule),
|
|
1242
|
-
streamText: createStreamTextWrapper(aiModule),
|
|
1243
|
-
generateObject: aiModule.generateObject ? createGenerateObjectWrapper(aiModule) : void 0,
|
|
1244
|
-
streamObject: aiModule.streamObject ? createStreamObjectWrapper(aiModule) : void 0
|
|
1245
|
-
};
|
|
1246
|
-
}
|
|
1247
|
-
function createGenerateTextWrapper(aiModule) {
|
|
1138
|
+
|
|
1139
|
+
// src/trace/wrappers/vercel-ai/generate-text.ts
|
|
1140
|
+
function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
1141
|
+
const ctx = sessionCtx;
|
|
1248
1142
|
return async (...args) => {
|
|
1249
|
-
|
|
1250
|
-
if (!ctx || !initialized) {
|
|
1143
|
+
if (!isInitialized()) {
|
|
1251
1144
|
return aiModule.generateText(...args);
|
|
1252
1145
|
}
|
|
1253
|
-
|
|
1254
|
-
try {
|
|
1255
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1256
|
-
promptCtx = getPromptContext();
|
|
1257
|
-
} catch {
|
|
1258
|
-
}
|
|
1259
|
-
const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
|
|
1146
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1260
1147
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1261
1148
|
const spanId = generateHexId(16);
|
|
1262
1149
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1263
1150
|
const params = args[0] || {};
|
|
1264
1151
|
const startTime = Date.now();
|
|
1152
|
+
const captureContent2 = shouldCaptureContent();
|
|
1265
1153
|
try {
|
|
1266
1154
|
const result = await aiModule.generateText(...args);
|
|
1267
1155
|
const endTime = Date.now();
|
|
1268
|
-
if (
|
|
1156
|
+
if (debug || isDebugMode()) {
|
|
1269
1157
|
console.log(
|
|
1270
1158
|
"\n\u{1F50D} [Fallom Debug] generateText result keys:",
|
|
1271
1159
|
Object.keys(result || {})
|
|
@@ -1274,14 +1162,6 @@ function createGenerateTextWrapper(aiModule) {
|
|
|
1274
1162
|
"\u{1F50D} [Fallom Debug] result.usage:",
|
|
1275
1163
|
JSON.stringify(result?.usage, null, 2)
|
|
1276
1164
|
);
|
|
1277
|
-
console.log(
|
|
1278
|
-
"\u{1F50D} [Fallom Debug] result.response keys:",
|
|
1279
|
-
Object.keys(result?.response || {})
|
|
1280
|
-
);
|
|
1281
|
-
console.log(
|
|
1282
|
-
"\u{1F50D} [Fallom Debug] result.response.usage:",
|
|
1283
|
-
JSON.stringify(result?.response?.usage, null, 2)
|
|
1284
|
-
);
|
|
1285
1165
|
console.log(
|
|
1286
1166
|
"\u{1F50D} [Fallom Debug] result.experimental_providerMetadata:",
|
|
1287
1167
|
JSON.stringify(result?.experimental_providerMetadata, null, 2)
|
|
@@ -1289,7 +1169,7 @@ function createGenerateTextWrapper(aiModule) {
|
|
|
1289
1169
|
}
|
|
1290
1170
|
const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
|
|
1291
1171
|
const attributes = {};
|
|
1292
|
-
if (
|
|
1172
|
+
if (captureContent2) {
|
|
1293
1173
|
attributes["gen_ai.request.model"] = modelId;
|
|
1294
1174
|
attributes["gen_ai.response.model"] = modelId;
|
|
1295
1175
|
if (params?.prompt) {
|
|
@@ -1339,11 +1219,7 @@ function createGenerateTextWrapper(aiModule) {
|
|
|
1339
1219
|
prompt_tokens: usage.promptTokens,
|
|
1340
1220
|
completion_tokens: usage.completionTokens,
|
|
1341
1221
|
total_tokens: usage.totalTokens,
|
|
1342
|
-
attributes:
|
|
1343
|
-
prompt_key: promptCtx?.promptKey,
|
|
1344
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1345
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1346
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1222
|
+
attributes: captureContent2 ? attributes : void 0
|
|
1347
1223
|
}).catch(() => {
|
|
1348
1224
|
});
|
|
1349
1225
|
return result;
|
|
@@ -1364,52 +1240,44 @@ function createGenerateTextWrapper(aiModule) {
|
|
|
1364
1240
|
end_time: new Date(endTime).toISOString(),
|
|
1365
1241
|
duration_ms: endTime - startTime,
|
|
1366
1242
|
status: "ERROR",
|
|
1367
|
-
error_message: error?.message
|
|
1368
|
-
prompt_key: promptCtx?.promptKey,
|
|
1369
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1370
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1371
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1243
|
+
error_message: error?.message
|
|
1372
1244
|
}).catch(() => {
|
|
1373
1245
|
});
|
|
1374
1246
|
throw error;
|
|
1375
1247
|
}
|
|
1376
1248
|
};
|
|
1377
1249
|
}
|
|
1378
|
-
|
|
1250
|
+
|
|
1251
|
+
// src/trace/wrappers/vercel-ai/stream-text.ts
|
|
1252
|
+
function log2(...args) {
|
|
1253
|
+
if (isDebugMode()) console.log("[Fallom]", ...args);
|
|
1254
|
+
}
|
|
1255
|
+
function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
1256
|
+
const ctx = sessionCtx;
|
|
1379
1257
|
return async (...args) => {
|
|
1380
|
-
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
1381
1258
|
const params = args[0] || {};
|
|
1382
1259
|
const startTime = Date.now();
|
|
1260
|
+
const captureContent2 = shouldCaptureContent();
|
|
1383
1261
|
const result = await aiModule.streamText(...args);
|
|
1384
|
-
if (!
|
|
1262
|
+
if (!isInitialized()) {
|
|
1385
1263
|
return result;
|
|
1386
1264
|
}
|
|
1387
|
-
const traceCtx =
|
|
1265
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1388
1266
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1389
1267
|
const spanId = generateHexId(16);
|
|
1390
1268
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1391
1269
|
let firstTokenTime = null;
|
|
1392
1270
|
const modelId = params?.model?.modelId || String(params?.model || "unknown");
|
|
1393
|
-
let promptCtx = null;
|
|
1394
|
-
try {
|
|
1395
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1396
|
-
promptCtx = getPromptContext();
|
|
1397
|
-
} catch {
|
|
1398
|
-
}
|
|
1399
1271
|
if (result?.usage) {
|
|
1400
1272
|
result.usage.then(async (rawUsage) => {
|
|
1401
1273
|
const endTime = Date.now();
|
|
1402
|
-
if (
|
|
1274
|
+
if (debug || isDebugMode()) {
|
|
1403
1275
|
console.log(
|
|
1404
1276
|
"\n\u{1F50D} [Fallom Debug] streamText usage:",
|
|
1405
1277
|
JSON.stringify(rawUsage, null, 2)
|
|
1406
1278
|
);
|
|
1407
|
-
console.log(
|
|
1408
|
-
"\u{1F50D} [Fallom Debug] streamText result keys:",
|
|
1409
|
-
Object.keys(result || {})
|
|
1410
|
-
);
|
|
1411
1279
|
}
|
|
1412
|
-
|
|
1280
|
+
log2("\u{1F4CA} streamText usage:", JSON.stringify(rawUsage, null, 2));
|
|
1413
1281
|
let providerMetadata = result?.experimental_providerMetadata;
|
|
1414
1282
|
if (providerMetadata && typeof providerMetadata.then === "function") {
|
|
1415
1283
|
try {
|
|
@@ -1423,7 +1291,7 @@ function createStreamTextWrapper(aiModule) {
|
|
|
1423
1291
|
rawUsage
|
|
1424
1292
|
);
|
|
1425
1293
|
const attributes = {};
|
|
1426
|
-
if (
|
|
1294
|
+
if (captureContent2) {
|
|
1427
1295
|
attributes["gen_ai.request.model"] = modelId;
|
|
1428
1296
|
if (params?.prompt) {
|
|
1429
1297
|
attributes["gen_ai.prompt.0.role"] = "user";
|
|
@@ -1457,17 +1325,13 @@ function createStreamTextWrapper(aiModule) {
|
|
|
1457
1325
|
completion_tokens: usage.completionTokens,
|
|
1458
1326
|
total_tokens: usage.totalTokens,
|
|
1459
1327
|
time_to_first_token_ms: firstTokenTime ? firstTokenTime - startTime : void 0,
|
|
1460
|
-
attributes:
|
|
1461
|
-
prompt_key: promptCtx?.promptKey,
|
|
1462
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1463
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1464
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1328
|
+
attributes: captureContent2 ? attributes : void 0
|
|
1465
1329
|
};
|
|
1466
1330
|
sendTrace(tracePayload).catch(() => {
|
|
1467
1331
|
});
|
|
1468
1332
|
}).catch((error) => {
|
|
1469
1333
|
const endTime = Date.now();
|
|
1470
|
-
|
|
1334
|
+
log2("\u274C streamText error:", error?.message);
|
|
1471
1335
|
sendTrace({
|
|
1472
1336
|
config_key: ctx.configKey,
|
|
1473
1337
|
session_id: ctx.sessionId,
|
|
@@ -1482,11 +1346,7 @@ function createStreamTextWrapper(aiModule) {
|
|
|
1482
1346
|
end_time: new Date(endTime).toISOString(),
|
|
1483
1347
|
duration_ms: endTime - startTime,
|
|
1484
1348
|
status: "ERROR",
|
|
1485
|
-
error_message: error?.message
|
|
1486
|
-
prompt_key: promptCtx?.promptKey,
|
|
1487
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1488
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1489
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1349
|
+
error_message: error?.message
|
|
1490
1350
|
}).catch(() => {
|
|
1491
1351
|
});
|
|
1492
1352
|
});
|
|
@@ -1497,7 +1357,7 @@ function createStreamTextWrapper(aiModule) {
|
|
|
1497
1357
|
for await (const chunk of originalTextStream) {
|
|
1498
1358
|
if (!firstTokenTime) {
|
|
1499
1359
|
firstTokenTime = Date.now();
|
|
1500
|
-
|
|
1360
|
+
log2("\u23F1\uFE0F Time to first token:", firstTokenTime - startTime, "ms");
|
|
1501
1361
|
}
|
|
1502
1362
|
yield chunk;
|
|
1503
1363
|
}
|
|
@@ -1514,28 +1374,25 @@ function createStreamTextWrapper(aiModule) {
|
|
|
1514
1374
|
return result;
|
|
1515
1375
|
};
|
|
1516
1376
|
}
|
|
1517
|
-
|
|
1377
|
+
|
|
1378
|
+
// src/trace/wrappers/vercel-ai/generate-object.ts
|
|
1379
|
+
function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
1380
|
+
const ctx = sessionCtx;
|
|
1518
1381
|
return async (...args) => {
|
|
1519
|
-
|
|
1520
|
-
if (!ctx || !initialized) {
|
|
1382
|
+
if (!isInitialized()) {
|
|
1521
1383
|
return aiModule.generateObject(...args);
|
|
1522
1384
|
}
|
|
1523
|
-
|
|
1524
|
-
try {
|
|
1525
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1526
|
-
promptCtx = getPromptContext();
|
|
1527
|
-
} catch {
|
|
1528
|
-
}
|
|
1529
|
-
const traceCtx = traceContextStorage.getStore() || fallbackTraceContext;
|
|
1385
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1530
1386
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1531
1387
|
const spanId = generateHexId(16);
|
|
1532
1388
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1533
1389
|
const params = args[0] || {};
|
|
1534
1390
|
const startTime = Date.now();
|
|
1391
|
+
const captureContent2 = shouldCaptureContent();
|
|
1535
1392
|
try {
|
|
1536
1393
|
const result = await aiModule.generateObject(...args);
|
|
1537
1394
|
const endTime = Date.now();
|
|
1538
|
-
if (
|
|
1395
|
+
if (debug || isDebugMode()) {
|
|
1539
1396
|
console.log(
|
|
1540
1397
|
"\n\u{1F50D} [Fallom Debug] generateObject result keys:",
|
|
1541
1398
|
Object.keys(result || {})
|
|
@@ -1544,18 +1401,10 @@ function createGenerateObjectWrapper(aiModule) {
|
|
|
1544
1401
|
"\u{1F50D} [Fallom Debug] result.usage:",
|
|
1545
1402
|
JSON.stringify(result?.usage, null, 2)
|
|
1546
1403
|
);
|
|
1547
|
-
console.log(
|
|
1548
|
-
"\u{1F50D} [Fallom Debug] result.response keys:",
|
|
1549
|
-
Object.keys(result?.response || {})
|
|
1550
|
-
);
|
|
1551
|
-
console.log(
|
|
1552
|
-
"\u{1F50D} [Fallom Debug] result.response.usage:",
|
|
1553
|
-
JSON.stringify(result?.response?.usage, null, 2)
|
|
1554
|
-
);
|
|
1555
1404
|
}
|
|
1556
1405
|
const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
|
|
1557
1406
|
const attributes = {};
|
|
1558
|
-
if (
|
|
1407
|
+
if (captureContent2) {
|
|
1559
1408
|
attributes["gen_ai.request.model"] = modelId;
|
|
1560
1409
|
attributes["gen_ai.response.model"] = modelId;
|
|
1561
1410
|
if (result?.object) {
|
|
@@ -1594,11 +1443,7 @@ function createGenerateObjectWrapper(aiModule) {
|
|
|
1594
1443
|
prompt_tokens: usage.promptTokens,
|
|
1595
1444
|
completion_tokens: usage.completionTokens,
|
|
1596
1445
|
total_tokens: usage.totalTokens,
|
|
1597
|
-
attributes:
|
|
1598
|
-
prompt_key: promptCtx?.promptKey,
|
|
1599
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1600
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1601
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1446
|
+
attributes: captureContent2 ? attributes : void 0
|
|
1602
1447
|
}).catch(() => {
|
|
1603
1448
|
});
|
|
1604
1449
|
return result;
|
|
@@ -1619,53 +1464,45 @@ function createGenerateObjectWrapper(aiModule) {
|
|
|
1619
1464
|
end_time: new Date(endTime).toISOString(),
|
|
1620
1465
|
duration_ms: endTime - startTime,
|
|
1621
1466
|
status: "ERROR",
|
|
1622
|
-
error_message: error?.message
|
|
1623
|
-
prompt_key: promptCtx?.promptKey,
|
|
1624
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1625
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1626
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1467
|
+
error_message: error?.message
|
|
1627
1468
|
}).catch(() => {
|
|
1628
1469
|
});
|
|
1629
1470
|
throw error;
|
|
1630
1471
|
}
|
|
1631
1472
|
};
|
|
1632
1473
|
}
|
|
1633
|
-
|
|
1474
|
+
|
|
1475
|
+
// src/trace/wrappers/vercel-ai/stream-object.ts
|
|
1476
|
+
function log3(...args) {
|
|
1477
|
+
if (isDebugMode()) console.log("[Fallom]", ...args);
|
|
1478
|
+
}
|
|
1479
|
+
function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
1480
|
+
const ctx = sessionCtx;
|
|
1634
1481
|
return async (...args) => {
|
|
1635
|
-
const ctx = sessionStorage.getStore() || fallbackSession;
|
|
1636
1482
|
const params = args[0] || {};
|
|
1637
1483
|
const startTime = Date.now();
|
|
1484
|
+
const captureContent2 = shouldCaptureContent();
|
|
1638
1485
|
const result = await aiModule.streamObject(...args);
|
|
1639
|
-
|
|
1640
|
-
if (!
|
|
1486
|
+
log3("\u{1F50D} streamObject result keys:", Object.keys(result || {}));
|
|
1487
|
+
if (!isInitialized()) {
|
|
1641
1488
|
return result;
|
|
1642
1489
|
}
|
|
1643
|
-
const traceCtx =
|
|
1490
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1644
1491
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1645
1492
|
const spanId = generateHexId(16);
|
|
1646
1493
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1647
1494
|
let firstTokenTime = null;
|
|
1648
1495
|
const modelId = params?.model?.modelId || String(params?.model || "unknown");
|
|
1649
|
-
let promptCtx = null;
|
|
1650
|
-
try {
|
|
1651
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1652
|
-
promptCtx = getPromptContext();
|
|
1653
|
-
} catch {
|
|
1654
|
-
}
|
|
1655
1496
|
if (result?.usage) {
|
|
1656
1497
|
result.usage.then(async (rawUsage) => {
|
|
1657
1498
|
const endTime = Date.now();
|
|
1658
|
-
if (
|
|
1499
|
+
if (debug || isDebugMode()) {
|
|
1659
1500
|
console.log(
|
|
1660
1501
|
"\n\u{1F50D} [Fallom Debug] streamObject usage:",
|
|
1661
1502
|
JSON.stringify(rawUsage, null, 2)
|
|
1662
1503
|
);
|
|
1663
|
-
console.log(
|
|
1664
|
-
"\u{1F50D} [Fallom Debug] streamObject result keys:",
|
|
1665
|
-
Object.keys(result || {})
|
|
1666
|
-
);
|
|
1667
1504
|
}
|
|
1668
|
-
|
|
1505
|
+
log3("\u{1F4CA} streamObject usage:", JSON.stringify(rawUsage, null, 2));
|
|
1669
1506
|
let providerMetadata = result?.experimental_providerMetadata;
|
|
1670
1507
|
if (providerMetadata && typeof providerMetadata.then === "function") {
|
|
1671
1508
|
try {
|
|
@@ -1679,7 +1516,7 @@ function createStreamObjectWrapper(aiModule) {
|
|
|
1679
1516
|
rawUsage
|
|
1680
1517
|
);
|
|
1681
1518
|
const attributes = {};
|
|
1682
|
-
if (
|
|
1519
|
+
if (captureContent2) {
|
|
1683
1520
|
attributes["gen_ai.request.model"] = modelId;
|
|
1684
1521
|
}
|
|
1685
1522
|
if (firstTokenTime) {
|
|
@@ -1708,11 +1545,7 @@ function createStreamObjectWrapper(aiModule) {
|
|
|
1708
1545
|
prompt_tokens: usage.promptTokens,
|
|
1709
1546
|
completion_tokens: usage.completionTokens,
|
|
1710
1547
|
total_tokens: usage.totalTokens,
|
|
1711
|
-
attributes:
|
|
1712
|
-
prompt_key: promptCtx?.promptKey,
|
|
1713
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1714
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1715
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1548
|
+
attributes: captureContent2 ? attributes : void 0
|
|
1716
1549
|
}).catch(() => {
|
|
1717
1550
|
});
|
|
1718
1551
|
}).catch((error) => {
|
|
@@ -1731,11 +1564,7 @@ function createStreamObjectWrapper(aiModule) {
|
|
|
1731
1564
|
end_time: new Date(endTime).toISOString(),
|
|
1732
1565
|
duration_ms: endTime - startTime,
|
|
1733
1566
|
status: "ERROR",
|
|
1734
|
-
error_message: error?.message
|
|
1735
|
-
prompt_key: promptCtx?.promptKey,
|
|
1736
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1737
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1738
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1567
|
+
error_message: error?.message
|
|
1739
1568
|
}).catch(() => {
|
|
1740
1569
|
});
|
|
1741
1570
|
});
|
|
@@ -1746,7 +1575,7 @@ function createStreamObjectWrapper(aiModule) {
|
|
|
1746
1575
|
for await (const chunk of originalStream) {
|
|
1747
1576
|
if (!firstTokenTime) {
|
|
1748
1577
|
firstTokenTime = Date.now();
|
|
1749
|
-
|
|
1578
|
+
log3("\u23F1\uFE0F Time to first token:", firstTokenTime - startTime, "ms");
|
|
1750
1579
|
}
|
|
1751
1580
|
yield chunk;
|
|
1752
1581
|
}
|
|
@@ -1763,20 +1592,27 @@ function createStreamObjectWrapper(aiModule) {
|
|
|
1763
1592
|
return result;
|
|
1764
1593
|
};
|
|
1765
1594
|
}
|
|
1766
|
-
|
|
1595
|
+
|
|
1596
|
+
// src/trace/wrappers/vercel-ai/index.ts
|
|
1597
|
+
function wrapAISDK(ai, sessionCtx, options) {
|
|
1598
|
+
const debug = options?.debug ?? false;
|
|
1599
|
+
return {
|
|
1600
|
+
generateText: createGenerateTextWrapper(ai, sessionCtx, debug),
|
|
1601
|
+
streamText: createStreamTextWrapper(ai, sessionCtx, debug),
|
|
1602
|
+
generateObject: ai.generateObject ? createGenerateObjectWrapper(ai, sessionCtx, debug) : void 0,
|
|
1603
|
+
streamObject: ai.streamObject ? createStreamObjectWrapper(ai, sessionCtx, debug) : void 0
|
|
1604
|
+
};
|
|
1605
|
+
}
|
|
1606
|
+
|
|
1607
|
+
// src/trace/wrappers/mastra.ts
|
|
1608
|
+
function wrapMastraAgent(agent, sessionCtx) {
|
|
1767
1609
|
const originalGenerate = agent.generate.bind(agent);
|
|
1768
1610
|
const agentName = agent.name || "MastraAgent";
|
|
1611
|
+
const ctx = sessionCtx;
|
|
1769
1612
|
agent.generate = async function(...args) {
|
|
1770
|
-
|
|
1771
|
-
if (!ctx || !initialized) {
|
|
1613
|
+
if (!isInitialized()) {
|
|
1772
1614
|
return originalGenerate(...args);
|
|
1773
1615
|
}
|
|
1774
|
-
let promptCtx = null;
|
|
1775
|
-
try {
|
|
1776
|
-
const { getPromptContext } = await import("./prompts-VAN5E3L4.mjs");
|
|
1777
|
-
promptCtx = getPromptContext();
|
|
1778
|
-
} catch {
|
|
1779
|
-
}
|
|
1780
1616
|
const traceId = generateHexId(32);
|
|
1781
1617
|
const spanId = generateHexId(16);
|
|
1782
1618
|
const startTime = Date.now();
|
|
@@ -1848,11 +1684,7 @@ function wrapMastraAgent(agent) {
|
|
|
1848
1684
|
prompt_tokens: result?.usage?.promptTokens,
|
|
1849
1685
|
completion_tokens: result?.usage?.completionTokens,
|
|
1850
1686
|
total_tokens: result?.usage?.totalTokens,
|
|
1851
|
-
attributes
|
|
1852
|
-
prompt_key: promptCtx?.promptKey,
|
|
1853
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1854
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1855
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1687
|
+
attributes
|
|
1856
1688
|
};
|
|
1857
1689
|
sendTrace(traceData).catch(() => {
|
|
1858
1690
|
});
|
|
@@ -1871,11 +1703,7 @@ function wrapMastraAgent(agent) {
|
|
|
1871
1703
|
end_time: new Date(endTime).toISOString(),
|
|
1872
1704
|
duration_ms: endTime - startTime,
|
|
1873
1705
|
status: "ERROR",
|
|
1874
|
-
error_message: error instanceof Error ? error.message : String(error)
|
|
1875
|
-
prompt_key: promptCtx?.promptKey,
|
|
1876
|
-
prompt_version: promptCtx?.promptVersion,
|
|
1877
|
-
prompt_ab_test_key: promptCtx?.abTestKey,
|
|
1878
|
-
prompt_variant_index: promptCtx?.variantIndex
|
|
1706
|
+
error_message: error instanceof Error ? error.message : String(error)
|
|
1879
1707
|
};
|
|
1880
1708
|
sendTrace(traceData).catch(() => {
|
|
1881
1709
|
});
|
|
@@ -1885,38 +1713,215 @@ function wrapMastraAgent(agent) {
|
|
|
1885
1713
|
return agent;
|
|
1886
1714
|
}
|
|
1887
1715
|
|
|
1888
|
-
// src/
|
|
1889
|
-
var
|
|
1890
|
-
|
|
1716
|
+
// src/trace/session.ts
|
|
1717
|
+
var FallomSession = class {
|
|
1718
|
+
constructor(options) {
|
|
1719
|
+
this.ctx = {
|
|
1720
|
+
configKey: options.configKey,
|
|
1721
|
+
sessionId: options.sessionId,
|
|
1722
|
+
customerId: options.customerId
|
|
1723
|
+
};
|
|
1724
|
+
}
|
|
1725
|
+
/** Get the session context. */
|
|
1726
|
+
getContext() {
|
|
1727
|
+
return { ...this.ctx };
|
|
1728
|
+
}
|
|
1729
|
+
/**
|
|
1730
|
+
* Get model assignment for this session (A/B testing).
|
|
1731
|
+
*/
|
|
1732
|
+
async getModel(configKeyOrOptions, options) {
|
|
1733
|
+
let configKey;
|
|
1734
|
+
let opts;
|
|
1735
|
+
if (typeof configKeyOrOptions === "string") {
|
|
1736
|
+
configKey = configKeyOrOptions;
|
|
1737
|
+
opts = options || {};
|
|
1738
|
+
} else {
|
|
1739
|
+
configKey = this.ctx.configKey;
|
|
1740
|
+
opts = configKeyOrOptions || {};
|
|
1741
|
+
}
|
|
1742
|
+
const { get: get2 } = await import("./models-JKMOBZUO.mjs");
|
|
1743
|
+
return get2(configKey, this.ctx.sessionId, opts);
|
|
1744
|
+
}
|
|
1745
|
+
/**
|
|
1746
|
+
* Wrap a Vercel AI SDK model to trace all calls (PostHog style).
|
|
1747
|
+
* Returns the same model type with tracing injected.
|
|
1748
|
+
*/
|
|
1749
|
+
traceModel(model) {
|
|
1750
|
+
const ctx = this.ctx;
|
|
1751
|
+
const tracedModel = Object.create(model);
|
|
1752
|
+
const m = model;
|
|
1753
|
+
if (m.doGenerate) {
|
|
1754
|
+
const originalDoGenerate = m.doGenerate.bind(model);
|
|
1755
|
+
tracedModel.doGenerate = async function(...args) {
|
|
1756
|
+
if (!isInitialized()) return originalDoGenerate(...args);
|
|
1757
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1758
|
+
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1759
|
+
const spanId = generateHexId(16);
|
|
1760
|
+
const startTime = Date.now();
|
|
1761
|
+
try {
|
|
1762
|
+
const result = await originalDoGenerate(...args);
|
|
1763
|
+
const endTime = Date.now();
|
|
1764
|
+
const modelId = model.modelId || "unknown";
|
|
1765
|
+
const usage = result?.usage || result?.rawResponse?.usage;
|
|
1766
|
+
sendTrace({
|
|
1767
|
+
config_key: ctx.configKey,
|
|
1768
|
+
session_id: ctx.sessionId,
|
|
1769
|
+
customer_id: ctx.customerId,
|
|
1770
|
+
trace_id: traceId,
|
|
1771
|
+
span_id: spanId,
|
|
1772
|
+
parent_span_id: traceCtx?.parentSpanId,
|
|
1773
|
+
name: "generateText",
|
|
1774
|
+
kind: "llm",
|
|
1775
|
+
model: modelId,
|
|
1776
|
+
start_time: new Date(startTime).toISOString(),
|
|
1777
|
+
end_time: new Date(endTime).toISOString(),
|
|
1778
|
+
duration_ms: endTime - startTime,
|
|
1779
|
+
status: "OK",
|
|
1780
|
+
prompt_tokens: usage?.promptTokens,
|
|
1781
|
+
completion_tokens: usage?.completionTokens,
|
|
1782
|
+
total_tokens: usage?.totalTokens,
|
|
1783
|
+
attributes: shouldCaptureContent() && usage ? { "fallom.raw.usage": JSON.stringify(usage) } : void 0
|
|
1784
|
+
}).catch(() => {
|
|
1785
|
+
});
|
|
1786
|
+
return result;
|
|
1787
|
+
} catch (error) {
|
|
1788
|
+
const endTime = Date.now();
|
|
1789
|
+
sendTrace({
|
|
1790
|
+
config_key: ctx.configKey,
|
|
1791
|
+
session_id: ctx.sessionId,
|
|
1792
|
+
customer_id: ctx.customerId,
|
|
1793
|
+
trace_id: traceId,
|
|
1794
|
+
span_id: spanId,
|
|
1795
|
+
parent_span_id: traceCtx?.parentSpanId,
|
|
1796
|
+
name: "generateText",
|
|
1797
|
+
kind: "llm",
|
|
1798
|
+
model: model.modelId || "unknown",
|
|
1799
|
+
start_time: new Date(startTime).toISOString(),
|
|
1800
|
+
end_time: new Date(endTime).toISOString(),
|
|
1801
|
+
duration_ms: endTime - startTime,
|
|
1802
|
+
status: "ERROR",
|
|
1803
|
+
error_message: error instanceof Error ? error.message : String(error)
|
|
1804
|
+
}).catch(() => {
|
|
1805
|
+
});
|
|
1806
|
+
throw error;
|
|
1807
|
+
}
|
|
1808
|
+
};
|
|
1809
|
+
}
|
|
1810
|
+
if (m.doStream) {
|
|
1811
|
+
const originalDoStream = m.doStream.bind(model);
|
|
1812
|
+
tracedModel.doStream = async function(...args) {
|
|
1813
|
+
if (!isInitialized()) return originalDoStream(...args);
|
|
1814
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1815
|
+
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1816
|
+
const spanId = generateHexId(16);
|
|
1817
|
+
const startTime = Date.now();
|
|
1818
|
+
const modelId = model.modelId || "unknown";
|
|
1819
|
+
try {
|
|
1820
|
+
const result = await originalDoStream(...args);
|
|
1821
|
+
sendTrace({
|
|
1822
|
+
config_key: ctx.configKey,
|
|
1823
|
+
session_id: ctx.sessionId,
|
|
1824
|
+
customer_id: ctx.customerId,
|
|
1825
|
+
trace_id: traceId,
|
|
1826
|
+
span_id: spanId,
|
|
1827
|
+
parent_span_id: traceCtx?.parentSpanId,
|
|
1828
|
+
name: "streamText",
|
|
1829
|
+
kind: "llm",
|
|
1830
|
+
model: modelId,
|
|
1831
|
+
start_time: new Date(startTime).toISOString(),
|
|
1832
|
+
end_time: new Date(Date.now()).toISOString(),
|
|
1833
|
+
duration_ms: Date.now() - startTime,
|
|
1834
|
+
status: "OK",
|
|
1835
|
+
is_streaming: true
|
|
1836
|
+
}).catch(() => {
|
|
1837
|
+
});
|
|
1838
|
+
return result;
|
|
1839
|
+
} catch (error) {
|
|
1840
|
+
sendTrace({
|
|
1841
|
+
config_key: ctx.configKey,
|
|
1842
|
+
session_id: ctx.sessionId,
|
|
1843
|
+
customer_id: ctx.customerId,
|
|
1844
|
+
trace_id: traceId,
|
|
1845
|
+
span_id: spanId,
|
|
1846
|
+
parent_span_id: traceCtx?.parentSpanId,
|
|
1847
|
+
name: "streamText",
|
|
1848
|
+
kind: "llm",
|
|
1849
|
+
model: modelId,
|
|
1850
|
+
start_time: new Date(startTime).toISOString(),
|
|
1851
|
+
end_time: new Date(Date.now()).toISOString(),
|
|
1852
|
+
duration_ms: Date.now() - startTime,
|
|
1853
|
+
status: "ERROR",
|
|
1854
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
1855
|
+
is_streaming: true
|
|
1856
|
+
}).catch(() => {
|
|
1857
|
+
});
|
|
1858
|
+
throw error;
|
|
1859
|
+
}
|
|
1860
|
+
};
|
|
1861
|
+
}
|
|
1862
|
+
return tracedModel;
|
|
1863
|
+
}
|
|
1864
|
+
/** Wrap OpenAI client. Delegates to shared wrapper. */
|
|
1865
|
+
wrapOpenAI(client) {
|
|
1866
|
+
return wrapOpenAI(client, this.ctx);
|
|
1867
|
+
}
|
|
1868
|
+
/** Wrap Anthropic client. Delegates to shared wrapper. */
|
|
1869
|
+
wrapAnthropic(client) {
|
|
1870
|
+
return wrapAnthropic(client, this.ctx);
|
|
1871
|
+
}
|
|
1872
|
+
/** Wrap Google AI model. Delegates to shared wrapper. */
|
|
1873
|
+
wrapGoogleAI(model) {
|
|
1874
|
+
return wrapGoogleAI(model, this.ctx);
|
|
1875
|
+
}
|
|
1876
|
+
/** Wrap Vercel AI SDK. Delegates to shared wrapper. */
|
|
1877
|
+
wrapAISDK(ai, options) {
|
|
1878
|
+
return wrapAISDK(ai, this.ctx, options);
|
|
1879
|
+
}
|
|
1880
|
+
/** Wrap Mastra agent. Delegates to shared wrapper. */
|
|
1881
|
+
wrapMastraAgent(agent) {
|
|
1882
|
+
return wrapMastraAgent(agent, this.ctx);
|
|
1883
|
+
}
|
|
1884
|
+
};
|
|
1885
|
+
function session(options) {
|
|
1886
|
+
return new FallomSession(options);
|
|
1887
|
+
}
|
|
1888
|
+
|
|
1889
|
+
// src/prompts.ts
|
|
1890
|
+
var prompts_exports = {};
|
|
1891
|
+
__export(prompts_exports, {
|
|
1892
|
+
clearPromptContext: () => clearPromptContext,
|
|
1891
1893
|
get: () => get,
|
|
1894
|
+
getAB: () => getAB,
|
|
1895
|
+
getPromptContext: () => getPromptContext,
|
|
1892
1896
|
init: () => init3
|
|
1893
1897
|
});
|
|
1894
1898
|
import { createHash } from "crypto";
|
|
1895
1899
|
var apiKey2 = null;
|
|
1896
|
-
var baseUrl2 = "https://
|
|
1900
|
+
var baseUrl2 = "https://prompts.fallom.com";
|
|
1897
1901
|
var initialized2 = false;
|
|
1898
1902
|
var syncInterval = null;
|
|
1899
1903
|
var debugMode2 = false;
|
|
1900
|
-
var
|
|
1904
|
+
var promptCache = /* @__PURE__ */ new Map();
|
|
1905
|
+
var promptABCache = /* @__PURE__ */ new Map();
|
|
1906
|
+
var promptContext = null;
|
|
1901
1907
|
var SYNC_TIMEOUT = 2e3;
|
|
1902
|
-
|
|
1903
|
-
function log2(msg) {
|
|
1908
|
+
function log4(msg) {
|
|
1904
1909
|
if (debugMode2) {
|
|
1905
|
-
console.log(`[Fallom] ${msg}`);
|
|
1910
|
+
console.log(`[Fallom Prompts] ${msg}`);
|
|
1906
1911
|
}
|
|
1907
1912
|
}
|
|
1908
1913
|
function init3(options = {}) {
|
|
1909
1914
|
apiKey2 = options.apiKey || process.env.FALLOM_API_KEY || null;
|
|
1910
|
-
baseUrl2 = options.baseUrl || process.env.
|
|
1915
|
+
baseUrl2 = options.baseUrl || process.env.FALLOM_PROMPTS_URL || process.env.FALLOM_BASE_URL || "https://prompts.fallom.com";
|
|
1911
1916
|
initialized2 = true;
|
|
1912
1917
|
if (!apiKey2) {
|
|
1913
1918
|
return;
|
|
1914
1919
|
}
|
|
1915
|
-
|
|
1920
|
+
fetchAll().catch(() => {
|
|
1916
1921
|
});
|
|
1917
1922
|
if (!syncInterval) {
|
|
1918
1923
|
syncInterval = setInterval(() => {
|
|
1919
|
-
|
|
1924
|
+
fetchAll().catch(() => {
|
|
1920
1925
|
});
|
|
1921
1926
|
}, 3e4);
|
|
1922
1927
|
syncInterval.unref();
|
|
@@ -1930,202 +1935,195 @@ function ensureInit() {
|
|
|
1930
1935
|
}
|
|
1931
1936
|
}
|
|
1932
1937
|
}
|
|
1933
|
-
async function
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
+
async function fetchAll() {
|
|
1939
|
+
await Promise.all([fetchPrompts(), fetchPromptABTests()]);
|
|
1940
|
+
}
|
|
1941
|
+
async function fetchPrompts(timeout = SYNC_TIMEOUT) {
|
|
1942
|
+
if (!apiKey2) return;
|
|
1938
1943
|
try {
|
|
1939
|
-
log2(`Fetching configs from ${baseUrl2}/configs`);
|
|
1940
1944
|
const controller = new AbortController();
|
|
1941
1945
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1942
|
-
const resp = await fetch(`${baseUrl2}/
|
|
1946
|
+
const resp = await fetch(`${baseUrl2}/prompts`, {
|
|
1943
1947
|
headers: { Authorization: `Bearer ${apiKey2}` },
|
|
1944
1948
|
signal: controller.signal
|
|
1945
1949
|
});
|
|
1946
1950
|
clearTimeout(timeoutId);
|
|
1947
|
-
log2(`Response status: ${resp.status}`);
|
|
1948
1951
|
if (resp.ok) {
|
|
1949
1952
|
const data = await resp.json();
|
|
1950
|
-
const
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
const key = c.key;
|
|
1954
|
-
const version = c.version || 1;
|
|
1955
|
-
log2(`Config '${key}' v${version}: ${JSON.stringify(c.variants)}`);
|
|
1956
|
-
if (!configCache.has(key)) {
|
|
1957
|
-
configCache.set(key, { versions: /* @__PURE__ */ new Map(), latest: null });
|
|
1953
|
+
for (const p of data.prompts || []) {
|
|
1954
|
+
if (!promptCache.has(p.key)) {
|
|
1955
|
+
promptCache.set(p.key, { versions: /* @__PURE__ */ new Map(), current: null });
|
|
1958
1956
|
}
|
|
1959
|
-
const cached =
|
|
1960
|
-
cached.versions.set(version,
|
|
1961
|
-
|
|
1957
|
+
const cached = promptCache.get(p.key);
|
|
1958
|
+
cached.versions.set(p.version, {
|
|
1959
|
+
systemPrompt: p.system_prompt,
|
|
1960
|
+
userTemplate: p.user_template
|
|
1961
|
+
});
|
|
1962
|
+
cached.current = p.version;
|
|
1962
1963
|
}
|
|
1963
|
-
} else {
|
|
1964
|
-
log2(`Fetch failed: ${resp.statusText}`);
|
|
1965
1964
|
}
|
|
1966
|
-
} catch
|
|
1967
|
-
log2(`Fetch exception: ${e}`);
|
|
1965
|
+
} catch {
|
|
1968
1966
|
}
|
|
1969
1967
|
}
|
|
1970
|
-
async function
|
|
1971
|
-
if (!apiKey2) return
|
|
1968
|
+
async function fetchPromptABTests(timeout = SYNC_TIMEOUT) {
|
|
1969
|
+
if (!apiKey2) return;
|
|
1972
1970
|
try {
|
|
1973
1971
|
const controller = new AbortController();
|
|
1974
1972
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
1975
|
-
const resp = await fetch(
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
signal: controller.signal
|
|
1980
|
-
}
|
|
1981
|
-
);
|
|
1973
|
+
const resp = await fetch(`${baseUrl2}/prompt-ab-tests`, {
|
|
1974
|
+
headers: { Authorization: `Bearer ${apiKey2}` },
|
|
1975
|
+
signal: controller.signal
|
|
1976
|
+
});
|
|
1982
1977
|
clearTimeout(timeoutId);
|
|
1983
1978
|
if (resp.ok) {
|
|
1984
|
-
const
|
|
1985
|
-
|
|
1986
|
-
|
|
1979
|
+
const data = await resp.json();
|
|
1980
|
+
for (const t of data.prompt_ab_tests || []) {
|
|
1981
|
+
if (!promptABCache.has(t.key)) {
|
|
1982
|
+
promptABCache.set(t.key, { versions: /* @__PURE__ */ new Map(), current: null });
|
|
1983
|
+
}
|
|
1984
|
+
const cached = promptABCache.get(t.key);
|
|
1985
|
+
cached.versions.set(t.version, { variants: t.variants });
|
|
1986
|
+
cached.current = t.version;
|
|
1987
1987
|
}
|
|
1988
|
-
configCache.get(configKey).versions.set(version, config);
|
|
1989
|
-
return config;
|
|
1990
1988
|
}
|
|
1991
1989
|
} catch {
|
|
1992
1990
|
}
|
|
1993
|
-
return null;
|
|
1994
1991
|
}
|
|
1995
|
-
|
|
1996
|
-
|
|
1992
|
+
function replaceVariables(template, variables) {
|
|
1993
|
+
if (!variables) return template;
|
|
1994
|
+
return template.replace(/\{\{(\s*\w+\s*)\}\}/g, (match, varName) => {
|
|
1995
|
+
const key = varName.trim();
|
|
1996
|
+
return key in variables ? String(variables[key]) : match;
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
function setPromptContext(ctx) {
|
|
2000
|
+
promptContext = ctx;
|
|
2001
|
+
}
|
|
2002
|
+
function getPromptContext() {
|
|
2003
|
+
const ctx = promptContext;
|
|
2004
|
+
promptContext = null;
|
|
2005
|
+
return ctx;
|
|
2006
|
+
}
|
|
2007
|
+
async function get(promptKey, options = {}) {
|
|
2008
|
+
const { variables, version, debug = false } = options;
|
|
1997
2009
|
debugMode2 = debug;
|
|
1998
2010
|
ensureInit();
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
)
|
|
2002
|
-
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2011
|
+
log4(`get() called: promptKey=${promptKey}`);
|
|
2012
|
+
let promptData = promptCache.get(promptKey);
|
|
2013
|
+
if (!promptData) {
|
|
2014
|
+
log4("Not in cache, fetching...");
|
|
2015
|
+
await fetchPrompts(SYNC_TIMEOUT);
|
|
2016
|
+
promptData = promptCache.get(promptKey);
|
|
2017
|
+
}
|
|
2018
|
+
if (!promptData) {
|
|
2019
|
+
throw new Error(
|
|
2020
|
+
`Prompt '${promptKey}' not found. Check that it exists in your Fallom dashboard.`
|
|
2006
2021
|
);
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
);
|
|
2014
|
-
}
|
|
2015
|
-
if (!configData) {
|
|
2016
|
-
log2(`Config not found, using fallback: ${fallback}`);
|
|
2017
|
-
if (fallback) {
|
|
2018
|
-
console.warn(
|
|
2019
|
-
`[Fallom WARNING] Config '${configKey}' not found, using fallback model: ${fallback}`
|
|
2020
|
-
);
|
|
2021
|
-
return returnWithTrace(configKey, sessionId, fallback, 0);
|
|
2022
|
-
}
|
|
2023
|
-
throw new Error(
|
|
2024
|
-
`Config '${configKey}' not found. Check that it exists in your Fallom dashboard.`
|
|
2025
|
-
);
|
|
2026
|
-
}
|
|
2027
|
-
let config;
|
|
2028
|
-
let targetVersion;
|
|
2029
|
-
if (version !== void 0) {
|
|
2030
|
-
config = configData.versions.get(version);
|
|
2031
|
-
if (!config) {
|
|
2032
|
-
config = await fetchSpecificVersion(configKey, version, SYNC_TIMEOUT) || void 0;
|
|
2033
|
-
}
|
|
2034
|
-
if (!config) {
|
|
2035
|
-
if (fallback) {
|
|
2036
|
-
console.warn(
|
|
2037
|
-
`[Fallom WARNING] Config '${configKey}' version ${version} not found, using fallback: ${fallback}`
|
|
2038
|
-
);
|
|
2039
|
-
return returnWithTrace(configKey, sessionId, fallback, 0);
|
|
2040
|
-
}
|
|
2041
|
-
throw new Error(`Config '${configKey}' version ${version} not found.`);
|
|
2042
|
-
}
|
|
2043
|
-
targetVersion = version;
|
|
2044
|
-
} else {
|
|
2045
|
-
targetVersion = configData.latest;
|
|
2046
|
-
config = configData.versions.get(targetVersion);
|
|
2047
|
-
if (!config) {
|
|
2048
|
-
if (fallback) {
|
|
2049
|
-
console.warn(
|
|
2050
|
-
`[Fallom WARNING] Config '${configKey}' has no cached version, using fallback: ${fallback}`
|
|
2051
|
-
);
|
|
2052
|
-
return returnWithTrace(configKey, sessionId, fallback, 0);
|
|
2053
|
-
}
|
|
2054
|
-
throw new Error(`Config '${configKey}' has no cached version.`);
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
const variantsRaw = config.variants;
|
|
2058
|
-
const configVersion = config.version || targetVersion;
|
|
2059
|
-
const variants = Array.isArray(variantsRaw) ? variantsRaw : Object.values(variantsRaw);
|
|
2060
|
-
log2(
|
|
2061
|
-
`Config found! Version: ${configVersion}, Variants: ${JSON.stringify(
|
|
2062
|
-
variants
|
|
2063
|
-
)}`
|
|
2022
|
+
}
|
|
2023
|
+
const targetVersion = version ?? promptData.current;
|
|
2024
|
+
const content = promptData.versions.get(targetVersion);
|
|
2025
|
+
if (!content) {
|
|
2026
|
+
throw new Error(
|
|
2027
|
+
`Prompt '${promptKey}' version ${targetVersion} not found.`
|
|
2064
2028
|
);
|
|
2065
|
-
const hashBytes = createHash("md5").update(sessionId).digest();
|
|
2066
|
-
const hashVal = hashBytes.readUInt32BE(0) % 1e6;
|
|
2067
|
-
log2(`Session hash: ${hashVal} (out of 1,000,000)`);
|
|
2068
|
-
let cumulative = 0;
|
|
2069
|
-
let assignedModel = variants[variants.length - 1].model;
|
|
2070
|
-
for (const v of variants) {
|
|
2071
|
-
const oldCumulative = cumulative;
|
|
2072
|
-
cumulative += v.weight * 1e4;
|
|
2073
|
-
log2(
|
|
2074
|
-
`Variant ${v.model}: weight=${v.weight}%, range=${oldCumulative}-${cumulative}, hash=${hashVal}, match=${hashVal < cumulative}`
|
|
2075
|
-
);
|
|
2076
|
-
if (hashVal < cumulative) {
|
|
2077
|
-
assignedModel = v.model;
|
|
2078
|
-
break;
|
|
2079
|
-
}
|
|
2080
|
-
}
|
|
2081
|
-
log2(`\u2705 Assigned model: ${assignedModel}`);
|
|
2082
|
-
return returnWithTrace(configKey, sessionId, assignedModel, configVersion);
|
|
2083
|
-
} catch (e) {
|
|
2084
|
-
if (e instanceof Error && e.message.includes("not found")) {
|
|
2085
|
-
throw e;
|
|
2086
|
-
}
|
|
2087
|
-
if (fallback) {
|
|
2088
|
-
console.warn(
|
|
2089
|
-
`[Fallom WARNING] Error getting model for '${configKey}': ${e}. Using fallback: ${fallback}`
|
|
2090
|
-
);
|
|
2091
|
-
return returnWithTrace(configKey, sessionId, fallback, 0);
|
|
2092
|
-
}
|
|
2093
|
-
throw e;
|
|
2094
2029
|
}
|
|
2030
|
+
const system = replaceVariables(content.systemPrompt, variables);
|
|
2031
|
+
const user = replaceVariables(content.userTemplate, variables);
|
|
2032
|
+
setPromptContext({
|
|
2033
|
+
promptKey,
|
|
2034
|
+
promptVersion: targetVersion
|
|
2035
|
+
});
|
|
2036
|
+
log4(`\u2705 Got prompt: ${promptKey} v${targetVersion}`);
|
|
2037
|
+
return {
|
|
2038
|
+
key: promptKey,
|
|
2039
|
+
version: targetVersion,
|
|
2040
|
+
system,
|
|
2041
|
+
user
|
|
2042
|
+
};
|
|
2095
2043
|
}
|
|
2096
|
-
function
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2044
|
+
async function getAB(abTestKey, sessionId, options = {}) {
|
|
2045
|
+
const { variables, debug = false } = options;
|
|
2046
|
+
debugMode2 = debug;
|
|
2047
|
+
ensureInit();
|
|
2048
|
+
log4(`getAB() called: abTestKey=${abTestKey}, sessionId=${sessionId}`);
|
|
2049
|
+
let abData = promptABCache.get(abTestKey);
|
|
2050
|
+
if (!abData) {
|
|
2051
|
+
log4("Not in cache, fetching...");
|
|
2052
|
+
await fetchPromptABTests(SYNC_TIMEOUT);
|
|
2053
|
+
abData = promptABCache.get(abTestKey);
|
|
2100
2054
|
}
|
|
2101
|
-
if (
|
|
2102
|
-
|
|
2103
|
-
|
|
2055
|
+
if (!abData) {
|
|
2056
|
+
throw new Error(
|
|
2057
|
+
`Prompt A/B test '${abTestKey}' not found. Check that it exists in your Fallom dashboard.`
|
|
2058
|
+
);
|
|
2104
2059
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
},
|
|
2118
|
-
body: JSON.stringify({
|
|
2119
|
-
config_key: configKey,
|
|
2120
|
-
config_version: version,
|
|
2121
|
-
session_id: sessionId,
|
|
2122
|
-
assigned_model: model
|
|
2123
|
-
}),
|
|
2124
|
-
signal: controller.signal
|
|
2125
|
-
});
|
|
2126
|
-
clearTimeout(timeoutId);
|
|
2127
|
-
} catch {
|
|
2060
|
+
const currentVersion = abData.current;
|
|
2061
|
+
const versionData = abData.versions.get(currentVersion);
|
|
2062
|
+
if (!versionData) {
|
|
2063
|
+
throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
|
|
2064
|
+
}
|
|
2065
|
+
const { variants } = versionData;
|
|
2066
|
+
log4(`A/B test '${abTestKey}' has ${variants?.length ?? 0} variants`);
|
|
2067
|
+
log4(`Version data: ${JSON.stringify(versionData, null, 2)}`);
|
|
2068
|
+
if (!variants || variants.length === 0) {
|
|
2069
|
+
throw new Error(
|
|
2070
|
+
`Prompt A/B test '${abTestKey}' has no variants configured.`
|
|
2071
|
+
);
|
|
2128
2072
|
}
|
|
2073
|
+
const hashBytes = createHash("md5").update(sessionId).digest();
|
|
2074
|
+
const hashVal = hashBytes.readUInt32BE(0) % 1e6;
|
|
2075
|
+
let cumulative = 0;
|
|
2076
|
+
let selectedVariant = variants[variants.length - 1];
|
|
2077
|
+
let selectedIndex = variants.length - 1;
|
|
2078
|
+
for (let i = 0; i < variants.length; i++) {
|
|
2079
|
+
cumulative += variants[i].weight * 1e4;
|
|
2080
|
+
if (hashVal < cumulative) {
|
|
2081
|
+
selectedVariant = variants[i];
|
|
2082
|
+
selectedIndex = i;
|
|
2083
|
+
break;
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
2086
|
+
const promptKey = selectedVariant.prompt_key;
|
|
2087
|
+
const promptVersion = selectedVariant.prompt_version;
|
|
2088
|
+
let promptData = promptCache.get(promptKey);
|
|
2089
|
+
if (!promptData) {
|
|
2090
|
+
await fetchPrompts(SYNC_TIMEOUT);
|
|
2091
|
+
promptData = promptCache.get(promptKey);
|
|
2092
|
+
}
|
|
2093
|
+
if (!promptData) {
|
|
2094
|
+
throw new Error(
|
|
2095
|
+
`Prompt '${promptKey}' (from A/B test '${abTestKey}') not found.`
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
2098
|
+
const targetVersion = promptVersion ?? promptData.current;
|
|
2099
|
+
const content = promptData.versions.get(targetVersion);
|
|
2100
|
+
if (!content) {
|
|
2101
|
+
throw new Error(
|
|
2102
|
+
`Prompt '${promptKey}' version ${targetVersion} not found.`
|
|
2103
|
+
);
|
|
2104
|
+
}
|
|
2105
|
+
const system = replaceVariables(content.systemPrompt, variables);
|
|
2106
|
+
const user = replaceVariables(content.userTemplate, variables);
|
|
2107
|
+
setPromptContext({
|
|
2108
|
+
promptKey,
|
|
2109
|
+
promptVersion: targetVersion,
|
|
2110
|
+
abTestKey,
|
|
2111
|
+
variantIndex: selectedIndex
|
|
2112
|
+
});
|
|
2113
|
+
log4(
|
|
2114
|
+
`\u2705 Got prompt from A/B: ${promptKey} v${targetVersion} (variant ${selectedIndex})`
|
|
2115
|
+
);
|
|
2116
|
+
return {
|
|
2117
|
+
key: promptKey,
|
|
2118
|
+
version: targetVersion,
|
|
2119
|
+
system,
|
|
2120
|
+
user,
|
|
2121
|
+
abTestKey,
|
|
2122
|
+
variantIndex: selectedIndex
|
|
2123
|
+
};
|
|
2124
|
+
}
|
|
2125
|
+
function clearPromptContext() {
|
|
2126
|
+
promptContext = null;
|
|
2129
2127
|
}
|
|
2130
2128
|
|
|
2131
2129
|
// src/init.ts
|
|
@@ -2139,11 +2137,11 @@ async function init4(options = {}) {
|
|
|
2139
2137
|
captureContent: options.captureContent,
|
|
2140
2138
|
debug: options.debug
|
|
2141
2139
|
});
|
|
2142
|
-
|
|
2140
|
+
init({
|
|
2143
2141
|
apiKey: options.apiKey,
|
|
2144
2142
|
baseUrl: configsUrl
|
|
2145
2143
|
});
|
|
2146
|
-
|
|
2144
|
+
init3({
|
|
2147
2145
|
apiKey: options.apiKey,
|
|
2148
2146
|
baseUrl: promptsUrl
|
|
2149
2147
|
});
|
|
@@ -2151,9 +2149,9 @@ async function init4(options = {}) {
|
|
|
2151
2149
|
|
|
2152
2150
|
// src/mastra.ts
|
|
2153
2151
|
import { ExportResultCode } from "@opentelemetry/core";
|
|
2154
|
-
var
|
|
2152
|
+
var promptContext2 = {};
|
|
2155
2153
|
function setMastraPrompt(promptKey, version) {
|
|
2156
|
-
|
|
2154
|
+
promptContext2 = {
|
|
2157
2155
|
promptKey,
|
|
2158
2156
|
promptVersion: version,
|
|
2159
2157
|
promptAbTestKey: void 0,
|
|
@@ -2161,7 +2159,7 @@ function setMastraPrompt(promptKey, version) {
|
|
|
2161
2159
|
};
|
|
2162
2160
|
}
|
|
2163
2161
|
function setMastraPromptAB(abTestKey, variantIndex) {
|
|
2164
|
-
|
|
2162
|
+
promptContext2 = {
|
|
2165
2163
|
promptKey: void 0,
|
|
2166
2164
|
promptVersion: void 0,
|
|
2167
2165
|
promptAbTestKey: abTestKey,
|
|
@@ -2169,7 +2167,7 @@ function setMastraPromptAB(abTestKey, variantIndex) {
|
|
|
2169
2167
|
};
|
|
2170
2168
|
}
|
|
2171
2169
|
function clearMastraPrompt() {
|
|
2172
|
-
|
|
2170
|
+
promptContext2 = {};
|
|
2173
2171
|
}
|
|
2174
2172
|
var FallomExporter = class {
|
|
2175
2173
|
constructor(options = {}) {
|
|
@@ -2177,9 +2175,13 @@ var FallomExporter = class {
|
|
|
2177
2175
|
this.apiKey = options.apiKey ?? process.env.FALLOM_API_KEY ?? "";
|
|
2178
2176
|
this.baseUrl = options.baseUrl ?? "https://traces.fallom.com";
|
|
2179
2177
|
this.debug = options.debug ?? false;
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2178
|
+
this.session = options.session;
|
|
2179
|
+
if (this.debug) {
|
|
2180
|
+
console.log("[FallomExporter] Constructor called");
|
|
2181
|
+
console.log("[FallomExporter] API key present:", !!this.apiKey);
|
|
2182
|
+
console.log("[FallomExporter] Base URL:", this.baseUrl);
|
|
2183
|
+
console.log("[FallomExporter] Session:", this.session);
|
|
2184
|
+
}
|
|
2183
2185
|
if (!this.apiKey) {
|
|
2184
2186
|
console.warn(
|
|
2185
2187
|
"[FallomExporter] No API key provided. Set FALLOM_API_KEY env var or pass apiKey option."
|
|
@@ -2201,10 +2203,10 @@ var FallomExporter = class {
|
|
|
2201
2203
|
}
|
|
2202
2204
|
this.log(`Exporting ${spans.length} spans...`);
|
|
2203
2205
|
if (this.debug) {
|
|
2204
|
-
for (const
|
|
2205
|
-
this.log(` - ${
|
|
2206
|
+
for (const span of spans) {
|
|
2207
|
+
this.log(` - ${span.name}`, {
|
|
2206
2208
|
attributes: Object.fromEntries(
|
|
2207
|
-
Object.entries(
|
|
2209
|
+
Object.entries(span.attributes).filter(
|
|
2208
2210
|
([k]) => k.startsWith("gen_ai") || k.startsWith("llm")
|
|
2209
2211
|
)
|
|
2210
2212
|
)
|
|
@@ -2240,33 +2242,32 @@ var FallomExporter = class {
|
|
|
2240
2242
|
* Send spans to Fallom's OTLP endpoint.
|
|
2241
2243
|
*/
|
|
2242
2244
|
async sendSpans(spans) {
|
|
2243
|
-
const session = getSession();
|
|
2244
2245
|
const resourceSpans = this.spansToOtlpJson(spans);
|
|
2245
2246
|
const headers = {
|
|
2246
2247
|
"Content-Type": "application/json",
|
|
2247
2248
|
Authorization: `Bearer ${this.apiKey}`
|
|
2248
2249
|
};
|
|
2249
|
-
if (session?.configKey) {
|
|
2250
|
-
headers["X-Fallom-Config-Key"] = session.configKey;
|
|
2250
|
+
if (this.session?.configKey) {
|
|
2251
|
+
headers["X-Fallom-Config-Key"] = this.session.configKey;
|
|
2251
2252
|
}
|
|
2252
|
-
if (session?.sessionId) {
|
|
2253
|
-
headers["X-Fallom-Session-Id"] = session.sessionId;
|
|
2253
|
+
if (this.session?.sessionId) {
|
|
2254
|
+
headers["X-Fallom-Session-Id"] = this.session.sessionId;
|
|
2254
2255
|
}
|
|
2255
|
-
if (session?.customerId) {
|
|
2256
|
-
headers["X-Fallom-Customer-Id"] = session.customerId;
|
|
2256
|
+
if (this.session?.customerId) {
|
|
2257
|
+
headers["X-Fallom-Customer-Id"] = this.session.customerId;
|
|
2257
2258
|
}
|
|
2258
|
-
if (
|
|
2259
|
-
headers["X-Fallom-Prompt-Key"] =
|
|
2259
|
+
if (promptContext2.promptKey) {
|
|
2260
|
+
headers["X-Fallom-Prompt-Key"] = promptContext2.promptKey;
|
|
2260
2261
|
}
|
|
2261
|
-
if (
|
|
2262
|
-
headers["X-Fallom-Prompt-Version"] = String(
|
|
2262
|
+
if (promptContext2.promptVersion !== void 0) {
|
|
2263
|
+
headers["X-Fallom-Prompt-Version"] = String(promptContext2.promptVersion);
|
|
2263
2264
|
}
|
|
2264
|
-
if (
|
|
2265
|
-
headers["X-Fallom-Prompt-AB-Test"] =
|
|
2265
|
+
if (promptContext2.promptAbTestKey) {
|
|
2266
|
+
headers["X-Fallom-Prompt-AB-Test"] = promptContext2.promptAbTestKey;
|
|
2266
2267
|
}
|
|
2267
|
-
if (
|
|
2268
|
+
if (promptContext2.promptVariantIndex !== void 0) {
|
|
2268
2269
|
headers["X-Fallom-Prompt-Variant"] = String(
|
|
2269
|
-
|
|
2270
|
+
promptContext2.promptVariantIndex
|
|
2270
2271
|
);
|
|
2271
2272
|
}
|
|
2272
2273
|
const endpoint = `${this.baseUrl}/v1/traces`;
|
|
@@ -2290,12 +2291,12 @@ var FallomExporter = class {
|
|
|
2290
2291
|
*/
|
|
2291
2292
|
spansToOtlpJson(spans) {
|
|
2292
2293
|
const resourceMap = /* @__PURE__ */ new Map();
|
|
2293
|
-
for (const
|
|
2294
|
-
const resourceKey = JSON.stringify(
|
|
2294
|
+
for (const span of spans) {
|
|
2295
|
+
const resourceKey = JSON.stringify(span.resource.attributes);
|
|
2295
2296
|
if (!resourceMap.has(resourceKey)) {
|
|
2296
2297
|
resourceMap.set(resourceKey, []);
|
|
2297
2298
|
}
|
|
2298
|
-
resourceMap.get(resourceKey).push(
|
|
2299
|
+
resourceMap.get(resourceKey).push(span);
|
|
2299
2300
|
}
|
|
2300
2301
|
const resourceSpans = [];
|
|
2301
2302
|
for (const [_resourceKey, resourceSpanList] of resourceMap) {
|
|
@@ -2310,7 +2311,7 @@ var FallomExporter = class {
|
|
|
2310
2311
|
name: firstSpan.instrumentationLibrary.name,
|
|
2311
2312
|
version: firstSpan.instrumentationLibrary.version
|
|
2312
2313
|
},
|
|
2313
|
-
spans: resourceSpanList.map((
|
|
2314
|
+
spans: resourceSpanList.map((span) => this.spanToOtlp(span))
|
|
2314
2315
|
}
|
|
2315
2316
|
]
|
|
2316
2317
|
});
|
|
@@ -2320,21 +2321,21 @@ var FallomExporter = class {
|
|
|
2320
2321
|
/**
|
|
2321
2322
|
* Convert a single span to OTLP format.
|
|
2322
2323
|
*/
|
|
2323
|
-
spanToOtlp(
|
|
2324
|
+
spanToOtlp(span) {
|
|
2324
2325
|
return {
|
|
2325
|
-
traceId:
|
|
2326
|
-
spanId:
|
|
2327
|
-
parentSpanId:
|
|
2328
|
-
name:
|
|
2329
|
-
kind:
|
|
2330
|
-
startTimeUnixNano: this.hrTimeToNanos(
|
|
2331
|
-
endTimeUnixNano: this.hrTimeToNanos(
|
|
2332
|
-
attributes: this.attributesToOtlp(
|
|
2326
|
+
traceId: span.spanContext().traceId,
|
|
2327
|
+
spanId: span.spanContext().spanId,
|
|
2328
|
+
parentSpanId: span.parentSpanId,
|
|
2329
|
+
name: span.name,
|
|
2330
|
+
kind: span.kind,
|
|
2331
|
+
startTimeUnixNano: this.hrTimeToNanos(span.startTime),
|
|
2332
|
+
endTimeUnixNano: this.hrTimeToNanos(span.endTime),
|
|
2333
|
+
attributes: this.attributesToOtlp(span.attributes),
|
|
2333
2334
|
status: {
|
|
2334
|
-
code:
|
|
2335
|
-
message:
|
|
2335
|
+
code: span.status.code,
|
|
2336
|
+
message: span.status.message
|
|
2336
2337
|
},
|
|
2337
|
-
events:
|
|
2338
|
+
events: span.events.map((event) => ({
|
|
2338
2339
|
timeUnixNano: this.hrTimeToNanos(event.time),
|
|
2339
2340
|
name: event.name,
|
|
2340
2341
|
attributes: this.attributesToOtlp(event.attributes || {})
|
|
@@ -2389,15 +2390,18 @@ var index_default = {
|
|
|
2389
2390
|
init: init4,
|
|
2390
2391
|
trace: trace_exports,
|
|
2391
2392
|
models: models_exports,
|
|
2392
|
-
prompts: prompts_exports
|
|
2393
|
+
prompts: prompts_exports,
|
|
2394
|
+
session
|
|
2393
2395
|
};
|
|
2394
2396
|
export {
|
|
2395
2397
|
FallomExporter,
|
|
2398
|
+
FallomSession,
|
|
2396
2399
|
clearMastraPrompt,
|
|
2397
2400
|
index_default as default,
|
|
2398
2401
|
init4 as init,
|
|
2399
2402
|
models_exports as models,
|
|
2400
2403
|
prompts_exports as prompts,
|
|
2404
|
+
session,
|
|
2401
2405
|
setMastraPrompt,
|
|
2402
2406
|
setMastraPromptAB,
|
|
2403
2407
|
trace_exports as trace
|