@fallom/trace 0.2.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +246 -392
- package/dist/index.mjs +229 -375
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -795,32 +795,6 @@ function generateHexId(length) {
|
|
|
795
795
|
crypto.getRandomValues(bytes);
|
|
796
796
|
return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
797
797
|
}
|
|
798
|
-
function messagesToOtelAttributes(messages, completion, model, responseId) {
|
|
799
|
-
const attrs = {};
|
|
800
|
-
if (model) {
|
|
801
|
-
attrs["gen_ai.request.model"] = model;
|
|
802
|
-
attrs["gen_ai.response.model"] = model;
|
|
803
|
-
}
|
|
804
|
-
if (responseId) {
|
|
805
|
-
attrs["gen_ai.response.id"] = responseId;
|
|
806
|
-
}
|
|
807
|
-
if (messages) {
|
|
808
|
-
messages.forEach((msg, i) => {
|
|
809
|
-
attrs[`gen_ai.prompt.${i}.role`] = msg.role;
|
|
810
|
-
attrs[`gen_ai.prompt.${i}.content`] = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
811
|
-
});
|
|
812
|
-
}
|
|
813
|
-
if (completion) {
|
|
814
|
-
attrs["gen_ai.completion.0.role"] = completion.role;
|
|
815
|
-
attrs["gen_ai.completion.0.content"] = typeof completion.content === "string" ? completion.content : JSON.stringify(completion.content);
|
|
816
|
-
if (completion.tool_calls) {
|
|
817
|
-
attrs["gen_ai.completion.0.tool_calls"] = JSON.stringify(
|
|
818
|
-
completion.tool_calls
|
|
819
|
-
);
|
|
820
|
-
}
|
|
821
|
-
}
|
|
822
|
-
return attrs;
|
|
823
|
-
}
|
|
824
798
|
|
|
825
799
|
// src/trace/wrappers/openai.ts
|
|
826
800
|
function wrapOpenAI(client, sessionCtx) {
|
|
@@ -842,18 +816,25 @@ function wrapOpenAI(client, sessionCtx) {
|
|
|
842
816
|
try {
|
|
843
817
|
const response = await originalCreate(...args);
|
|
844
818
|
const endTime = Date.now();
|
|
845
|
-
const attributes =
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
819
|
+
const attributes = {
|
|
820
|
+
"fallom.sdk_version": "2",
|
|
821
|
+
"fallom.method": "chat.completions.create"
|
|
822
|
+
};
|
|
823
|
+
if (captureContent2) {
|
|
824
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
825
|
+
messages: params?.messages,
|
|
826
|
+
model: params?.model
|
|
827
|
+
});
|
|
828
|
+
attributes["fallom.raw.response"] = JSON.stringify({
|
|
829
|
+
text: response?.choices?.[0]?.message?.content,
|
|
830
|
+
finishReason: response?.choices?.[0]?.finish_reason,
|
|
831
|
+
responseId: response?.id,
|
|
832
|
+
model: response?.model
|
|
833
|
+
});
|
|
834
|
+
}
|
|
851
835
|
if (response?.usage) {
|
|
852
836
|
attributes["fallom.raw.usage"] = JSON.stringify(response.usage);
|
|
853
837
|
}
|
|
854
|
-
if (response?.choices?.[0]?.finish_reason) {
|
|
855
|
-
attributes["gen_ai.response.finish_reason"] = response.choices[0].finish_reason;
|
|
856
|
-
}
|
|
857
838
|
sendTrace({
|
|
858
839
|
config_key: ctx.configKey,
|
|
859
840
|
session_id: ctx.sessionId,
|
|
@@ -868,24 +849,12 @@ function wrapOpenAI(client, sessionCtx) {
|
|
|
868
849
|
end_time: new Date(endTime).toISOString(),
|
|
869
850
|
duration_ms: endTime - startTime,
|
|
870
851
|
status: "OK",
|
|
871
|
-
|
|
872
|
-
completion_tokens: response?.usage?.completion_tokens,
|
|
873
|
-
total_tokens: response?.usage?.total_tokens,
|
|
874
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
852
|
+
attributes
|
|
875
853
|
}).catch(() => {
|
|
876
854
|
});
|
|
877
855
|
return response;
|
|
878
856
|
} catch (error) {
|
|
879
857
|
const endTime = Date.now();
|
|
880
|
-
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
881
|
-
params?.messages,
|
|
882
|
-
void 0,
|
|
883
|
-
params?.model,
|
|
884
|
-
void 0
|
|
885
|
-
) : void 0;
|
|
886
|
-
if (attributes) {
|
|
887
|
-
attributes["error.message"] = error?.message;
|
|
888
|
-
}
|
|
889
858
|
sendTrace({
|
|
890
859
|
config_key: ctx.configKey,
|
|
891
860
|
session_id: ctx.sessionId,
|
|
@@ -901,7 +870,10 @@ function wrapOpenAI(client, sessionCtx) {
|
|
|
901
870
|
duration_ms: endTime - startTime,
|
|
902
871
|
status: "ERROR",
|
|
903
872
|
error_message: error?.message,
|
|
904
|
-
attributes
|
|
873
|
+
attributes: {
|
|
874
|
+
"fallom.sdk_version": "2",
|
|
875
|
+
"fallom.method": "chat.completions.create"
|
|
876
|
+
}
|
|
905
877
|
}).catch(() => {
|
|
906
878
|
});
|
|
907
879
|
throw error;
|
|
@@ -928,21 +900,26 @@ function wrapAnthropic(client, sessionCtx) {
|
|
|
928
900
|
try {
|
|
929
901
|
const response = await originalCreate(...args);
|
|
930
902
|
const endTime = Date.now();
|
|
931
|
-
const attributes =
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
903
|
+
const attributes = {
|
|
904
|
+
"fallom.sdk_version": "2",
|
|
905
|
+
"fallom.method": "messages.create"
|
|
906
|
+
};
|
|
907
|
+
if (captureContent2) {
|
|
908
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
909
|
+
messages: params?.messages,
|
|
910
|
+
system: params?.system,
|
|
911
|
+
model: params?.model
|
|
912
|
+
});
|
|
913
|
+
attributes["fallom.raw.response"] = JSON.stringify({
|
|
914
|
+
text: response?.content?.[0]?.text,
|
|
915
|
+
finishReason: response?.stop_reason,
|
|
916
|
+
responseId: response?.id,
|
|
917
|
+
model: response?.model
|
|
918
|
+
});
|
|
939
919
|
}
|
|
940
920
|
if (response?.usage) {
|
|
941
921
|
attributes["fallom.raw.usage"] = JSON.stringify(response.usage);
|
|
942
922
|
}
|
|
943
|
-
if (response?.stop_reason) {
|
|
944
|
-
attributes["gen_ai.response.finish_reason"] = response.stop_reason;
|
|
945
|
-
}
|
|
946
923
|
sendTrace({
|
|
947
924
|
config_key: ctx.configKey,
|
|
948
925
|
session_id: ctx.sessionId,
|
|
@@ -957,27 +934,12 @@ function wrapAnthropic(client, sessionCtx) {
|
|
|
957
934
|
end_time: new Date(endTime).toISOString(),
|
|
958
935
|
duration_ms: endTime - startTime,
|
|
959
936
|
status: "OK",
|
|
960
|
-
|
|
961
|
-
completion_tokens: response?.usage?.output_tokens,
|
|
962
|
-
total_tokens: (response?.usage?.input_tokens || 0) + (response?.usage?.output_tokens || 0),
|
|
963
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
937
|
+
attributes
|
|
964
938
|
}).catch(() => {
|
|
965
939
|
});
|
|
966
940
|
return response;
|
|
967
941
|
} catch (error) {
|
|
968
942
|
const endTime = Date.now();
|
|
969
|
-
const attributes = captureContent2 ? messagesToOtelAttributes(
|
|
970
|
-
params?.messages,
|
|
971
|
-
void 0,
|
|
972
|
-
params?.model,
|
|
973
|
-
void 0
|
|
974
|
-
) : void 0;
|
|
975
|
-
if (attributes) {
|
|
976
|
-
attributes["error.message"] = error?.message;
|
|
977
|
-
if (params?.system) {
|
|
978
|
-
attributes["gen_ai.system_prompt"] = params.system;
|
|
979
|
-
}
|
|
980
|
-
}
|
|
981
943
|
sendTrace({
|
|
982
944
|
config_key: ctx.configKey,
|
|
983
945
|
session_id: ctx.sessionId,
|
|
@@ -993,7 +955,10 @@ function wrapAnthropic(client, sessionCtx) {
|
|
|
993
955
|
duration_ms: endTime - startTime,
|
|
994
956
|
status: "ERROR",
|
|
995
957
|
error_message: error?.message,
|
|
996
|
-
attributes
|
|
958
|
+
attributes: {
|
|
959
|
+
"fallom.sdk_version": "2",
|
|
960
|
+
"fallom.method": "messages.create"
|
|
961
|
+
}
|
|
997
962
|
}).catch(() => {
|
|
998
963
|
});
|
|
999
964
|
throw error;
|
|
@@ -1004,50 +969,36 @@ function wrapAnthropic(client, sessionCtx) {
|
|
|
1004
969
|
|
|
1005
970
|
// src/trace/wrappers/google-ai.ts
|
|
1006
971
|
function wrapGoogleAI(model, sessionCtx) {
|
|
1007
|
-
const
|
|
972
|
+
const originalGenerateContent = model.generateContent.bind(model);
|
|
1008
973
|
const ctx = sessionCtx;
|
|
1009
974
|
model.generateContent = async function(...args) {
|
|
1010
975
|
if (!isInitialized()) {
|
|
1011
|
-
return
|
|
976
|
+
return originalGenerateContent(...args);
|
|
1012
977
|
}
|
|
1013
978
|
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1014
979
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1015
980
|
const spanId = generateHexId(16);
|
|
1016
981
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
982
|
+
const request = args[0];
|
|
1017
983
|
const startTime = Date.now();
|
|
1018
984
|
const captureContent2 = shouldCaptureContent();
|
|
1019
985
|
try {
|
|
1020
|
-
const response = await
|
|
986
|
+
const response = await originalGenerateContent(...args);
|
|
1021
987
|
const endTime = Date.now();
|
|
1022
|
-
const result = response?.response;
|
|
1023
|
-
const
|
|
1024
|
-
|
|
1025
|
-
|
|
988
|
+
const result = response?.response || response;
|
|
989
|
+
const attributes = {
|
|
990
|
+
"fallom.sdk_version": "2",
|
|
991
|
+
"fallom.method": "generateContent"
|
|
992
|
+
};
|
|
1026
993
|
if (captureContent2) {
|
|
1027
|
-
attributes["
|
|
1028
|
-
attributes["
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
attributes["gen_ai.prompt.0.content"] = input;
|
|
1033
|
-
} else if (input?.contents) {
|
|
1034
|
-
input.contents.forEach((content, i) => {
|
|
1035
|
-
attributes[`gen_ai.prompt.${i}.role`] = content.role || "user";
|
|
1036
|
-
attributes[`gen_ai.prompt.${i}.content`] = content.parts?.[0]?.text || JSON.stringify(content.parts);
|
|
1037
|
-
});
|
|
1038
|
-
}
|
|
1039
|
-
const outputText = result?.text?.();
|
|
1040
|
-
if (outputText) {
|
|
1041
|
-
attributes["gen_ai.completion.0.role"] = "assistant";
|
|
1042
|
-
attributes["gen_ai.completion.0.content"] = outputText;
|
|
1043
|
-
}
|
|
1044
|
-
}
|
|
1045
|
-
if (usage) {
|
|
1046
|
-
attributes["fallom.raw.usage"] = JSON.stringify(usage);
|
|
994
|
+
attributes["fallom.raw.request"] = JSON.stringify(request);
|
|
995
|
+
attributes["fallom.raw.response"] = JSON.stringify({
|
|
996
|
+
text: result?.text?.(),
|
|
997
|
+
candidates: result?.candidates
|
|
998
|
+
});
|
|
1047
999
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
attributes["gen_ai.response.finish_reason"] = candidate.finishReason;
|
|
1000
|
+
if (result?.usageMetadata) {
|
|
1001
|
+
attributes["fallom.raw.usage"] = JSON.stringify(result.usageMetadata);
|
|
1051
1002
|
}
|
|
1052
1003
|
sendTrace({
|
|
1053
1004
|
config_key: ctx.configKey,
|
|
@@ -1058,31 +1009,17 @@ function wrapGoogleAI(model, sessionCtx) {
|
|
|
1058
1009
|
parent_span_id: parentSpanId,
|
|
1059
1010
|
name: "generateContent",
|
|
1060
1011
|
kind: "llm",
|
|
1061
|
-
model:
|
|
1012
|
+
model: model.model || "gemini",
|
|
1062
1013
|
start_time: new Date(startTime).toISOString(),
|
|
1063
1014
|
end_time: new Date(endTime).toISOString(),
|
|
1064
1015
|
duration_ms: endTime - startTime,
|
|
1065
1016
|
status: "OK",
|
|
1066
|
-
|
|
1067
|
-
completion_tokens: usage?.candidatesTokenCount,
|
|
1068
|
-
total_tokens: usage?.totalTokenCount,
|
|
1069
|
-
attributes: Object.keys(attributes).length > 0 ? attributes : void 0
|
|
1017
|
+
attributes
|
|
1070
1018
|
}).catch(() => {
|
|
1071
1019
|
});
|
|
1072
1020
|
return response;
|
|
1073
1021
|
} catch (error) {
|
|
1074
1022
|
const endTime = Date.now();
|
|
1075
|
-
const modelName = model?.model || "gemini";
|
|
1076
|
-
const attributes = {};
|
|
1077
|
-
if (captureContent2) {
|
|
1078
|
-
attributes["gen_ai.request.model"] = modelName;
|
|
1079
|
-
attributes["error.message"] = error?.message;
|
|
1080
|
-
const input = args[0];
|
|
1081
|
-
if (typeof input === "string") {
|
|
1082
|
-
attributes["gen_ai.prompt.0.role"] = "user";
|
|
1083
|
-
attributes["gen_ai.prompt.0.content"] = input;
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
1023
|
sendTrace({
|
|
1087
1024
|
config_key: ctx.configKey,
|
|
1088
1025
|
session_id: ctx.sessionId,
|
|
@@ -1092,13 +1029,16 @@ function wrapGoogleAI(model, sessionCtx) {
|
|
|
1092
1029
|
parent_span_id: parentSpanId,
|
|
1093
1030
|
name: "generateContent",
|
|
1094
1031
|
kind: "llm",
|
|
1095
|
-
model:
|
|
1032
|
+
model: model.model || "gemini",
|
|
1096
1033
|
start_time: new Date(startTime).toISOString(),
|
|
1097
1034
|
end_time: new Date(endTime).toISOString(),
|
|
1098
1035
|
duration_ms: endTime - startTime,
|
|
1099
1036
|
status: "ERROR",
|
|
1100
1037
|
error_message: error?.message,
|
|
1101
|
-
attributes:
|
|
1038
|
+
attributes: {
|
|
1039
|
+
"fallom.sdk_version": "2",
|
|
1040
|
+
"fallom.method": "generateContent"
|
|
1041
|
+
}
|
|
1102
1042
|
}).catch(() => {
|
|
1103
1043
|
});
|
|
1104
1044
|
throw error;
|
|
@@ -1107,35 +1047,6 @@ function wrapGoogleAI(model, sessionCtx) {
|
|
|
1107
1047
|
return model;
|
|
1108
1048
|
}
|
|
1109
1049
|
|
|
1110
|
-
// src/trace/wrappers/vercel-ai/utils.ts
|
|
1111
|
-
function extractUsageFromResult(result, directUsage) {
|
|
1112
|
-
let usage = directUsage ?? result?.usage;
|
|
1113
|
-
const isValidNumber = (v) => v !== null && v !== void 0 && !Number.isNaN(v);
|
|
1114
|
-
let promptTokens = isValidNumber(usage?.promptTokens) ? usage.promptTokens : void 0;
|
|
1115
|
-
let completionTokens = isValidNumber(usage?.completionTokens) ? usage.completionTokens : void 0;
|
|
1116
|
-
let totalTokens = isValidNumber(usage?.totalTokens) ? usage.totalTokens : void 0;
|
|
1117
|
-
let cost;
|
|
1118
|
-
const orUsage = result?.experimental_providerMetadata?.openrouter?.usage;
|
|
1119
|
-
if (orUsage) {
|
|
1120
|
-
if (promptTokens === void 0 && isValidNumber(orUsage.promptTokens)) {
|
|
1121
|
-
promptTokens = orUsage.promptTokens;
|
|
1122
|
-
}
|
|
1123
|
-
if (completionTokens === void 0 && isValidNumber(orUsage.completionTokens)) {
|
|
1124
|
-
completionTokens = orUsage.completionTokens;
|
|
1125
|
-
}
|
|
1126
|
-
if (totalTokens === void 0 && isValidNumber(orUsage.totalTokens)) {
|
|
1127
|
-
totalTokens = orUsage.totalTokens;
|
|
1128
|
-
}
|
|
1129
|
-
if (isValidNumber(orUsage.cost)) {
|
|
1130
|
-
cost = orUsage.cost;
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
if (totalTokens === void 0 && (promptTokens !== void 0 || completionTokens !== void 0)) {
|
|
1134
|
-
totalTokens = (promptTokens ?? 0) + (completionTokens ?? 0);
|
|
1135
|
-
}
|
|
1136
|
-
return { promptTokens, completionTokens, totalTokens, cost };
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
1050
|
// src/trace/wrappers/vercel-ai/generate-text.ts
|
|
1140
1051
|
function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
1141
1052
|
const ctx = sessionCtx;
|
|
@@ -1154,54 +1065,33 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1154
1065
|
const result = await aiModule.generateText(...args);
|
|
1155
1066
|
const endTime = Date.now();
|
|
1156
1067
|
if (debug || isDebugMode()) {
|
|
1157
|
-
console.log(
|
|
1158
|
-
"\n\u{1F50D} [Fallom Debug] generateText result keys:",
|
|
1159
|
-
Object.keys(result || {})
|
|
1160
|
-
);
|
|
1161
|
-
console.log(
|
|
1162
|
-
"\u{1F50D} [Fallom Debug] result.usage:",
|
|
1163
|
-
JSON.stringify(result?.usage, null, 2)
|
|
1164
|
-
);
|
|
1165
|
-
console.log(
|
|
1166
|
-
"\u{1F50D} [Fallom Debug] result.experimental_providerMetadata:",
|
|
1167
|
-
JSON.stringify(result?.experimental_providerMetadata, null, 2)
|
|
1168
|
-
);
|
|
1068
|
+
console.log("\n\u{1F50D} [Fallom Debug] generateText raw result:", JSON.stringify(result, null, 2));
|
|
1169
1069
|
}
|
|
1170
1070
|
const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
|
|
1171
|
-
const attributes = {
|
|
1071
|
+
const attributes = {
|
|
1072
|
+
"fallom.sdk_version": "2",
|
|
1073
|
+
"fallom.method": "generateText"
|
|
1074
|
+
};
|
|
1172
1075
|
if (captureContent2) {
|
|
1173
|
-
attributes["
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
}
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
}
|
|
1185
|
-
if (result?.text) {
|
|
1186
|
-
attributes["gen_ai.completion.0.role"] = "assistant";
|
|
1187
|
-
attributes["gen_ai.completion.0.content"] = result.text;
|
|
1188
|
-
}
|
|
1189
|
-
if (result?.response?.id) {
|
|
1190
|
-
attributes["gen_ai.response.id"] = result.response.id;
|
|
1191
|
-
}
|
|
1076
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
1077
|
+
prompt: params?.prompt,
|
|
1078
|
+
messages: params?.messages,
|
|
1079
|
+
system: params?.system,
|
|
1080
|
+
model: modelId
|
|
1081
|
+
});
|
|
1082
|
+
attributes["fallom.raw.response"] = JSON.stringify({
|
|
1083
|
+
text: result?.text,
|
|
1084
|
+
finishReason: result?.finishReason,
|
|
1085
|
+
responseId: result?.response?.id,
|
|
1086
|
+
modelId: result?.response?.modelId
|
|
1087
|
+
});
|
|
1192
1088
|
}
|
|
1193
1089
|
if (result?.usage) {
|
|
1194
1090
|
attributes["fallom.raw.usage"] = JSON.stringify(result.usage);
|
|
1195
1091
|
}
|
|
1196
1092
|
if (result?.experimental_providerMetadata) {
|
|
1197
|
-
attributes["fallom.raw.providerMetadata"] = JSON.stringify(
|
|
1198
|
-
result.experimental_providerMetadata
|
|
1199
|
-
);
|
|
1093
|
+
attributes["fallom.raw.providerMetadata"] = JSON.stringify(result.experimental_providerMetadata);
|
|
1200
1094
|
}
|
|
1201
|
-
if (result?.finishReason) {
|
|
1202
|
-
attributes["gen_ai.response.finish_reason"] = result.finishReason;
|
|
1203
|
-
}
|
|
1204
|
-
const usage = extractUsageFromResult(result);
|
|
1205
1095
|
sendTrace({
|
|
1206
1096
|
config_key: ctx.configKey,
|
|
1207
1097
|
session_id: ctx.sessionId,
|
|
@@ -1216,10 +1106,7 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1216
1106
|
end_time: new Date(endTime).toISOString(),
|
|
1217
1107
|
duration_ms: endTime - startTime,
|
|
1218
1108
|
status: "OK",
|
|
1219
|
-
|
|
1220
|
-
completion_tokens: usage.completionTokens,
|
|
1221
|
-
total_tokens: usage.totalTokens,
|
|
1222
|
-
attributes: captureContent2 ? attributes : void 0
|
|
1109
|
+
attributes
|
|
1223
1110
|
}).catch(() => {
|
|
1224
1111
|
});
|
|
1225
1112
|
return result;
|
|
@@ -1240,7 +1127,17 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1240
1127
|
end_time: new Date(endTime).toISOString(),
|
|
1241
1128
|
duration_ms: endTime - startTime,
|
|
1242
1129
|
status: "ERROR",
|
|
1243
|
-
error_message: error?.message
|
|
1130
|
+
error_message: error?.message,
|
|
1131
|
+
attributes: {
|
|
1132
|
+
"fallom.sdk_version": "2",
|
|
1133
|
+
"fallom.method": "generateText",
|
|
1134
|
+
"fallom.raw.request": JSON.stringify({
|
|
1135
|
+
prompt: params?.prompt,
|
|
1136
|
+
messages: params?.messages,
|
|
1137
|
+
system: params?.system,
|
|
1138
|
+
model: modelId
|
|
1139
|
+
})
|
|
1140
|
+
}
|
|
1244
1141
|
}).catch(() => {
|
|
1245
1142
|
});
|
|
1246
1143
|
throw error;
|
|
@@ -1272,12 +1169,8 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1272
1169
|
result.usage.then(async (rawUsage) => {
|
|
1273
1170
|
const endTime = Date.now();
|
|
1274
1171
|
if (debug || isDebugMode()) {
|
|
1275
|
-
console.log(
|
|
1276
|
-
"\n\u{1F50D} [Fallom Debug] streamText usage:",
|
|
1277
|
-
JSON.stringify(rawUsage, null, 2)
|
|
1278
|
-
);
|
|
1172
|
+
console.log("\n\u{1F50D} [Fallom Debug] streamText raw usage:", JSON.stringify(rawUsage, null, 2));
|
|
1279
1173
|
}
|
|
1280
|
-
log2("\u{1F4CA} streamText usage:", JSON.stringify(rawUsage, null, 2));
|
|
1281
1174
|
let providerMetadata = result?.experimental_providerMetadata;
|
|
1282
1175
|
if (providerMetadata && typeof providerMetadata.then === "function") {
|
|
1283
1176
|
try {
|
|
@@ -1286,20 +1179,18 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1286
1179
|
providerMetadata = void 0;
|
|
1287
1180
|
}
|
|
1288
1181
|
}
|
|
1289
|
-
const
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1182
|
+
const attributes = {
|
|
1183
|
+
"fallom.sdk_version": "2",
|
|
1184
|
+
"fallom.method": "streamText",
|
|
1185
|
+
"fallom.is_streaming": true
|
|
1186
|
+
};
|
|
1294
1187
|
if (captureContent2) {
|
|
1295
|
-
attributes["
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
if (firstTokenTime) {
|
|
1302
|
-
attributes["gen_ai.time_to_first_token_ms"] = firstTokenTime - startTime;
|
|
1188
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
1189
|
+
prompt: params?.prompt,
|
|
1190
|
+
messages: params?.messages,
|
|
1191
|
+
system: params?.system,
|
|
1192
|
+
model: modelId
|
|
1193
|
+
});
|
|
1303
1194
|
}
|
|
1304
1195
|
if (rawUsage) {
|
|
1305
1196
|
attributes["fallom.raw.usage"] = JSON.stringify(rawUsage);
|
|
@@ -1307,7 +1198,10 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1307
1198
|
if (providerMetadata) {
|
|
1308
1199
|
attributes["fallom.raw.providerMetadata"] = JSON.stringify(providerMetadata);
|
|
1309
1200
|
}
|
|
1310
|
-
|
|
1201
|
+
if (firstTokenTime) {
|
|
1202
|
+
attributes["fallom.time_to_first_token_ms"] = firstTokenTime - startTime;
|
|
1203
|
+
}
|
|
1204
|
+
sendTrace({
|
|
1311
1205
|
config_key: ctx.configKey,
|
|
1312
1206
|
session_id: ctx.sessionId,
|
|
1313
1207
|
customer_id: ctx.customerId,
|
|
@@ -1321,13 +1215,10 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1321
1215
|
end_time: new Date(endTime).toISOString(),
|
|
1322
1216
|
duration_ms: endTime - startTime,
|
|
1323
1217
|
status: "OK",
|
|
1324
|
-
prompt_tokens: usage.promptTokens,
|
|
1325
|
-
completion_tokens: usage.completionTokens,
|
|
1326
|
-
total_tokens: usage.totalTokens,
|
|
1327
1218
|
time_to_first_token_ms: firstTokenTime ? firstTokenTime - startTime : void 0,
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1219
|
+
is_streaming: true,
|
|
1220
|
+
attributes
|
|
1221
|
+
}).catch(() => {
|
|
1331
1222
|
});
|
|
1332
1223
|
}).catch((error) => {
|
|
1333
1224
|
const endTime = Date.now();
|
|
@@ -1346,7 +1237,12 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1346
1237
|
end_time: new Date(endTime).toISOString(),
|
|
1347
1238
|
duration_ms: endTime - startTime,
|
|
1348
1239
|
status: "ERROR",
|
|
1349
|
-
error_message: error?.message
|
|
1240
|
+
error_message: error?.message,
|
|
1241
|
+
attributes: {
|
|
1242
|
+
"fallom.sdk_version": "2",
|
|
1243
|
+
"fallom.method": "streamText",
|
|
1244
|
+
"fallom.is_streaming": true
|
|
1245
|
+
}
|
|
1350
1246
|
}).catch(() => {
|
|
1351
1247
|
});
|
|
1352
1248
|
});
|
|
@@ -1394,25 +1290,30 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1394
1290
|
const endTime = Date.now();
|
|
1395
1291
|
if (debug || isDebugMode()) {
|
|
1396
1292
|
console.log(
|
|
1397
|
-
"\n\u{1F50D} [Fallom Debug] generateObject result
|
|
1398
|
-
|
|
1399
|
-
);
|
|
1400
|
-
console.log(
|
|
1401
|
-
"\u{1F50D} [Fallom Debug] result.usage:",
|
|
1402
|
-
JSON.stringify(result?.usage, null, 2)
|
|
1293
|
+
"\n\u{1F50D} [Fallom Debug] generateObject raw result:",
|
|
1294
|
+
JSON.stringify(result, null, 2)
|
|
1403
1295
|
);
|
|
1404
1296
|
}
|
|
1405
1297
|
const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
|
|
1406
|
-
const attributes = {
|
|
1298
|
+
const attributes = {
|
|
1299
|
+
"fallom.sdk_version": "2",
|
|
1300
|
+
"fallom.method": "generateObject"
|
|
1301
|
+
};
|
|
1407
1302
|
if (captureContent2) {
|
|
1408
|
-
attributes["
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1303
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
1304
|
+
prompt: params?.prompt,
|
|
1305
|
+
messages: params?.messages,
|
|
1306
|
+
system: params?.system,
|
|
1307
|
+
model: modelId,
|
|
1308
|
+
schema: params?.schema ? "provided" : void 0
|
|
1309
|
+
// Don't send full schema, just note if present
|
|
1310
|
+
});
|
|
1311
|
+
attributes["fallom.raw.response"] = JSON.stringify({
|
|
1312
|
+
object: result?.object,
|
|
1313
|
+
finishReason: result?.finishReason,
|
|
1314
|
+
responseId: result?.response?.id,
|
|
1315
|
+
modelId: result?.response?.modelId
|
|
1316
|
+
});
|
|
1416
1317
|
}
|
|
1417
1318
|
if (result?.usage) {
|
|
1418
1319
|
attributes["fallom.raw.usage"] = JSON.stringify(result.usage);
|
|
@@ -1422,10 +1323,6 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1422
1323
|
result.experimental_providerMetadata
|
|
1423
1324
|
);
|
|
1424
1325
|
}
|
|
1425
|
-
if (result?.finishReason) {
|
|
1426
|
-
attributes["gen_ai.response.finish_reason"] = result.finishReason;
|
|
1427
|
-
}
|
|
1428
|
-
const usage = extractUsageFromResult(result);
|
|
1429
1326
|
sendTrace({
|
|
1430
1327
|
config_key: ctx.configKey,
|
|
1431
1328
|
session_id: ctx.sessionId,
|
|
@@ -1440,10 +1337,7 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1440
1337
|
end_time: new Date(endTime).toISOString(),
|
|
1441
1338
|
duration_ms: endTime - startTime,
|
|
1442
1339
|
status: "OK",
|
|
1443
|
-
|
|
1444
|
-
completion_tokens: usage.completionTokens,
|
|
1445
|
-
total_tokens: usage.totalTokens,
|
|
1446
|
-
attributes: captureContent2 ? attributes : void 0
|
|
1340
|
+
attributes
|
|
1447
1341
|
}).catch(() => {
|
|
1448
1342
|
});
|
|
1449
1343
|
return result;
|
|
@@ -1464,7 +1358,11 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1464
1358
|
end_time: new Date(endTime).toISOString(),
|
|
1465
1359
|
duration_ms: endTime - startTime,
|
|
1466
1360
|
status: "ERROR",
|
|
1467
|
-
error_message: error?.message
|
|
1361
|
+
error_message: error?.message,
|
|
1362
|
+
attributes: {
|
|
1363
|
+
"fallom.sdk_version": "2",
|
|
1364
|
+
"fallom.method": "generateObject"
|
|
1365
|
+
}
|
|
1468
1366
|
}).catch(() => {
|
|
1469
1367
|
});
|
|
1470
1368
|
throw error;
|
|
@@ -1473,9 +1371,6 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1473
1371
|
}
|
|
1474
1372
|
|
|
1475
1373
|
// src/trace/wrappers/vercel-ai/stream-object.ts
|
|
1476
|
-
function log3(...args) {
|
|
1477
|
-
if (isDebugMode()) console.log("[Fallom]", ...args);
|
|
1478
|
-
}
|
|
1479
1374
|
function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
1480
1375
|
const ctx = sessionCtx;
|
|
1481
1376
|
return async (...args) => {
|
|
@@ -1483,7 +1378,6 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1483
1378
|
const startTime = Date.now();
|
|
1484
1379
|
const captureContent2 = shouldCaptureContent();
|
|
1485
1380
|
const result = await aiModule.streamObject(...args);
|
|
1486
|
-
log3("\u{1F50D} streamObject result keys:", Object.keys(result || {}));
|
|
1487
1381
|
if (!isInitialized()) {
|
|
1488
1382
|
return result;
|
|
1489
1383
|
}
|
|
@@ -1491,18 +1385,13 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1491
1385
|
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1492
1386
|
const spanId = generateHexId(16);
|
|
1493
1387
|
const parentSpanId = traceCtx?.parentSpanId;
|
|
1494
|
-
let firstTokenTime = null;
|
|
1495
1388
|
const modelId = params?.model?.modelId || String(params?.model || "unknown");
|
|
1496
1389
|
if (result?.usage) {
|
|
1497
1390
|
result.usage.then(async (rawUsage) => {
|
|
1498
1391
|
const endTime = Date.now();
|
|
1499
1392
|
if (debug || isDebugMode()) {
|
|
1500
|
-
console.log(
|
|
1501
|
-
"\n\u{1F50D} [Fallom Debug] streamObject usage:",
|
|
1502
|
-
JSON.stringify(rawUsage, null, 2)
|
|
1503
|
-
);
|
|
1393
|
+
console.log("\n\u{1F50D} [Fallom Debug] streamObject raw usage:", JSON.stringify(rawUsage, null, 2));
|
|
1504
1394
|
}
|
|
1505
|
-
log3("\u{1F4CA} streamObject usage:", JSON.stringify(rawUsage, null, 2));
|
|
1506
1395
|
let providerMetadata = result?.experimental_providerMetadata;
|
|
1507
1396
|
if (providerMetadata && typeof providerMetadata.then === "function") {
|
|
1508
1397
|
try {
|
|
@@ -1511,16 +1400,19 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1511
1400
|
providerMetadata = void 0;
|
|
1512
1401
|
}
|
|
1513
1402
|
}
|
|
1514
|
-
const
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1403
|
+
const attributes = {
|
|
1404
|
+
"fallom.sdk_version": "2",
|
|
1405
|
+
"fallom.method": "streamObject",
|
|
1406
|
+
"fallom.is_streaming": true
|
|
1407
|
+
};
|
|
1519
1408
|
if (captureContent2) {
|
|
1520
|
-
attributes["
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1409
|
+
attributes["fallom.raw.request"] = JSON.stringify({
|
|
1410
|
+
prompt: params?.prompt,
|
|
1411
|
+
messages: params?.messages,
|
|
1412
|
+
system: params?.system,
|
|
1413
|
+
model: modelId,
|
|
1414
|
+
schema: params?.schema ? "provided" : void 0
|
|
1415
|
+
});
|
|
1524
1416
|
}
|
|
1525
1417
|
if (rawUsage) {
|
|
1526
1418
|
attributes["fallom.raw.usage"] = JSON.stringify(rawUsage);
|
|
@@ -1542,10 +1434,8 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1542
1434
|
end_time: new Date(endTime).toISOString(),
|
|
1543
1435
|
duration_ms: endTime - startTime,
|
|
1544
1436
|
status: "OK",
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
total_tokens: usage.totalTokens,
|
|
1548
|
-
attributes: captureContent2 ? attributes : void 0
|
|
1437
|
+
is_streaming: true,
|
|
1438
|
+
attributes
|
|
1549
1439
|
}).catch(() => {
|
|
1550
1440
|
});
|
|
1551
1441
|
}).catch((error) => {
|
|
@@ -1564,31 +1454,16 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
|
|
|
1564
1454
|
end_time: new Date(endTime).toISOString(),
|
|
1565
1455
|
duration_ms: endTime - startTime,
|
|
1566
1456
|
status: "ERROR",
|
|
1567
|
-
error_message: error?.message
|
|
1457
|
+
error_message: error?.message,
|
|
1458
|
+
attributes: {
|
|
1459
|
+
"fallom.sdk_version": "2",
|
|
1460
|
+
"fallom.method": "streamObject",
|
|
1461
|
+
"fallom.is_streaming": true
|
|
1462
|
+
}
|
|
1568
1463
|
}).catch(() => {
|
|
1569
1464
|
});
|
|
1570
1465
|
});
|
|
1571
1466
|
}
|
|
1572
|
-
if (result?.partialObjectStream) {
|
|
1573
|
-
const originalStream = result.partialObjectStream;
|
|
1574
|
-
const wrappedStream = (async function* () {
|
|
1575
|
-
for await (const chunk of originalStream) {
|
|
1576
|
-
if (!firstTokenTime) {
|
|
1577
|
-
firstTokenTime = Date.now();
|
|
1578
|
-
log3("\u23F1\uFE0F Time to first token:", firstTokenTime - startTime, "ms");
|
|
1579
|
-
}
|
|
1580
|
-
yield chunk;
|
|
1581
|
-
}
|
|
1582
|
-
})();
|
|
1583
|
-
return new Proxy(result, {
|
|
1584
|
-
get(target, prop) {
|
|
1585
|
-
if (prop === "partialObjectStream") {
|
|
1586
|
-
return wrappedStream;
|
|
1587
|
-
}
|
|
1588
|
-
return target[prop];
|
|
1589
|
-
}
|
|
1590
|
-
});
|
|
1591
|
-
}
|
|
1592
1467
|
return result;
|
|
1593
1468
|
};
|
|
1594
1469
|
}
|
|
@@ -1607,105 +1482,69 @@ function wrapAISDK(ai, sessionCtx, options) {
|
|
|
1607
1482
|
// src/trace/wrappers/mastra.ts
|
|
1608
1483
|
function wrapMastraAgent(agent, sessionCtx) {
|
|
1609
1484
|
const originalGenerate = agent.generate.bind(agent);
|
|
1610
|
-
const agentName = agent.name || "MastraAgent";
|
|
1611
1485
|
const ctx = sessionCtx;
|
|
1612
1486
|
agent.generate = async function(...args) {
|
|
1613
1487
|
if (!isInitialized()) {
|
|
1614
1488
|
return originalGenerate(...args);
|
|
1615
1489
|
}
|
|
1616
|
-
const
|
|
1490
|
+
const traceCtx = getTraceContextStorage().getStore() || getFallbackTraceContext();
|
|
1491
|
+
const traceId = traceCtx?.traceId || generateHexId(32);
|
|
1617
1492
|
const spanId = generateHexId(16);
|
|
1493
|
+
const parentSpanId = traceCtx?.parentSpanId;
|
|
1494
|
+
const input = args[0];
|
|
1618
1495
|
const startTime = Date.now();
|
|
1619
|
-
const
|
|
1496
|
+
const captureContent2 = shouldCaptureContent();
|
|
1620
1497
|
try {
|
|
1621
1498
|
const result = await originalGenerate(...args);
|
|
1622
1499
|
const endTime = Date.now();
|
|
1623
|
-
const model = result?.model?.modelId || "unknown";
|
|
1624
|
-
const toolCalls = [];
|
|
1625
|
-
if (result?.steps?.length) {
|
|
1626
|
-
for (const step of result.steps) {
|
|
1627
|
-
if (step.toolCalls?.length) {
|
|
1628
|
-
for (let i = 0; i < step.toolCalls.length; i++) {
|
|
1629
|
-
const tc = step.toolCalls[i];
|
|
1630
|
-
const tr = step.toolResults?.[i];
|
|
1631
|
-
toolCalls.push({
|
|
1632
|
-
name: tc.toolName,
|
|
1633
|
-
arguments: tc.args,
|
|
1634
|
-
result: tr?.result
|
|
1635
|
-
});
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
}
|
|
1640
1500
|
const attributes = {
|
|
1641
|
-
"
|
|
1642
|
-
"
|
|
1643
|
-
"
|
|
1644
|
-
"fallom.source": "mastra-agent",
|
|
1645
|
-
"llm.request.type": "chat"
|
|
1501
|
+
"fallom.sdk_version": "2",
|
|
1502
|
+
"fallom.method": "agent.generate",
|
|
1503
|
+
"fallom.agent_name": agent.name || "unknown"
|
|
1646
1504
|
};
|
|
1647
|
-
if (
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
attributes[`gen_ai.prompt.${i}.content`] = typeof msg.content === "string" ? msg.content : JSON.stringify(msg.content);
|
|
1651
|
-
});
|
|
1652
|
-
}
|
|
1653
|
-
if (result?.text) {
|
|
1654
|
-
attributes["gen_ai.completion.0.role"] = "assistant";
|
|
1655
|
-
attributes["gen_ai.completion.0.content"] = result.text;
|
|
1656
|
-
attributes["gen_ai.completion.0.finish_reason"] = "stop";
|
|
1657
|
-
}
|
|
1658
|
-
if (toolCalls.length > 0) {
|
|
1659
|
-
attributes["fallom.tool_calls"] = JSON.stringify(toolCalls);
|
|
1660
|
-
toolCalls.forEach((tc, i) => {
|
|
1661
|
-
attributes[`gen_ai.completion.0.tool_calls.${i}.name`] = tc.name;
|
|
1662
|
-
attributes[`gen_ai.completion.0.tool_calls.${i}.type`] = "function";
|
|
1663
|
-
attributes[`gen_ai.completion.0.tool_calls.${i}.arguments`] = JSON.stringify(tc.arguments);
|
|
1664
|
-
});
|
|
1665
|
-
}
|
|
1666
|
-
if (result?.usage) {
|
|
1667
|
-
attributes["gen_ai.usage.prompt_tokens"] = result.usage.promptTokens;
|
|
1668
|
-
attributes["gen_ai.usage.completion_tokens"] = result.usage.completionTokens;
|
|
1669
|
-
attributes["llm.usage.total_tokens"] = result.usage.totalTokens;
|
|
1505
|
+
if (captureContent2) {
|
|
1506
|
+
attributes["fallom.raw.request"] = JSON.stringify(input);
|
|
1507
|
+
attributes["fallom.raw.response"] = JSON.stringify(result);
|
|
1670
1508
|
}
|
|
1671
|
-
|
|
1509
|
+
sendTrace({
|
|
1672
1510
|
config_key: ctx.configKey,
|
|
1673
1511
|
session_id: ctx.sessionId,
|
|
1674
1512
|
customer_id: ctx.customerId,
|
|
1675
1513
|
trace_id: traceId,
|
|
1676
1514
|
span_id: spanId,
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1515
|
+
parent_span_id: parentSpanId,
|
|
1516
|
+
name: `agent.${agent.name || "unknown"}.generate`,
|
|
1517
|
+
kind: "agent",
|
|
1680
1518
|
start_time: new Date(startTime).toISOString(),
|
|
1681
1519
|
end_time: new Date(endTime).toISOString(),
|
|
1682
1520
|
duration_ms: endTime - startTime,
|
|
1683
1521
|
status: "OK",
|
|
1684
|
-
prompt_tokens: result?.usage?.promptTokens,
|
|
1685
|
-
completion_tokens: result?.usage?.completionTokens,
|
|
1686
|
-
total_tokens: result?.usage?.totalTokens,
|
|
1687
1522
|
attributes
|
|
1688
|
-
}
|
|
1689
|
-
sendTrace(traceData).catch(() => {
|
|
1523
|
+
}).catch(() => {
|
|
1690
1524
|
});
|
|
1691
1525
|
return result;
|
|
1692
1526
|
} catch (error) {
|
|
1693
1527
|
const endTime = Date.now();
|
|
1694
|
-
|
|
1528
|
+
sendTrace({
|
|
1695
1529
|
config_key: ctx.configKey,
|
|
1696
1530
|
session_id: ctx.sessionId,
|
|
1697
1531
|
customer_id: ctx.customerId,
|
|
1698
1532
|
trace_id: traceId,
|
|
1699
1533
|
span_id: spanId,
|
|
1700
|
-
|
|
1701
|
-
|
|
1534
|
+
parent_span_id: parentSpanId,
|
|
1535
|
+
name: `agent.${agent.name || "unknown"}.generate`,
|
|
1536
|
+
kind: "agent",
|
|
1702
1537
|
start_time: new Date(startTime).toISOString(),
|
|
1703
1538
|
end_time: new Date(endTime).toISOString(),
|
|
1704
1539
|
duration_ms: endTime - startTime,
|
|
1705
1540
|
status: "ERROR",
|
|
1706
|
-
error_message: error
|
|
1707
|
-
|
|
1708
|
-
|
|
1541
|
+
error_message: error?.message,
|
|
1542
|
+
attributes: {
|
|
1543
|
+
"fallom.sdk_version": "2",
|
|
1544
|
+
"fallom.method": "agent.generate",
|
|
1545
|
+
"fallom.agent_name": agent.name || "unknown"
|
|
1546
|
+
}
|
|
1547
|
+
}).catch(() => {
|
|
1709
1548
|
});
|
|
1710
1549
|
throw error;
|
|
1711
1550
|
}
|
|
@@ -1745,6 +1584,9 @@ var FallomSession = class {
|
|
|
1745
1584
|
/**
|
|
1746
1585
|
* Wrap a Vercel AI SDK model to trace all calls (PostHog style).
|
|
1747
1586
|
* Returns the same model type with tracing injected.
|
|
1587
|
+
*
|
|
1588
|
+
* Note: This only captures tokens/timing, not prompt/completion content.
|
|
1589
|
+
* Use wrapAISDK for full content tracing.
|
|
1748
1590
|
*/
|
|
1749
1591
|
traceModel(model) {
|
|
1750
1592
|
const ctx = this.ctx;
|
|
@@ -1770,17 +1612,18 @@ var FallomSession = class {
|
|
|
1770
1612
|
trace_id: traceId,
|
|
1771
1613
|
span_id: spanId,
|
|
1772
1614
|
parent_span_id: traceCtx?.parentSpanId,
|
|
1773
|
-
name: "
|
|
1615
|
+
name: "doGenerate",
|
|
1774
1616
|
kind: "llm",
|
|
1775
1617
|
model: modelId,
|
|
1776
1618
|
start_time: new Date(startTime).toISOString(),
|
|
1777
1619
|
end_time: new Date(endTime).toISOString(),
|
|
1778
1620
|
duration_ms: endTime - startTime,
|
|
1779
1621
|
status: "OK",
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1622
|
+
attributes: {
|
|
1623
|
+
"fallom.sdk_version": "2",
|
|
1624
|
+
"fallom.method": "traceModel.doGenerate",
|
|
1625
|
+
...usage ? { "fallom.raw.usage": JSON.stringify(usage) } : {}
|
|
1626
|
+
}
|
|
1784
1627
|
}).catch(() => {
|
|
1785
1628
|
});
|
|
1786
1629
|
return result;
|
|
@@ -1793,14 +1636,15 @@ var FallomSession = class {
|
|
|
1793
1636
|
trace_id: traceId,
|
|
1794
1637
|
span_id: spanId,
|
|
1795
1638
|
parent_span_id: traceCtx?.parentSpanId,
|
|
1796
|
-
name: "
|
|
1639
|
+
name: "doGenerate",
|
|
1797
1640
|
kind: "llm",
|
|
1798
1641
|
model: model.modelId || "unknown",
|
|
1799
1642
|
start_time: new Date(startTime).toISOString(),
|
|
1800
1643
|
end_time: new Date(endTime).toISOString(),
|
|
1801
1644
|
duration_ms: endTime - startTime,
|
|
1802
1645
|
status: "ERROR",
|
|
1803
|
-
error_message: error instanceof Error ? error.message : String(error)
|
|
1646
|
+
error_message: error instanceof Error ? error.message : String(error),
|
|
1647
|
+
attributes: { "fallom.sdk_version": "2", "fallom.method": "traceModel.doGenerate" }
|
|
1804
1648
|
}).catch(() => {
|
|
1805
1649
|
});
|
|
1806
1650
|
throw error;
|
|
@@ -1825,14 +1669,19 @@ var FallomSession = class {
|
|
|
1825
1669
|
trace_id: traceId,
|
|
1826
1670
|
span_id: spanId,
|
|
1827
1671
|
parent_span_id: traceCtx?.parentSpanId,
|
|
1828
|
-
name: "
|
|
1672
|
+
name: "doStream",
|
|
1829
1673
|
kind: "llm",
|
|
1830
1674
|
model: modelId,
|
|
1831
1675
|
start_time: new Date(startTime).toISOString(),
|
|
1832
1676
|
end_time: new Date(Date.now()).toISOString(),
|
|
1833
1677
|
duration_ms: Date.now() - startTime,
|
|
1834
1678
|
status: "OK",
|
|
1835
|
-
is_streaming: true
|
|
1679
|
+
is_streaming: true,
|
|
1680
|
+
attributes: {
|
|
1681
|
+
"fallom.sdk_version": "2",
|
|
1682
|
+
"fallom.method": "traceModel.doStream",
|
|
1683
|
+
"fallom.is_streaming": true
|
|
1684
|
+
}
|
|
1836
1685
|
}).catch(() => {
|
|
1837
1686
|
});
|
|
1838
1687
|
return result;
|
|
@@ -1844,7 +1693,7 @@ var FallomSession = class {
|
|
|
1844
1693
|
trace_id: traceId,
|
|
1845
1694
|
span_id: spanId,
|
|
1846
1695
|
parent_span_id: traceCtx?.parentSpanId,
|
|
1847
|
-
name: "
|
|
1696
|
+
name: "doStream",
|
|
1848
1697
|
kind: "llm",
|
|
1849
1698
|
model: modelId,
|
|
1850
1699
|
start_time: new Date(startTime).toISOString(),
|
|
@@ -1852,7 +1701,12 @@ var FallomSession = class {
|
|
|
1852
1701
|
duration_ms: Date.now() - startTime,
|
|
1853
1702
|
status: "ERROR",
|
|
1854
1703
|
error_message: error instanceof Error ? error.message : String(error),
|
|
1855
|
-
is_streaming: true
|
|
1704
|
+
is_streaming: true,
|
|
1705
|
+
attributes: {
|
|
1706
|
+
"fallom.sdk_version": "2",
|
|
1707
|
+
"fallom.method": "traceModel.doStream",
|
|
1708
|
+
"fallom.is_streaming": true
|
|
1709
|
+
}
|
|
1856
1710
|
}).catch(() => {
|
|
1857
1711
|
});
|
|
1858
1712
|
throw error;
|
|
@@ -1905,7 +1759,7 @@ var promptCache = /* @__PURE__ */ new Map();
|
|
|
1905
1759
|
var promptABCache = /* @__PURE__ */ new Map();
|
|
1906
1760
|
var promptContext = null;
|
|
1907
1761
|
var SYNC_TIMEOUT = 2e3;
|
|
1908
|
-
function
|
|
1762
|
+
function log3(msg) {
|
|
1909
1763
|
if (debugMode2) {
|
|
1910
1764
|
console.log(`[Fallom Prompts] ${msg}`);
|
|
1911
1765
|
}
|
|
@@ -2008,10 +1862,10 @@ async function get(promptKey, options = {}) {
|
|
|
2008
1862
|
const { variables, version, debug = false } = options;
|
|
2009
1863
|
debugMode2 = debug;
|
|
2010
1864
|
ensureInit();
|
|
2011
|
-
|
|
1865
|
+
log3(`get() called: promptKey=${promptKey}`);
|
|
2012
1866
|
let promptData = promptCache.get(promptKey);
|
|
2013
1867
|
if (!promptData) {
|
|
2014
|
-
|
|
1868
|
+
log3("Not in cache, fetching...");
|
|
2015
1869
|
await fetchPrompts(SYNC_TIMEOUT);
|
|
2016
1870
|
promptData = promptCache.get(promptKey);
|
|
2017
1871
|
}
|
|
@@ -2033,7 +1887,7 @@ async function get(promptKey, options = {}) {
|
|
|
2033
1887
|
promptKey,
|
|
2034
1888
|
promptVersion: targetVersion
|
|
2035
1889
|
});
|
|
2036
|
-
|
|
1890
|
+
log3(`\u2705 Got prompt: ${promptKey} v${targetVersion}`);
|
|
2037
1891
|
return {
|
|
2038
1892
|
key: promptKey,
|
|
2039
1893
|
version: targetVersion,
|
|
@@ -2045,10 +1899,10 @@ async function getAB(abTestKey, sessionId, options = {}) {
|
|
|
2045
1899
|
const { variables, debug = false } = options;
|
|
2046
1900
|
debugMode2 = debug;
|
|
2047
1901
|
ensureInit();
|
|
2048
|
-
|
|
1902
|
+
log3(`getAB() called: abTestKey=${abTestKey}, sessionId=${sessionId}`);
|
|
2049
1903
|
let abData = promptABCache.get(abTestKey);
|
|
2050
1904
|
if (!abData) {
|
|
2051
|
-
|
|
1905
|
+
log3("Not in cache, fetching...");
|
|
2052
1906
|
await fetchPromptABTests(SYNC_TIMEOUT);
|
|
2053
1907
|
abData = promptABCache.get(abTestKey);
|
|
2054
1908
|
}
|
|
@@ -2063,8 +1917,8 @@ async function getAB(abTestKey, sessionId, options = {}) {
|
|
|
2063
1917
|
throw new Error(`Prompt A/B test '${abTestKey}' has no current version.`);
|
|
2064
1918
|
}
|
|
2065
1919
|
const { variants } = versionData;
|
|
2066
|
-
|
|
2067
|
-
|
|
1920
|
+
log3(`A/B test '${abTestKey}' has ${variants?.length ?? 0} variants`);
|
|
1921
|
+
log3(`Version data: ${JSON.stringify(versionData, null, 2)}`);
|
|
2068
1922
|
if (!variants || variants.length === 0) {
|
|
2069
1923
|
throw new Error(
|
|
2070
1924
|
`Prompt A/B test '${abTestKey}' has no variants configured.`
|
|
@@ -2110,7 +1964,7 @@ async function getAB(abTestKey, sessionId, options = {}) {
|
|
|
2110
1964
|
abTestKey,
|
|
2111
1965
|
variantIndex: selectedIndex
|
|
2112
1966
|
});
|
|
2113
|
-
|
|
1967
|
+
log3(
|
|
2114
1968
|
`\u2705 Got prompt from A/B: ${promptKey} v${targetVersion} (variant ${selectedIndex})`
|
|
2115
1969
|
);
|
|
2116
1970
|
return {
|