@fallom/trace 0.2.23 → 0.2.25

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.
@@ -128,7 +128,9 @@ async function runGEval(options) {
128
128
  systemMessage,
129
129
  judgeModel,
130
130
  openrouterKey,
131
- fallomApiKey
131
+ fallomApiKey,
132
+ traceSessionId,
133
+ traceCustomerId
132
134
  } = options;
133
135
  const apiKey = openrouterKey || process.env.OPENROUTER_API_KEY;
134
136
  if (!apiKey) {
@@ -185,7 +187,9 @@ async function runGEval(options) {
185
187
  reasoning,
186
188
  startTime,
187
189
  endTime,
188
- usage: data.usage
190
+ usage: data.usage,
191
+ sessionId: traceSessionId,
192
+ customerId: traceCustomerId
189
193
  }).catch(() => {
190
194
  });
191
195
  }
@@ -205,12 +209,15 @@ async function sendGEvalTrace(options) {
205
209
  reasoning,
206
210
  startTime,
207
211
  endTime,
208
- usage
212
+ usage,
213
+ sessionId,
214
+ customerId
209
215
  } = options;
210
216
  const traceUrl = process.env.FALLOM_TRACES_URL || "https://traces.fallom.com";
211
217
  const traceData = {
212
218
  config_key: "eval-worker",
213
- session_id: `geval-${Date.now()}`,
219
+ session_id: sessionId || `geval-${Date.now()}`,
220
+ customer_id: customerId,
214
221
  trace_id: generateHexId(32),
215
222
  span_id: generateHexId(16),
216
223
  name: `geval.${metricName}`,
@@ -416,7 +423,7 @@ function datasetFromTraces(traces) {
416
423
  return items;
417
424
  }
418
425
  async function datasetFromFallom(datasetKey, version, config) {
419
- const { _apiKey: _apiKey2, _baseUrl: _baseUrl2, _initialized: _initialized2 } = await import("./core-3MHBKYBC.mjs").then(
426
+ const { _apiKey: _apiKey2, _baseUrl: _baseUrl2, _initialized: _initialized2 } = await import("./core-Q3IHBEHB.mjs").then(
420
427
  (m) => ({
421
428
  _apiKey: config?._apiKey ?? m._apiKey,
422
429
  _baseUrl: config?._baseUrl ?? m._baseUrl,
@@ -489,7 +496,7 @@ var EvaluationDataset = class {
489
496
  * @returns Self for chaining
490
497
  */
491
498
  async pull(alias, version) {
492
- const { _apiKey: _apiKey2, _baseUrl: _baseUrl2, _initialized: _initialized2 } = await import("./core-3MHBKYBC.mjs");
499
+ const { _apiKey: _apiKey2, _baseUrl: _baseUrl2, _initialized: _initialized2 } = await import("./core-Q3IHBEHB.mjs");
493
500
  if (!_initialized2) {
494
501
  throw new Error("Fallom evals not initialized. Call evals.init() first.");
495
502
  }
@@ -7,7 +7,7 @@ import {
7
7
  evaluate,
8
8
  init,
9
9
  uploadResultsPublic
10
- } from "./chunk-NNVWIZN5.mjs";
10
+ } from "./chunk-3VWF2OJX.mjs";
11
11
  import "./chunk-7P6ASYW6.mjs";
12
12
  export {
13
13
  DEFAULT_JUDGE_MODEL,
package/dist/index.d.mts CHANGED
@@ -590,6 +590,10 @@ interface RunGEvalOptions {
590
590
  openrouterKey?: string;
591
591
  /** Optional Fallom API key to enable tracing of the judge LLM call */
592
592
  fallomApiKey?: string;
593
+ /** Optional session ID for tracing (e.g., eval run ID) */
594
+ traceSessionId?: string;
595
+ /** Optional customer ID for tracing (e.g., organization ID) */
596
+ traceCustomerId?: string;
593
597
  }
594
598
  /**
595
599
  * Run G-Eval for a single metric using OpenRouter.
package/dist/index.d.ts CHANGED
@@ -590,6 +590,10 @@ interface RunGEvalOptions {
590
590
  openrouterKey?: string;
591
591
  /** Optional Fallom API key to enable tracing of the judge LLM call */
592
592
  fallomApiKey?: string;
593
+ /** Optional session ID for tracing (e.g., eval run ID) */
594
+ traceSessionId?: string;
595
+ /** Optional customer ID for tracing (e.g., organization ID) */
596
+ traceCustomerId?: string;
593
597
  }
594
598
  /**
595
599
  * Run G-Eval for a single metric using OpenRouter.
package/dist/index.js CHANGED
@@ -386,7 +386,9 @@ async function runGEval(options) {
386
386
  systemMessage,
387
387
  judgeModel,
388
388
  openrouterKey,
389
- fallomApiKey
389
+ fallomApiKey,
390
+ traceSessionId,
391
+ traceCustomerId
390
392
  } = options;
391
393
  const apiKey4 = openrouterKey || process.env.OPENROUTER_API_KEY;
392
394
  if (!apiKey4) {
@@ -443,7 +445,9 @@ async function runGEval(options) {
443
445
  reasoning,
444
446
  startTime,
445
447
  endTime,
446
- usage: data.usage
448
+ usage: data.usage,
449
+ sessionId: traceSessionId,
450
+ customerId: traceCustomerId
447
451
  }).catch(() => {
448
452
  });
449
453
  }
@@ -463,12 +467,15 @@ async function sendGEvalTrace(options) {
463
467
  reasoning,
464
468
  startTime,
465
469
  endTime,
466
- usage
470
+ usage,
471
+ sessionId,
472
+ customerId
467
473
  } = options;
468
474
  const traceUrl = process.env.FALLOM_TRACES_URL || "https://traces.fallom.com";
469
475
  const traceData = {
470
476
  config_key: "eval-worker",
471
- session_id: `geval-${Date.now()}`,
477
+ session_id: sessionId || `geval-${Date.now()}`,
478
+ customer_id: customerId,
472
479
  trace_id: generateHexId2(32),
473
480
  span_id: generateHexId2(16),
474
481
  name: `geval.${metricName}`,
@@ -2835,6 +2842,101 @@ function wrapGoogleAI(model, sessionCtx) {
2835
2842
  return model;
2836
2843
  }
2837
2844
 
2845
+ // src/trace/wrappers/vercel-ai/utils.ts
2846
+ function extractProviderInfo(model, aiModule, result) {
2847
+ const info = {};
2848
+ try {
2849
+ if (aiModule) {
2850
+ info.aiSdkVersion = aiModule.version ?? aiModule.VERSION ?? void 0;
2851
+ }
2852
+ if (!model) return info;
2853
+ info.modelId = model.modelId ?? model.id ?? String(model);
2854
+ if (model.provider) {
2855
+ if (typeof model.provider === "string") {
2856
+ info.provider = model.provider;
2857
+ } else if (typeof model.provider === "object") {
2858
+ info.provider = model.provider.id ?? model.provider.name;
2859
+ info.providerId = model.provider.id;
2860
+ }
2861
+ }
2862
+ if (model.providerId) {
2863
+ info.providerId = model.providerId;
2864
+ }
2865
+ const baseUrl4 = model.config?.baseURL ?? model.config?.baseUrl ?? model.settings?.baseURL ?? model.settings?.baseUrl ?? model.baseURL ?? model.baseUrl;
2866
+ if (baseUrl4 && typeof baseUrl4 === "string") {
2867
+ info.baseUrl = baseUrl4;
2868
+ if (!info.provider) {
2869
+ if (baseUrl4.includes("openrouter.ai")) {
2870
+ info.provider = "openrouter";
2871
+ } else if (baseUrl4.includes("api.openai.com")) {
2872
+ info.provider = "openai";
2873
+ } else if (baseUrl4.includes("api.anthropic.com")) {
2874
+ info.provider = "anthropic";
2875
+ } else if (baseUrl4.includes("generativelanguage.googleapis.com")) {
2876
+ info.provider = "google";
2877
+ } else if (baseUrl4.includes("api.mistral.ai")) {
2878
+ info.provider = "mistral";
2879
+ } else if (baseUrl4.includes("api.together.xyz")) {
2880
+ info.provider = "together";
2881
+ } else if (baseUrl4.includes("api.groq.com")) {
2882
+ info.provider = "groq";
2883
+ } else if (baseUrl4.includes("localhost") || baseUrl4.includes("127.0.0.1")) {
2884
+ info.provider = "local";
2885
+ }
2886
+ }
2887
+ }
2888
+ if (!info.provider && info.modelId) {
2889
+ const modelStr = String(info.modelId).toLowerCase();
2890
+ if (modelStr.includes("gpt-") || modelStr.includes("o1-") || modelStr.includes("text-embedding")) {
2891
+ info.provider = info.provider ?? "openai";
2892
+ } else if (modelStr.includes("claude-")) {
2893
+ info.provider = info.provider ?? "anthropic";
2894
+ } else if (modelStr.includes("gemini-") || modelStr.includes("gemma-")) {
2895
+ info.provider = info.provider ?? "google";
2896
+ } else if (modelStr.includes("mistral-") || modelStr.includes("mixtral-")) {
2897
+ info.provider = info.provider ?? "mistral";
2898
+ } else if (modelStr.includes("llama-") || modelStr.includes("meta-llama")) {
2899
+ info.provider = info.provider ?? "meta";
2900
+ } else if (modelStr.includes("/")) {
2901
+ info.provider = info.provider ?? "openrouter";
2902
+ }
2903
+ }
2904
+ if (result?.response) {
2905
+ if (!info.modelId && result.response.modelId) {
2906
+ info.modelId = result.response.modelId;
2907
+ }
2908
+ }
2909
+ info.raw = {};
2910
+ if (model.modelId) info.raw.modelId = model.modelId;
2911
+ if (model.provider) {
2912
+ info.raw.provider = typeof model.provider === "object" ? { id: model.provider.id, name: model.provider.name } : model.provider;
2913
+ }
2914
+ if (model.providerId) info.raw.providerId = model.providerId;
2915
+ if (model.specificationVersion) info.raw.specificationVersion = model.specificationVersion;
2916
+ } catch {
2917
+ }
2918
+ return info;
2919
+ }
2920
+ function providerInfoToAttributes(info) {
2921
+ const attrs = {};
2922
+ if (info.provider) {
2923
+ attrs["fallom.provider"] = info.provider;
2924
+ }
2925
+ if (info.providerId) {
2926
+ attrs["fallom.provider_id"] = info.providerId;
2927
+ }
2928
+ if (info.baseUrl) {
2929
+ attrs["fallom.base_url"] = info.baseUrl;
2930
+ }
2931
+ if (info.aiSdkVersion) {
2932
+ attrs["fallom.ai_sdk_version"] = info.aiSdkVersion;
2933
+ }
2934
+ if (info.raw && Object.keys(info.raw).length > 0) {
2935
+ attrs["fallom.provider_raw"] = JSON.stringify(info.raw);
2936
+ }
2937
+ return attrs;
2938
+ }
2939
+
2838
2940
  // src/trace/wrappers/vercel-ai/generate-text.ts
2839
2941
  function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2840
2942
  const ctx = sessionCtx;
@@ -2858,34 +2960,44 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2858
2960
  )) {
2859
2961
  if (tool && typeof tool.execute === "function") {
2860
2962
  const originalExecute = tool.execute;
2861
- wrappedTools[toolName] = {
2862
- ...tool,
2863
- execute: async (...executeArgs) => {
2864
- const toolStartTime = Date.now();
2865
- const toolCallId = `${toolName}-${toolStartTime}`;
2866
- try {
2867
- const result = await originalExecute(...executeArgs);
2868
- const toolEndTime = Date.now();
2869
- toolTimings.set(toolCallId, {
2870
- name: toolName,
2871
- startTime: toolStartTime - startTime,
2872
- // Relative to request start
2873
- endTime: toolEndTime - startTime,
2874
- duration: toolEndTime - toolStartTime
2875
- });
2876
- return result;
2877
- } catch (error) {
2878
- const toolEndTime = Date.now();
2879
- toolTimings.set(toolCallId, {
2880
- name: toolName,
2881
- startTime: toolStartTime - startTime,
2882
- endTime: toolEndTime - startTime,
2883
- duration: toolEndTime - toolStartTime
2884
- });
2885
- throw error;
2886
- }
2963
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
2964
+ const allKeys = [
2965
+ ...Object.getOwnPropertyNames(tool),
2966
+ ...Object.getOwnPropertySymbols(tool)
2967
+ ];
2968
+ for (const key of allKeys) {
2969
+ if (key === "execute") continue;
2970
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
2971
+ if (descriptor) {
2972
+ Object.defineProperty(wrappedTool, key, descriptor);
2973
+ }
2974
+ }
2975
+ wrappedTool.execute = async (...executeArgs) => {
2976
+ const toolStartTime = Date.now();
2977
+ const toolCallId = `${toolName}-${toolStartTime}`;
2978
+ try {
2979
+ const result = await originalExecute(...executeArgs);
2980
+ const toolEndTime = Date.now();
2981
+ toolTimings.set(toolCallId, {
2982
+ name: toolName,
2983
+ startTime: toolStartTime - startTime,
2984
+ // Relative to request start
2985
+ endTime: toolEndTime - startTime,
2986
+ duration: toolEndTime - toolStartTime
2987
+ });
2988
+ return result;
2989
+ } catch (error) {
2990
+ const toolEndTime = Date.now();
2991
+ toolTimings.set(toolCallId, {
2992
+ name: toolName,
2993
+ startTime: toolStartTime - startTime,
2994
+ endTime: toolEndTime - startTime,
2995
+ duration: toolEndTime - toolStartTime
2996
+ });
2997
+ throw error;
2887
2998
  }
2888
2999
  };
3000
+ wrappedTools[toolName] = wrappedTool;
2889
3001
  } else {
2890
3002
  wrappedTools[toolName] = tool;
2891
3003
  }
@@ -2901,9 +3013,12 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2901
3013
  console.log(" steps:", result?.steps?.length || 0);
2902
3014
  }
2903
3015
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
3016
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
2904
3017
  const attributes = {
2905
3018
  "fallom.sdk_version": "2",
2906
- "fallom.method": "generateText"
3019
+ "fallom.method": "generateText",
3020
+ // Provider info for debugging
3021
+ ...providerInfoToAttributes(providerInfo)
2907
3022
  };
2908
3023
  if (captureContent2) {
2909
3024
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -2917,7 +3032,17 @@ function createGenerateTextWrapper(aiModule, sessionCtx, debug = false) {
2917
3032
  const mapToolCall = (tc) => {
2918
3033
  let args2 = tc?.args ?? tc?.input;
2919
3034
  if (args2 === void 0 && tc) {
2920
- const { type, toolCallId, toolName, providerExecuted, dynamic, invalid, error, providerMetadata, ...rest } = tc;
3035
+ const {
3036
+ type,
3037
+ toolCallId,
3038
+ toolName,
3039
+ providerExecuted,
3040
+ dynamic,
3041
+ invalid,
3042
+ error,
3043
+ providerMetadata,
3044
+ ...rest
3045
+ } = tc;
2921
3046
  if (Object.keys(rest).length > 0) {
2922
3047
  args2 = rest;
2923
3048
  }
@@ -3161,33 +3286,43 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
3161
3286
  )) {
3162
3287
  if (tool && typeof tool.execute === "function") {
3163
3288
  const originalExecute = tool.execute;
3164
- wrappedTools[toolName] = {
3165
- ...tool,
3166
- execute: async (...executeArgs) => {
3167
- const toolStartTime = Date.now();
3168
- const toolCallId = `${toolName}-${toolStartTime}`;
3169
- try {
3170
- const result2 = await originalExecute(...executeArgs);
3171
- const toolEndTime = Date.now();
3172
- toolTimings.set(toolCallId, {
3173
- name: toolName,
3174
- startTime: toolStartTime - startTime,
3175
- endTime: toolEndTime - startTime,
3176
- duration: toolEndTime - toolStartTime
3177
- });
3178
- return result2;
3179
- } catch (error) {
3180
- const toolEndTime = Date.now();
3181
- toolTimings.set(toolCallId, {
3182
- name: toolName,
3183
- startTime: toolStartTime - startTime,
3184
- endTime: toolEndTime - startTime,
3185
- duration: toolEndTime - toolStartTime
3186
- });
3187
- throw error;
3188
- }
3289
+ const wrappedTool = Object.create(Object.getPrototypeOf(tool) || {});
3290
+ const allKeys = [
3291
+ ...Object.getOwnPropertyNames(tool),
3292
+ ...Object.getOwnPropertySymbols(tool)
3293
+ ];
3294
+ for (const key of allKeys) {
3295
+ if (key === "execute") continue;
3296
+ const descriptor = Object.getOwnPropertyDescriptor(tool, key);
3297
+ if (descriptor) {
3298
+ Object.defineProperty(wrappedTool, key, descriptor);
3299
+ }
3300
+ }
3301
+ wrappedTool.execute = async (...executeArgs) => {
3302
+ const toolStartTime = Date.now();
3303
+ const toolCallId = `${toolName}-${toolStartTime}`;
3304
+ try {
3305
+ const result2 = await originalExecute(...executeArgs);
3306
+ const toolEndTime = Date.now();
3307
+ toolTimings.set(toolCallId, {
3308
+ name: toolName,
3309
+ startTime: toolStartTime - startTime,
3310
+ endTime: toolEndTime - startTime,
3311
+ duration: toolEndTime - toolStartTime
3312
+ });
3313
+ return result2;
3314
+ } catch (error) {
3315
+ const toolEndTime = Date.now();
3316
+ toolTimings.set(toolCallId, {
3317
+ name: toolName,
3318
+ startTime: toolStartTime - startTime,
3319
+ endTime: toolEndTime - startTime,
3320
+ duration: toolEndTime - toolStartTime
3321
+ });
3322
+ throw error;
3189
3323
  }
3190
3324
  };
3325
+ wrappedTools[toolName] = wrappedTool;
3191
3326
  } else {
3192
3327
  wrappedTools[toolName] = tool;
3193
3328
  }
@@ -3298,10 +3433,13 @@ function createStreamTextWrapper(aiModule, sessionCtx, debug = false) {
3298
3433
  providerMetadata = void 0;
3299
3434
  }
3300
3435
  }
3436
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3301
3437
  const attributes = {
3302
3438
  "fallom.sdk_version": "2",
3303
3439
  "fallom.method": "streamText",
3304
- "fallom.is_streaming": true
3440
+ "fallom.is_streaming": true,
3441
+ // Provider info for debugging
3442
+ ...providerInfoToAttributes(providerInfo)
3305
3443
  };
3306
3444
  if (captureContent2) {
3307
3445
  const mapToolCall = (tc) => {
@@ -3572,9 +3710,12 @@ function createGenerateObjectWrapper(aiModule, sessionCtx, debug = false) {
3572
3710
  );
3573
3711
  }
3574
3712
  const modelId = result?.response?.modelId || params?.model?.modelId || String(params?.model || "unknown");
3713
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3575
3714
  const attributes = {
3576
3715
  "fallom.sdk_version": "2",
3577
- "fallom.method": "generateObject"
3716
+ "fallom.method": "generateObject",
3717
+ // Provider info for debugging
3718
+ ...providerInfoToAttributes(providerInfo)
3578
3719
  };
3579
3720
  if (captureContent2) {
3580
3721
  attributes["fallom.raw.request"] = JSON.stringify({
@@ -3697,10 +3838,13 @@ function createStreamObjectWrapper(aiModule, sessionCtx, debug = false) {
3697
3838
  providerMetadata = void 0;
3698
3839
  }
3699
3840
  }
3841
+ const providerInfo = extractProviderInfo(params?.model, aiModule, result);
3700
3842
  const attributes = {
3701
3843
  "fallom.sdk_version": "2",
3702
3844
  "fallom.method": "streamObject",
3703
- "fallom.is_streaming": true
3845
+ "fallom.is_streaming": true,
3846
+ // Provider info for debugging
3847
+ ...providerInfoToAttributes(providerInfo)
3704
3848
  };
3705
3849
  if (captureContent2) {
3706
3850
  attributes["fallom.raw.request"] = JSON.stringify({