langwatch 1.3.0 → 1.5.0

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.
Files changed (34) hide show
  1. package/dist/{chunk-GOGMRTV5.js → chunk-5ERLGHP2.js} +2 -2
  2. package/dist/chunk-5ERLGHP2.js.map +1 -0
  3. package/dist/{chunk-SOODMKTN.mjs → chunk-QZRTEEGV.mjs} +65 -27
  4. package/dist/chunk-QZRTEEGV.mjs.map +1 -0
  5. package/dist/{chunk-KUJACQJ2.js → chunk-XIN5LXHQ.js} +75 -37
  6. package/dist/chunk-XIN5LXHQ.js.map +1 -0
  7. package/dist/{chunk-7SZIBH2A.mjs → chunk-Y6XAM26B.mjs} +2 -2
  8. package/dist/chunk-Y6XAM26B.mjs.map +1 -0
  9. package/dist/cli/bundle.js +547 -408
  10. package/dist/{implementation-Cdrj3mBw.d.ts → implementation-CvPr4t60.d.ts} +1 -1
  11. package/dist/{implementation-Bd2Z0kjH.d.mts → implementation-Ro3LpjAt.d.mts} +1 -1
  12. package/dist/index.d.mts +568 -44
  13. package/dist/index.d.ts +568 -44
  14. package/dist/index.js +860 -101
  15. package/dist/index.js.map +1 -1
  16. package/dist/index.mjs +832 -73
  17. package/dist/index.mjs.map +1 -1
  18. package/dist/observability-sdk/index.d.mts +3 -3
  19. package/dist/observability-sdk/index.d.ts +3 -3
  20. package/dist/observability-sdk/index.js +2 -2
  21. package/dist/observability-sdk/index.mjs +1 -1
  22. package/dist/observability-sdk/instrumentation/langchain/index.d.mts +1 -1
  23. package/dist/observability-sdk/instrumentation/langchain/index.d.ts +1 -1
  24. package/dist/observability-sdk/setup/node/index.d.mts +25 -0
  25. package/dist/observability-sdk/setup/node/index.d.ts +25 -0
  26. package/dist/observability-sdk/setup/node/index.js +3 -3
  27. package/dist/observability-sdk/setup/node/index.mjs +2 -2
  28. package/dist/{types-DzSFwVBw.d.ts → types-CHIvGRuv.d.ts} +12173 -7892
  29. package/dist/{types-ruthADbq.d.mts → types-VoDc_AXK.d.mts} +12173 -7892
  30. package/package.json +5 -2
  31. package/dist/chunk-7SZIBH2A.mjs.map +0 -1
  32. package/dist/chunk-GOGMRTV5.js.map +0 -1
  33. package/dist/chunk-KUJACQJ2.js.map +0 -1
  34. package/dist/chunk-SOODMKTN.mjs.map +0 -1
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@ var _chunkK6KPNTQOjs = require('./chunk-K6KPNTQO.js');
9
9
 
10
10
 
11
11
 
12
- var _chunkKUJACQJ2js = require('./chunk-KUJACQJ2.js');
12
+ var _chunkXIN5LXHQjs = require('./chunk-XIN5LXHQ.js');
13
13
 
14
14
 
15
15
 
@@ -20,7 +20,7 @@ var _chunkKUJACQJ2js = require('./chunk-KUJACQJ2.js');
20
20
 
21
21
 
22
22
 
23
- var _chunkGOGMRTV5js = require('./chunk-GOGMRTV5.js');
23
+ var _chunk5ERLGHP2js = require('./chunk-5ERLGHP2.js');
24
24
 
25
25
 
26
26
 
@@ -326,7 +326,7 @@ var PromptServiceTracingDecorator = class {
326
326
  };
327
327
 
328
328
  // src/client-sdk/services/prompts/tracing/tracer.ts
329
- var tracer = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunkGOGMRTV5js.LANGWATCH_SDK_NAME_CLIENT}.prompts`, _chunkGOGMRTV5js.LANGWATCH_SDK_VERSION);
329
+ var tracer = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunk5ERLGHP2js.LANGWATCH_SDK_NAME_CLIENT}.prompts`, _chunk5ERLGHP2js.LANGWATCH_SDK_VERSION);
330
330
 
331
331
  // src/client-sdk/tracing/create-tracing-proxy.ts
332
332
  var _api = require('@opentelemetry/api');
@@ -659,14 +659,14 @@ var handledErrorMiddleware = {
659
659
  };
660
660
  var createLangWatchApiClient = (apiKey = ((_b) => (_b = ((_a) => (_a = scopedApiKey()) != null ? _a : process.env.LANGWATCH_API_KEY)()) != null ? _b : "")(), endpoint, projectId = process.env.LANGWATCH_PROJECT_ID) => {
661
661
  const client = _openapifetch2.default.call(void 0, {
662
- baseUrl: _chunkKUJACQJ2js.resolveEndpoint.call(void 0, endpoint),
663
- headers: _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey, projectId })), {
662
+ baseUrl: _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, endpoint),
663
+ headers: _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey, projectId })), {
664
664
  "content-type": "application/json",
665
- "user-agent": `langwatch-sdk-node/${_chunkGOGMRTV5js.version}`,
666
- "x-langwatch-sdk-name": _chunkGOGMRTV5js.LANGWATCH_SDK_NAME_OBSERVABILITY,
667
- "x-langwatch-sdk-language": _chunkGOGMRTV5js.LANGWATCH_SDK_LANGUAGE,
668
- "x-langwatch-sdk-version": _chunkGOGMRTV5js.LANGWATCH_SDK_VERSION,
669
- "x-langwatch-sdk-platform": _chunkGOGMRTV5js.LANGWATCH_SDK_RUNTIME.call(void 0, )
665
+ "user-agent": `langwatch-sdk-node/${_chunk5ERLGHP2js.version}`,
666
+ "x-langwatch-sdk-name": _chunk5ERLGHP2js.LANGWATCH_SDK_NAME_OBSERVABILITY,
667
+ "x-langwatch-sdk-language": _chunk5ERLGHP2js.LANGWATCH_SDK_LANGUAGE,
668
+ "x-langwatch-sdk-version": _chunk5ERLGHP2js.LANGWATCH_SDK_VERSION,
669
+ "x-langwatch-sdk-platform": _chunk5ERLGHP2js.LANGWATCH_SDK_RUNTIME.call(void 0, )
670
670
  })
671
671
  });
672
672
  client.use(handledErrorMiddleware);
@@ -710,9 +710,64 @@ var PromptsApiError = class extends PromptsError {
710
710
  }
711
711
  };
712
712
 
713
+ // src/client-sdk/services/_shared/error-code-copy.ts
714
+ var SENTENCE_BY_CODE = {
715
+ enterprise_plan_required: "This capability needs the Enterprise plan",
716
+ insufficient_permissions: "This credential does not carry the permission this call needs",
717
+ missing_credentials: "This request carried no API key",
718
+ invalid_credentials: "That API key is not valid",
719
+ organization_not_found: "That API key does not resolve to an organization on this instance",
720
+ validation_error: "The request did not pass validation",
721
+ custom_role_in_use: "That role is still held by a member or a role binding",
722
+ custom_role_id_required: "A CUSTOM role binding has to name which custom role it grants",
723
+ custom_role_not_assignable: "That custom role cannot be granted here",
724
+ custom_role_name_reserved: "That role name is reserved",
725
+ custom_role_name_taken: "A role with that name already exists here",
726
+ role_binding_principal_invalid: "A role binding names exactly one principal: a user, a group, or an API key",
727
+ role_binding_already_exists: "That principal already holds that role at that scope",
728
+ org_exclusive_permission_scope: "That role carries an organization-only permission, so it cannot be bound to a team or a project",
729
+ member_seat_limit_reached: "The plan's member seats are all in use",
730
+ personal_workspace_not_managed_here: "Personal workspaces are not managed through this API",
731
+ already_organization_member: "They are already in this organization",
732
+ user_not_in_organization: "That user is not a member of this organization",
733
+ group_not_in_organization: "That group does not belong to this organization",
734
+ api_key_not_in_organization: "That API key does not belong to this organization",
735
+ team_not_in_organization: "That team does not belong to this organization",
736
+ scope_not_in_organization: "That scope does not belong to this organization",
737
+ // Humanizing turns an acronym into a word: "Api key not found", "Scim token
738
+ // not found". Spelled out here instead.
739
+ api_key_not_found: "API key not found",
740
+ api_key_not_owned: "That API key belongs to somebody else",
741
+ api_key_already_revoked: "That API key is already revoked",
742
+ scim_token_not_found: "SCIM token not found",
743
+ duplicate_invite: "They already have a pending invite",
744
+ cannot_remove_self: "A credential cannot remove its own member",
745
+ cannot_disable_self: "A credential cannot disable its own member",
746
+ cannot_remove_last_admin: "That is the organization's last administrator, so it has to keep them",
747
+ api_key_scope_violation: "That API key cannot be given that access"
748
+ };
749
+ var humanizeCode = (code) => {
750
+ const words = code.replace(/[_-]+/g, " ").trim();
751
+ if (!words) return code;
752
+ return words.charAt(0).toUpperCase() + words.slice(1);
753
+ };
754
+ var isCodeAsMessage = ({
755
+ code,
756
+ message
757
+ }) => typeof code === "string" && code.length > 0 && typeof message === "string" && message.trim() === code;
758
+ var sentenceForCode = (code) => {
759
+ var _a;
760
+ return (_a = SENTENCE_BY_CODE[code]) != null ? _a : humanizeCode(code);
761
+ };
762
+ var looksLikeErrorCode = (value) => typeof value === "string" && /^[a-z][a-z0-9]*(?:_[a-z0-9]+)*$/.test(value);
763
+
713
764
  // src/client-sdk/services/_shared/format-api-error.ts
714
765
  var GENERIC_MESSAGES = /* @__PURE__ */ new Set([
715
766
  "",
767
+ // The bare class name some envelopes carry in their `error` field; as a
768
+ // prefix it can only turn "enterprise_plan_required" into
769
+ // "Error: enterprise_plan_required".
770
+ "error",
716
771
  "internal server error",
717
772
  "unknown error",
718
773
  "unknown error occurred"
@@ -796,6 +851,13 @@ function formatApiErrorMessage({
796
851
  if (zod) return zod;
797
852
  const fromMessage = typeof body.message === "string" ? body.message : void 0;
798
853
  const fromError = typeof body.error === "string" ? body.error : void 0;
854
+ const codeField = looksLikeErrorCode(body.code) ? body.code : looksLikeErrorCode(fromError) ? fromError : void 0;
855
+ if (codeField) {
856
+ if (!isCodeAsMessage({ code: codeField, message: fromMessage }) && fromMessage && !isGeneric(fromMessage)) {
857
+ return fromMessage;
858
+ }
859
+ return sentenceForCode(codeField);
860
+ }
799
861
  const fromDetail = typeof body.detail === "string" ? body.detail : void 0;
800
862
  const fromReason = typeof body.reason === "string" ? body.reason : void 0;
801
863
  const meaningful = firstMeaningful(fromMessage, fromError, fromDetail, fromReason);
@@ -1881,12 +1943,12 @@ var DatasetPlanLimitError = class extends DatasetError {
1881
1943
  };
1882
1944
 
1883
1945
  // src/client-sdk/services/datasets/tracing/tracer.ts
1884
- var tracer2 = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunkGOGMRTV5js.LANGWATCH_SDK_NAME_CLIENT}.datasets`, _chunkGOGMRTV5js.LANGWATCH_SDK_VERSION);
1946
+ var tracer2 = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunk5ERLGHP2js.LANGWATCH_SDK_NAME_CLIENT}.datasets`, _chunk5ERLGHP2js.LANGWATCH_SDK_VERSION);
1885
1947
 
1886
1948
  // src/client-sdk/services/datasets/dataset.service.ts
1887
1949
  var DatasetService = class {
1888
1950
  constructor(config) {
1889
- this.config = _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, config), { endpoint: _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config.endpoint) });
1951
+ this.config = _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, config), { endpoint: _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config.endpoint) });
1890
1952
  return createTracingProxy(this, tracer2);
1891
1953
  }
1892
1954
  /**
@@ -2167,7 +2229,7 @@ var DatasetService = class {
2167
2229
  const url = `${endpoint}${path2}`;
2168
2230
  const response = await fetch(url, {
2169
2231
  method: "POST",
2170
- headers: _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey }),
2232
+ headers: _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey }),
2171
2233
  body: formData
2172
2234
  });
2173
2235
  if (!response.ok) {
@@ -2650,6 +2712,13 @@ If you want to use different metadata, please use a different target name.`
2650
2712
  this.name = "TargetMetadataConflictError";
2651
2713
  }
2652
2714
  };
2715
+ var ComparisonError = class extends ExperimentError {
2716
+ constructor(message, missingTargets = []) {
2717
+ super(message);
2718
+ this.missingTargets = missingTargets;
2719
+ this.name = "ComparisonError";
2720
+ }
2721
+ };
2653
2722
  var EvaluatorError = class extends ExperimentError {
2654
2723
  constructor(evaluatorSlug, message, cause) {
2655
2724
  super(`Evaluator '${evaluatorSlug}' failed: ${message}`);
@@ -2659,6 +2728,119 @@ var EvaluatorError = class extends ExperimentError {
2659
2728
  }
2660
2729
  };
2661
2730
 
2731
+ // src/client-sdk/services/experiments/comparison.ts
2732
+ var COMPARISON_EVALUATOR_SLUG = "langevals/select_best_compare";
2733
+ var DEFAULT_COMPARISON_NAME = "comparison";
2734
+ var renderTargetOutput = (result) => {
2735
+ var _a;
2736
+ if (result === void 0 || result === null) {
2737
+ return "";
2738
+ }
2739
+ if (typeof result === "string") {
2740
+ return result;
2741
+ }
2742
+ if (typeof result === "number" || typeof result === "boolean" || typeof result === "bigint") {
2743
+ return String(result);
2744
+ }
2745
+ if (typeof result === "object" && !Array.isArray(result)) {
2746
+ const fields = Object.keys(result);
2747
+ if (fields.length === 1 && fields[0] === "output") {
2748
+ return renderTargetOutput(result.output);
2749
+ }
2750
+ }
2751
+ try {
2752
+ return (_a = JSON.stringify(result)) != null ? _a : "";
2753
+ } catch (e) {
2754
+ return "";
2755
+ }
2756
+ };
2757
+ var buildComparisonSettings = (options) => {
2758
+ const settings = {};
2759
+ if (options.prompt !== void 0) settings.prompt = options.prompt;
2760
+ if (options.model !== void 0) settings.model = options.model;
2761
+ if (options.golden !== void 0) settings.has_golden_answer = true;
2762
+ if (options.allowTie !== void 0) settings.allow_tie = options.allowTie;
2763
+ if (options.randomizeOrder !== void 0) {
2764
+ settings.randomize_order = options.randomizeOrder;
2765
+ }
2766
+ if (options.swapAndReconcile !== void 0) {
2767
+ settings.swap_and_reconcile = options.swapAndReconcile;
2768
+ }
2769
+ if (options.includeMetrics !== void 0) {
2770
+ settings.include_metrics = options.includeMetrics;
2771
+ }
2772
+ if (options.temperature !== void 0) {
2773
+ settings.temperature = options.temperature;
2774
+ }
2775
+ return settings;
2776
+ };
2777
+ var buildComparisonCandidates = (names, captured) => names.map((name) => {
2778
+ const output = captured.get(name);
2779
+ if (!output) {
2780
+ throw new ComparisonError(
2781
+ `Cannot compare: '${name}' was selected as a candidate but recorded no output.`,
2782
+ [name]
2783
+ );
2784
+ }
2785
+ return _chunkCLTKABMOjs.__spreadValues.call(void 0, {
2786
+ id: name,
2787
+ output: output.output
2788
+ }, output.durationMs !== void 0 ? { duration: output.durationMs / 1e3 } : {});
2789
+ });
2790
+ var buildComparisonData = ({
2791
+ input,
2792
+ golden,
2793
+ candidates,
2794
+ index
2795
+ }) => _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, input !== void 0 ? { input } : {}), golden !== void 0 ? { golden } : {}), {
2796
+ candidates,
2797
+ row_index: index
2798
+ });
2799
+ var toComparisonVerdict = ({
2800
+ response,
2801
+ candidates
2802
+ }) => {
2803
+ var _a;
2804
+ const reasoning = (_a = response.details) != null ? _a : null;
2805
+ if (response.status === "error") {
2806
+ return { status: "error", winner: null, reasoning, candidates };
2807
+ }
2808
+ if (response.status !== "processed" || response.label == null) {
2809
+ return { status: "inconclusive", winner: null, reasoning, candidates };
2810
+ }
2811
+ if (response.label === "tie") {
2812
+ return { status: "tie", winner: null, reasoning, candidates };
2813
+ }
2814
+ return { status: "decided", winner: response.label, reasoning, candidates };
2815
+ };
2816
+ var comparisonEntryStatus = (status) => {
2817
+ switch (status) {
2818
+ case "decided":
2819
+ case "tie":
2820
+ return "processed";
2821
+ case "error":
2822
+ return "error";
2823
+ case "inconclusive":
2824
+ case "skipped":
2825
+ return "skipped";
2826
+ }
2827
+ };
2828
+ var comparisonEntryLabel = (verdict) => {
2829
+ if (verdict.status === "decided") return verdict.winner;
2830
+ if (verdict.status === "tie") return "tie";
2831
+ return null;
2832
+ };
2833
+ var describeSkippedComparison = ({
2834
+ candidates,
2835
+ missing
2836
+ }) => {
2837
+ const head = `A comparison needs at least two candidate outputs, this row has ${candidates.length}.`;
2838
+ if (missing.length === 0) {
2839
+ return head;
2840
+ }
2841
+ return `${head} No output was recorded for: ${missing.join(", ")}.`;
2842
+ };
2843
+
2662
2844
  // src/client-sdk/services/experiments/printSummary.ts
2663
2845
  function printSummary(result) {
2664
2846
  const { runId, status, passed, failed, passRate, duration, runUrl, summary } = result;
@@ -2706,6 +2888,8 @@ function printSummary(result) {
2706
2888
  // src/client-sdk/services/experiments/experiment.ts
2707
2889
  var DEFAULT_CONCURRENCY = 4;
2708
2890
  var DEBOUNCE_INTERVAL_MS = 1e3;
2891
+ var MAX_COMPARISON_ROWS_RETAINED = 1e3;
2892
+ var EVALUATOR_TIMEOUT_MS = 9e5;
2709
2893
  var iterationContextStorage = new (0, _async_hooks.AsyncLocalStorage)();
2710
2894
  var targetContextStorage = new (0, _async_hooks.AsyncLocalStorage)();
2711
2895
  var Experiment = class _Experiment {
@@ -2726,9 +2910,12 @@ var Experiment = class _Experiment {
2726
2910
  this.runUrl = "";
2727
2911
  // Target registry
2728
2912
  this.targets = /* @__PURE__ */ new Map();
2729
- // Current iteration context (for log/evaluate calls)
2730
- this.currentTraceId = null;
2731
- this.currentIndex = null;
2913
+ // Per-row target outputs for compare(), keyed by row then by target name.
2914
+ // Captured when a withTarget() callback resolves and kept independently of
2915
+ // the batch, which is flushed on a timer and may be long gone by the time
2916
+ // the row is compared. Insertion-ordered, and reaped oldest-first past
2917
+ // MAX_COMPARISON_ROWS_RETAINED.
2918
+ this.capturedOutputs = /* @__PURE__ */ new Map();
2732
2919
  // Track whether withTarget() was used in the current iteration
2733
2920
  // If so, we don't create dataset entries in executeItem()
2734
2921
  // Note: This is now checked via iterationContextStorage to be thread-safe
@@ -2741,7 +2928,7 @@ var Experiment = class _Experiment {
2741
2928
  this.experimentSlug = name;
2742
2929
  this.runId = (_a = options.runId) != null ? _a : generateHumanReadableId();
2743
2930
  this.apiClient = options.apiClient;
2744
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, options.endpoint);
2931
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, options.endpoint);
2745
2932
  this.apiKey = options.apiKey;
2746
2933
  this.logger = options.logger;
2747
2934
  this.concurrency = (_b = options.concurrency) != null ? _b : DEFAULT_CONCURRENCY;
@@ -2751,7 +2938,7 @@ var Experiment = class _Experiment {
2751
2938
  * Initialize an evaluation session
2752
2939
  */
2753
2940
  static async init(name, options) {
2754
- _chunkKUJACQJ2js.ensureSetup.call(void 0, );
2941
+ _chunkXIN5LXHQjs.ensureSetup.call(void 0, );
2755
2942
  const experiment = new _Experiment(name, options);
2756
2943
  await experiment.initialize();
2757
2944
  return experiment;
@@ -2770,7 +2957,7 @@ var Experiment = class _Experiment {
2770
2957
  method: "POST",
2771
2958
  headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, {
2772
2959
  "Content-Type": "application/json"
2773
- }, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
2960
+ }, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
2774
2961
  body: JSON.stringify({
2775
2962
  experiment_name: this.name,
2776
2963
  experiment_slug: this.experimentSlug,
@@ -2851,10 +3038,9 @@ var Experiment = class _Experiment {
2851
3038
  let error;
2852
3039
  let capturedTraceId = null;
2853
3040
  this.iterationUsedWithTarget.set(index, false);
2854
- const iterationContext = { index, item };
3041
+ const iterationContext = { index, item, traceId: null };
2855
3042
  if (this.evaluationUsesTargets) {
2856
3043
  await iterationContextStorage.run(iterationContext, async () => {
2857
- this.currentIndex = index;
2858
3044
  try {
2859
3045
  const span = {
2860
3046
  setStatus: () => {
@@ -2872,8 +3058,6 @@ var Experiment = class _Experiment {
2872
3058
  } catch (err) {
2873
3059
  error = err instanceof Error ? err : new Error(String(err));
2874
3060
  this.logger.error(`Evaluation error at index ${index}:`, error);
2875
- } finally {
2876
- this.currentIndex = null;
2877
3061
  }
2878
3062
  });
2879
3063
  } else {
@@ -2891,8 +3075,7 @@ var Experiment = class _Experiment {
2891
3075
  const span = _chunkK6KPNTQOjs.createLangWatchSpan.call(void 0, otelSpan);
2892
3076
  const spanContext = otelSpan.spanContext();
2893
3077
  const traceId = spanContext.traceId;
2894
- this.currentTraceId = traceId;
2895
- this.currentIndex = index;
3078
+ iterationContext.traceId = traceId;
2896
3079
  capturedTraceId = traceId;
2897
3080
  try {
2898
3081
  const ctx = { item, index, span };
@@ -2911,8 +3094,6 @@ var Experiment = class _Experiment {
2911
3094
  this.logger.error(`Evaluation error at index ${index}:`, error);
2912
3095
  } finally {
2913
3096
  span.end();
2914
- this.currentTraceId = null;
2915
- this.currentIndex = null;
2916
3097
  }
2917
3098
  }
2918
3099
  );
@@ -2960,7 +3141,7 @@ var Experiment = class _Experiment {
2960
3141
  * ```
2961
3142
  */
2962
3143
  log(metric, options) {
2963
- var _a, _b, _c, _d;
3144
+ var _a, _b, _c, _d, _e;
2964
3145
  const targetContext = targetContextStorage.getStore();
2965
3146
  const {
2966
3147
  data = {},
@@ -2981,7 +3162,7 @@ var Experiment = class _Experiment {
2981
3162
  if (target) {
2982
3163
  targetId = this.registerTarget(target, metadata);
2983
3164
  }
2984
- const traceId = (_c = (_b = targetContext == null ? void 0 : targetContext.traceId) != null ? _b : this.currentTraceId) != null ? _c : this.getTraceIdFromContext();
3165
+ const traceId = (_d = (_c = targetContext == null ? void 0 : targetContext.traceId) != null ? _c : (_b = iterationContextStorage.getStore()) == null ? void 0 : _b.traceId) != null ? _d : this.getTraceIdFromContext();
2985
3166
  const result = {
2986
3167
  name: metric,
2987
3168
  evaluator: metric,
@@ -2996,9 +3177,15 @@ var Experiment = class _Experiment {
2996
3177
  cost: cost != null ? cost : null,
2997
3178
  duration: duration != null ? duration : null,
2998
3179
  error_type: error ? error.name : null,
2999
- traceback: error ? [(_d = error.stack) != null ? _d : error.message] : null,
3180
+ traceback: error ? [(_e = error.stack) != null ? _e : error.message] : null,
3000
3181
  target_id: targetId != null ? targetId : null
3001
3182
  };
3183
+ this.pushEvaluation(result);
3184
+ }
3185
+ /**
3186
+ * Queue an evaluation result for the next batch
3187
+ */
3188
+ pushEvaluation(result) {
3002
3189
  this.batch.evaluations.push(result);
3003
3190
  this.cumulativeEvaluations.push({
3004
3191
  name: result.name,
@@ -3038,7 +3225,7 @@ var Experiment = class _Experiment {
3038
3225
  * ```
3039
3226
  */
3040
3227
  async evaluate(evaluatorSlug, options) {
3041
- var _a, _b, _c, _d, _e, _f, _g, _h, _i;
3228
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
3042
3229
  const targetContext = targetContextStorage.getStore();
3043
3230
  const {
3044
3231
  data,
@@ -3051,42 +3238,29 @@ var Experiment = class _Experiment {
3051
3238
  index = (_a = targetContext == null ? void 0 : targetContext.index) != null ? _a : options.index
3052
3239
  } = options;
3053
3240
  const startTime = Date.now();
3054
- const traceId = (_c = (_b = targetContext == null ? void 0 : targetContext.traceId) != null ? _b : this.currentTraceId) != null ? _c : this.getTraceIdFromContext();
3055
- const spanId = (_d = targetContext == null ? void 0 : targetContext.spanId) != null ? _d : this.getSpanIdFromContext();
3241
+ const traceId = (_d = (_c = targetContext == null ? void 0 : targetContext.traceId) != null ? _c : (_b = iterationContextStorage.getStore()) == null ? void 0 : _b.traceId) != null ? _d : this.getTraceIdFromContext();
3242
+ const spanId = (_e = targetContext == null ? void 0 : targetContext.spanId) != null ? _e : this.getSpanIdFromContext();
3056
3243
  try {
3057
- const response = await fetch(
3058
- `${this.endpoint}/api/evaluations/${evaluatorSlug}/evaluate`,
3059
- {
3060
- method: "POST",
3061
- headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, {
3062
- "Content-Type": "application/json"
3063
- }, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
3064
- body: JSON.stringify({
3065
- trace_id: traceId != null ? traceId : null,
3066
- span_id: spanId != null ? spanId : null,
3067
- name: name != null ? name : evaluatorSlug,
3068
- data,
3069
- settings,
3070
- as_guardrail: asGuardrail
3071
- })
3072
- }
3073
- );
3074
- if (!response.ok) {
3075
- const text = await response.text();
3076
- throw new EvaluatorError(evaluatorSlug, text);
3077
- }
3078
- const result = await response.json();
3244
+ const result = await this.callEvaluator({
3245
+ evaluatorSlug,
3246
+ data,
3247
+ settings,
3248
+ name,
3249
+ traceId,
3250
+ spanId,
3251
+ asGuardrail
3252
+ });
3079
3253
  const duration = Date.now() - startTime;
3080
3254
  this.log(name != null ? name : evaluatorSlug, {
3081
3255
  index,
3082
3256
  data,
3083
3257
  status: result.status,
3084
- score: (_e = result.score) != null ? _e : void 0,
3085
- passed: (_f = result.passed) != null ? _f : void 0,
3086
- details: (_g = result.details) != null ? _g : void 0,
3087
- label: (_h = result.label) != null ? _h : void 0,
3258
+ score: (_f = result.score) != null ? _f : void 0,
3259
+ passed: (_g = result.passed) != null ? _g : void 0,
3260
+ details: (_h = result.details) != null ? _h : void 0,
3261
+ label: (_i = result.label) != null ? _i : void 0,
3088
3262
  duration,
3089
- cost: (_i = result.cost) == null ? void 0 : _i.amount,
3263
+ cost: (_j = result.cost) == null ? void 0 : _j.amount,
3090
3264
  target,
3091
3265
  metadata
3092
3266
  });
@@ -3121,15 +3295,228 @@ var Experiment = class _Experiment {
3121
3295
  throw wrappedError;
3122
3296
  }
3123
3297
  }
3298
+ /**
3299
+ * Call an evaluator and return its raw result
3300
+ */
3301
+ async callEvaluator({
3302
+ evaluatorSlug,
3303
+ data,
3304
+ settings,
3305
+ name,
3306
+ traceId,
3307
+ spanId,
3308
+ asGuardrail = false
3309
+ }) {
3310
+ const response = await fetch(
3311
+ `${this.endpoint}/api/evaluations/${evaluatorSlug}/evaluate`,
3312
+ {
3313
+ method: "POST",
3314
+ headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, {
3315
+ "Content-Type": "application/json"
3316
+ }, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
3317
+ body: JSON.stringify({
3318
+ trace_id: traceId != null ? traceId : null,
3319
+ span_id: spanId != null ? spanId : null,
3320
+ name: name != null ? name : evaluatorSlug,
3321
+ data,
3322
+ settings,
3323
+ as_guardrail: asGuardrail
3324
+ }),
3325
+ signal: AbortSignal.timeout(EVALUATOR_TIMEOUT_MS)
3326
+ }
3327
+ );
3328
+ if (!response.ok) {
3329
+ const text = await response.text();
3330
+ throw new EvaluatorError(evaluatorSlug, text);
3331
+ }
3332
+ return await response.json();
3333
+ }
3334
+ /**
3335
+ * Compare a row's targets and pick the best one
3336
+ *
3337
+ * Every target that recorded an output for the row is judged together in a
3338
+ * single call, and the winner comes back named with the target name you
3339
+ * registered. Call it once the row's withTarget() calls have all settled,
3340
+ * which under the usual Promise.all is right after the await.
3341
+ *
3342
+ * The verdict grades no single target, so it is recorded against the row.
3343
+ *
3344
+ * The row is named the way log() names it: inside a run() callback it is
3345
+ * inferred from the row being processed, and outside one it is required.
3346
+ *
3347
+ * A row with fewer than two outputs cannot be compared: it is recorded as
3348
+ * skipped, naming the targets that produced nothing, and the run carries on.
3349
+ * A judge that fails or cannot be reached comes back as an `error` verdict
3350
+ * for the same reason, and stays distinct from `inconclusive`, which is the
3351
+ * judge telling you something about your candidates. Naming a target that
3352
+ * produced no output is a different thing again, and throws, because a
3353
+ * two-way verdict read as the three-way one you asked for is worse than a
3354
+ * failure.
3355
+ *
3356
+ * @param options - How the judge should read the row, and which row when
3357
+ * it cannot be inferred
3358
+ * @returns The verdict, including the candidates it actually saw
3359
+ *
3360
+ * @example
3361
+ * ```typescript
3362
+ * await experiment.run(dataset, async ({ item }) => {
3363
+ * await Promise.all([
3364
+ * experiment.withTarget('gpt-5-mini', () => askGpt(item.question)),
3365
+ * experiment.withTarget('claude-sonnet-5', () => askClaude(item.question)),
3366
+ * ]);
3367
+ *
3368
+ * const verdict = await experiment.compare({ input: item.question });
3369
+ * console.log(verdict.winner);
3370
+ * });
3371
+ * ```
3372
+ */
3373
+ async compare(options = {}) {
3374
+ var _a, _b, _c, _d, _e, _f;
3375
+ const {
3376
+ name = DEFAULT_COMPARISON_NAME,
3377
+ targets,
3378
+ input,
3379
+ golden
3380
+ } = options;
3381
+ const index = this.resolveComparisonRow(options.index);
3382
+ const captured = (_a = this.capturedOutputs.get(index)) != null ? _a : /* @__PURE__ */ new Map();
3383
+ if (targets) {
3384
+ const missing = targets.filter((target) => !captured.has(target));
3385
+ if (missing.length > 0) {
3386
+ throw new ComparisonError(
3387
+ `Cannot compare row ${index}: no output was recorded for ${missing.map((target) => `'${target}'`).join(", ")}. Compare a row once every withTarget() call for it has settled.`,
3388
+ missing
3389
+ );
3390
+ }
3391
+ }
3392
+ const requested = targets ? new Set(targets) : null;
3393
+ const candidates = Array.from(this.targets.keys()).filter(
3394
+ (target) => captured.has(target) && (requested === null || requested.has(target))
3395
+ );
3396
+ if (candidates.length < 2) {
3397
+ const missing = Array.from(this.targets.keys()).filter(
3398
+ (target) => !captured.has(target) && (requested === null || requested.has(target))
3399
+ );
3400
+ const verdict2 = {
3401
+ status: "skipped",
3402
+ winner: null,
3403
+ reasoning: describeSkippedComparison({ candidates, missing }),
3404
+ candidates
3405
+ };
3406
+ this.recordComparison({ name, index, verdict: verdict2 });
3407
+ return verdict2;
3408
+ }
3409
+ const data = buildComparisonData({
3410
+ input,
3411
+ golden,
3412
+ candidates: buildComparisonCandidates(candidates, captured),
3413
+ index
3414
+ });
3415
+ const settings = buildComparisonSettings(options);
3416
+ const startTime = Date.now();
3417
+ let response;
3418
+ try {
3419
+ response = await this.callEvaluator({
3420
+ evaluatorSlug: COMPARISON_EVALUATOR_SLUG,
3421
+ data,
3422
+ settings,
3423
+ name,
3424
+ traceId: (_c = (_b = iterationContextStorage.getStore()) == null ? void 0 : _b.traceId) != null ? _c : this.getTraceIdFromContext(),
3425
+ spanId: this.getSpanIdFromContext()
3426
+ });
3427
+ } catch (error) {
3428
+ response = {
3429
+ status: "error",
3430
+ details: error instanceof Error ? error.message : String(error)
3431
+ };
3432
+ }
3433
+ const verdict = toComparisonVerdict({ response, candidates });
3434
+ this.recordComparison({
3435
+ name,
3436
+ index,
3437
+ verdict,
3438
+ score: (_d = response.score) != null ? _d : null,
3439
+ cost: (_f = (_e = response.cost) == null ? void 0 : _e.amount) != null ? _f : null,
3440
+ duration: Date.now() - startTime
3441
+ });
3442
+ return verdict;
3443
+ }
3444
+ /**
3445
+ * The row a comparison is about
3446
+ *
3447
+ * Inferred from the row being processed, the same way withTarget() and
3448
+ * log() infer theirs, so a comparison inside a run() callback never repeats
3449
+ * an index the SDK already has. It reads that row from the iteration's own
3450
+ * context, which is what keeps a run of many rows at once from handing one
3451
+ * row's comparison the row a neighbour happens to be on.
3452
+ *
3453
+ * What it deliberately does not do is fall back to a row: judging row 0
3454
+ * because no row was named would hand back a confident verdict about
3455
+ * candidates the caller never asked about.
3456
+ */
3457
+ resolveComparisonRow(index) {
3458
+ var _a;
3459
+ const resolved = index != null ? index : (_a = iterationContextStorage.getStore()) == null ? void 0 : _a.index;
3460
+ if (resolved === void 0) {
3461
+ throw new ComparisonError(
3462
+ "Cannot compare: no row was given and none could be inferred. Pass index explicitly when comparing outside a run() iteration."
3463
+ );
3464
+ }
3465
+ return resolved;
3466
+ }
3467
+ /**
3468
+ * Record a comparison verdict against the row
3469
+ *
3470
+ * The verdict the caller is handed is the only input, so the row can never
3471
+ * say one thing while the return value says another.
3472
+ *
3473
+ * Deliberately not routed through log(): a comparison grades no single
3474
+ * target, so it must not pick one up from an ambient withTarget() context,
3475
+ * and it is recorded under the judge's own evaluator id so the results page
3476
+ * can tell it apart from a hand-logged metric.
3477
+ */
3478
+ recordComparison({
3479
+ name,
3480
+ index,
3481
+ verdict,
3482
+ score = null,
3483
+ cost = null,
3484
+ duration = null
3485
+ }) {
3486
+ var _a, _b;
3487
+ const status = comparisonEntryStatus(verdict.status);
3488
+ this.pushEvaluation({
3489
+ name,
3490
+ evaluator: COMPARISON_EVALUATOR_SLUG,
3491
+ trace_id: (_b = (_a = iterationContextStorage.getStore()) == null ? void 0 : _a.traceId) != null ? _b : this.getTraceIdFromContext(),
3492
+ status,
3493
+ // The results page keys a comparison column off this candidate list.
3494
+ data: {
3495
+ candidates: verdict.candidates.map((candidate) => ({ id: candidate }))
3496
+ },
3497
+ // A row that established nothing carries no score: 0.5 would read as the
3498
+ // tie it is not, and 1.0 as a win for a winner it does not have.
3499
+ score: status === "processed" ? score : null,
3500
+ passed: null,
3501
+ details: verdict.reasoning,
3502
+ index,
3503
+ label: comparisonEntryLabel(verdict),
3504
+ cost,
3505
+ duration,
3506
+ error_type: null,
3507
+ traceback: null,
3508
+ target_id: null
3509
+ });
3510
+ }
3124
3511
  async withTarget(targetName, metadataOrCallback, maybeCallback) {
3125
- var _a, _b, _c;
3512
+ var _a, _b;
3126
3513
  const metadata = typeof metadataOrCallback === "function" ? null : metadataOrCallback;
3127
3514
  const callback = typeof metadataOrCallback === "function" ? metadataOrCallback : maybeCallback;
3128
3515
  if (!this.evaluationUsesTargets) {
3129
3516
  this.evaluationUsesTargets = true;
3130
3517
  }
3131
3518
  const iterationContext = iterationContextStorage.getStore();
3132
- const index = (_b = (_a = iterationContext == null ? void 0 : iterationContext.index) != null ? _a : this.currentIndex) != null ? _b : 0;
3519
+ const index = (_a = iterationContext == null ? void 0 : iterationContext.index) != null ? _a : 0;
3133
3520
  const currentItem = iterationContext == null ? void 0 : iterationContext.item;
3134
3521
  this.iterationUsedWithTarget.set(index, true);
3135
3522
  this.registerTarget(targetName, metadata != null ? metadata : void 0);
@@ -3195,7 +3582,7 @@ var Experiment = class _Experiment {
3195
3582
  index,
3196
3583
  entry: this.serializeItem(currentItem),
3197
3584
  duration,
3198
- error: (_c = callbackError == null ? void 0 : callbackError.message) != null ? _c : null,
3585
+ error: (_b = callbackError == null ? void 0 : callbackError.message) != null ? _b : null,
3199
3586
  trace_id: traceId || null,
3200
3587
  // null if no tracer configured (no-op)
3201
3588
  target_id: targetName,
@@ -3208,6 +3595,12 @@ var Experiment = class _Experiment {
3208
3595
  cost: entry.cost,
3209
3596
  target_id: entry.target_id
3210
3597
  });
3598
+ this.captureTargetOutput({
3599
+ index,
3600
+ targetName,
3601
+ output: renderTargetOutput(result),
3602
+ durationMs: duration
3603
+ });
3211
3604
  this.scheduleSend();
3212
3605
  return {
3213
3606
  result,
@@ -3216,6 +3609,35 @@ var Experiment = class _Experiment {
3216
3609
  spanId
3217
3610
  };
3218
3611
  }
3612
+ /**
3613
+ * Keep a target's output for the row so compare() can reach it later
3614
+ *
3615
+ * The batch this output also went into is flushed on a timer and cleared, so
3616
+ * a comparison that read its candidates from there would find them missing
3617
+ * whenever the flush landed first. A target that produced nothing is not
3618
+ * captured at all: it has no output to judge.
3619
+ */
3620
+ captureTargetOutput({
3621
+ index,
3622
+ targetName,
3623
+ output,
3624
+ durationMs
3625
+ }) {
3626
+ if (output === "") {
3627
+ return;
3628
+ }
3629
+ let row = this.capturedOutputs.get(index);
3630
+ if (!row) {
3631
+ row = /* @__PURE__ */ new Map();
3632
+ this.capturedOutputs.set(index, row);
3633
+ }
3634
+ row.set(targetName, { output, durationMs });
3635
+ while (this.capturedOutputs.size > MAX_COMPARISON_ROWS_RETAINED) {
3636
+ const oldest = this.capturedOutputs.keys().next();
3637
+ if (oldest.done) break;
3638
+ this.capturedOutputs.delete(oldest.value);
3639
+ }
3640
+ }
3219
3641
  /**
3220
3642
  * Register a target for multi-target comparison
3221
3643
  */
@@ -3428,7 +3850,7 @@ var Experiment = class _Experiment {
3428
3850
  method: "POST",
3429
3851
  headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, {
3430
3852
  "Content-Type": "application/json"
3431
- }, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
3853
+ }, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })),
3432
3854
  body: JSON.stringify(body)
3433
3855
  }).then((response) => {
3434
3856
  if (!response.ok) {
@@ -3554,12 +3976,19 @@ var ExperimentsApiService = class {
3554
3976
  if (result.error) this.handleApiError(operation, result.error);
3555
3977
  return result.data;
3556
3978
  }
3557
- async startRun(slug) {
3979
+ /**
3980
+ * Start a saved experiment by slug.
3981
+ *
3982
+ * The body stays off the wire entirely when no overrides are given, so the
3983
+ * run uses the inputs the experiment is configured with.
3984
+ */
3985
+ async startRun(slug, options = {}) {
3986
+ const body = toRunStartRequest({ parameters: options.parameters });
3558
3987
  const { data, error } = await this.apiClient.POST(
3559
3988
  "/api/experiments/{slug}/run",
3560
- {
3989
+ _chunkCLTKABMOjs.__spreadValues.call(void 0, {
3561
3990
  params: { path: { slug } }
3562
- }
3991
+ }, body !== void 0 ? { body } : {})
3563
3992
  );
3564
3993
  if (error) this.handleApiError(`start experiment run for "${slug}"`, error);
3565
3994
  return data;
@@ -4308,7 +4737,7 @@ var EvaluationsFacade = class {
4308
4737
  method: "POST",
4309
4738
  headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, {
4310
4739
  "Content-Type": "application/json"
4311
- }, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: _chunkCLTKABMOjs.__privateGet.call(void 0, this, _apiKey) })),
4740
+ }, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: _chunkCLTKABMOjs.__privateGet.call(void 0, this, _apiKey) })),
4312
4741
  body: JSON.stringify(requestBody)
4313
4742
  });
4314
4743
  if (!response.ok) {
@@ -4583,12 +5012,16 @@ var SuitesApiService = class {
4583
5012
  if (error) this.handleApiError(`duplicate suite "${id}"`, error);
4584
5013
  return data;
4585
5014
  }
4586
- async run(id, idempotencyKey) {
5015
+ async run(id, optionsOrIdempotencyKey) {
5016
+ var _a;
5017
+ const options = typeof optionsOrIdempotencyKey === "string" ? { idempotencyKey: optionsOrIdempotencyKey } : optionsOrIdempotencyKey != null ? optionsOrIdempotencyKey : {};
5018
+ const body = {
5019
+ idempotencyKey: (_a = options.idempotencyKey) != null ? _a : `cli-${Date.now()}-${Math.random().toString(36).slice(2)}`
5020
+ };
5021
+ if (options.parameters !== void 0) body.parameters = options.parameters;
4587
5022
  const { data, error } = await this.apiClient.POST("/api/suites/{id}/run", {
4588
5023
  params: { path: { id } },
4589
- body: {
4590
- idempotencyKey: idempotencyKey != null ? idempotencyKey : `cli-${Date.now()}-${Math.random().toString(36).slice(2)}`
4591
- }
5024
+ body
4592
5025
  });
4593
5026
  if (error) this.handleApiError(`run suite "${id}"`, error);
4594
5027
  return data;
@@ -4614,7 +5047,7 @@ var WorkflowsApiError = class extends Error {
4614
5047
  var WorkflowsApiService = class {
4615
5048
  constructor(config) {
4616
5049
  var _a;
4617
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5050
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
4618
5051
  this.apiClient = (_a = config == null ? void 0 : config.langwatchApiClient) != null ? _a : createLangWatchApiClient(void 0, this.endpoint);
4619
5052
  this.experimentsApiService = new ExperimentsApiService({
4620
5053
  langwatchApiClient: this.apiClient
@@ -5174,12 +5607,12 @@ var MonitorsApiService = class {
5174
5607
  constructor(config) {
5175
5608
  var _a, _b, _c;
5176
5609
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
5177
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5610
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5178
5611
  }
5179
5612
  async request(path2, options) {
5180
5613
  var _a, _b;
5181
5614
  const response = await fetch(`${this.endpoint}${path2}`, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, options), {
5182
- headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })), {
5615
+ headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })), {
5183
5616
  "Content-Type": "application/json"
5184
5617
  }), options == null ? void 0 : options.headers)
5185
5618
  }));
@@ -5249,12 +5682,12 @@ var SecretsApiService = class {
5249
5682
  constructor(config) {
5250
5683
  var _a, _b, _c;
5251
5684
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
5252
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5685
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5253
5686
  }
5254
5687
  async request(path2, options) {
5255
5688
  var _a, _b;
5256
5689
  const response = await fetch(`${this.endpoint}${path2}`, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, options), {
5257
- headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunkGOGMRTV5js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })), {
5690
+ headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, _chunk5ERLGHP2js.buildAuthHeaders.call(void 0, { apiKey: this.apiKey })), {
5258
5691
  "Content-Type": "application/json"
5259
5692
  }), options == null ? void 0 : options.headers)
5260
5693
  }));
@@ -5384,7 +5817,7 @@ var VirtualKeysApiError = class extends Error {
5384
5817
  var VirtualKeysApiService = class {
5385
5818
  constructor(config) {
5386
5819
  var _a, _b, _c, _d;
5387
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5820
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5388
5821
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
5389
5822
  this.projectId = (_d = config == null ? void 0 : config.projectId) != null ? _d : process.env.LANGWATCH_PROJECT_ID;
5390
5823
  }
@@ -5612,7 +6045,7 @@ var GatewayBudgetsApiError = class extends Error {
5612
6045
  var GatewayBudgetsApiService = class {
5613
6046
  constructor(config) {
5614
6047
  var _a, _b, _c, _d;
5615
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
6048
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5616
6049
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
5617
6050
  this.projectId = (_d = config == null ? void 0 : config.projectId) != null ? _d : process.env.LANGWATCH_PROJECT_ID;
5618
6051
  }
@@ -5823,6 +6256,43 @@ var GatewayBudgetsApiService = class {
5823
6256
  };
5824
6257
 
5825
6258
  // src/client-sdk/services/spend-events/spend-events-api.service.ts
6259
+ var FILTER_PARAMS = [
6260
+ ["projectId", "project_id"],
6261
+ ["teamId", "team_id"],
6262
+ ["externalId", "external_id"],
6263
+ ["virtualKeyId", "virtual_key_id"],
6264
+ ["endUserId", "end_user_id"],
6265
+ ["principalUserId", "principal_user_id"],
6266
+ ["model", "model"],
6267
+ ["providerKey", "provider_key"],
6268
+ ["requestType", "request_type"],
6269
+ ["label", "label"]
6270
+ ];
6271
+ function appendSpendFilters({
6272
+ params,
6273
+ filters
6274
+ }) {
6275
+ var _a;
6276
+ for (const [field, name] of FILTER_PARAMS) {
6277
+ const value = filters[field];
6278
+ if (value === void 0) continue;
6279
+ for (const one of Array.isArray(value) ? value : [value]) {
6280
+ params.append(name, one);
6281
+ }
6282
+ }
6283
+ for (const [key, value] of Object.entries((_a = filters.metadata) != null ? _a : {})) {
6284
+ if (key.includes(":")) {
6285
+ throw new SpendEventsApiError(
6286
+ `A metadata key cannot contain a colon: ${key}`,
6287
+ "build spend filters"
6288
+ );
6289
+ }
6290
+ for (const one of Array.isArray(value) ? value : [value]) {
6291
+ params.append("metadata", `${key}:${one}`);
6292
+ }
6293
+ }
6294
+ if (filters.status) params.set("status", filters.status);
6295
+ }
5826
6296
  var SpendEventsApiError = class extends Error {
5827
6297
  constructor(message, operation, originalError) {
5828
6298
  super(message);
@@ -5834,7 +6304,7 @@ var SpendEventsApiError = class extends Error {
5834
6304
  var SpendEventsApiService = class {
5835
6305
  constructor(config) {
5836
6306
  var _a, _b, _c;
5837
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
6307
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
5838
6308
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
5839
6309
  }
5840
6310
  async request(operation, path2, init) {
@@ -5884,11 +6354,7 @@ var SpendEventsApiService = class {
5884
6354
  params.set("to", String(options.to));
5885
6355
  if (options.cursor) params.set("cursor", options.cursor);
5886
6356
  if (options.limit !== void 0) params.set("limit", String(options.limit));
5887
- if (options.virtualKeyId) params.set("virtual_key_id", options.virtualKeyId);
5888
- if (options.endUserId) params.set("end_user_id", options.endUserId);
5889
- if (options.projectId) params.set("project_id", options.projectId);
5890
- if (options.model) params.set("model", options.model);
5891
- if (options.status) params.set("status", options.status);
6357
+ appendSpendFilters({ params, filters: options });
5892
6358
  const qs = params.toString() !== "" ? `?${params.toString()}` : "";
5893
6359
  return await this.request(
5894
6360
  "list spend events",
@@ -5949,12 +6415,14 @@ var SpendEventsApiService = class {
5949
6415
  */
5950
6416
  async summariesPage(options) {
5951
6417
  const params = new URLSearchParams();
5952
- params.set("group_by", options.groupBy);
6418
+ const groupBy = Array.isArray(options.groupBy) ? options.groupBy : [options.groupBy];
6419
+ params.set("group_by", groupBy.join(","));
5953
6420
  params.set("from", String(options.from));
5954
6421
  params.set("to", String(options.to));
5955
- if (options.projectId) params.set("project_id", options.projectId);
5956
- if (options.virtualKeyId)
5957
- params.set("virtual_key_id", options.virtualKeyId);
6422
+ if (options.bucket) params.set("bucket", options.bucket);
6423
+ if (options.timezone) params.set("timezone", options.timezone);
6424
+ if (options.allowUnstable) params.set("allow_unstable", "true");
6425
+ appendSpendFilters({ params, filters: options });
5958
6426
  if (options.cursor) params.set("cursor", options.cursor);
5959
6427
  if (options.limit !== void 0) params.set("limit", String(options.limit));
5960
6428
  return await this.request(
@@ -6053,7 +6521,7 @@ var WebhooksApiError = class extends Error {
6053
6521
  var WebhooksApiService = class {
6054
6522
  constructor(config) {
6055
6523
  var _a, _b, _c;
6056
- this.endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
6524
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
6057
6525
  this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
6058
6526
  }
6059
6527
  async request(operation, path2, init) {
@@ -6240,11 +6708,11 @@ var WebhooksApiService = class {
6240
6708
  */
6241
6709
  async eventsPage(options) {
6242
6710
  const params = new URLSearchParams();
6243
- if (options == null ? void 0 : options.type) params.set("type", options.type);
6244
- if ((options == null ? void 0 : options.from) !== void 0) params.set("from", String(options.from));
6245
- if ((options == null ? void 0 : options.to) !== void 0) params.set("to", String(options.to));
6246
- if (options == null ? void 0 : options.cursor) params.set("cursor", options.cursor);
6247
- if ((options == null ? void 0 : options.limit) !== void 0) params.set("limit", String(options.limit));
6711
+ if (options.type) params.set("type", options.type);
6712
+ params.set("from", String(options.from));
6713
+ params.set("to", String(options.to));
6714
+ if (options.cursor) params.set("cursor", options.cursor);
6715
+ if (options.limit !== void 0) params.set("limit", String(options.limit));
6248
6716
  const qs = params.toString() !== "" ? `?${params.toString()}` : "";
6249
6717
  const { data, next_cursor } = await this.request("list emitted events", `/api/webhooks/v1/events${qs}`);
6250
6718
  return { data, next_cursor: next_cursor != null ? next_cursor : null };
@@ -6256,7 +6724,7 @@ var WebhooksApiService = class {
6256
6724
  iterEvents(options) {
6257
6725
  return _chunkCLTKABMOjs.__asyncGenerator.call(void 0, this, null, function* () {
6258
6726
  const pages = walkCursorPages({
6259
- startCursor: options == null ? void 0 : options.cursor,
6727
+ startCursor: options.cursor,
6260
6728
  nextCursorOf: (page) => page.next_cursor,
6261
6729
  onEndlessWalk: (reason) => new WebhooksApiError(
6262
6730
  `Failed to list emitted events: ${reason}.`,
@@ -6266,7 +6734,7 @@ var WebhooksApiService = class {
6266
6734
  var _a;
6267
6735
  return this.eventsPage(_chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, options), {
6268
6736
  cursor,
6269
- limit: (_a = options == null ? void 0 : options.limit) != null ? _a : CURSOR_WALK_PAGE_SIZE
6737
+ limit: (_a = options.limit) != null ? _a : CURSOR_WALK_PAGE_SIZE
6270
6738
  }));
6271
6739
  }
6272
6740
  });
@@ -6302,6 +6770,255 @@ var WebhooksApiService = class {
6302
6770
  }
6303
6771
  };
6304
6772
 
6773
+ // src/client-sdk/services/_shared/management-request.ts
6774
+ var MANAGEMENT_REQUEST_TIMEOUT_MS = 3e4;
6775
+ var resolveManagementToken = ({
6776
+ apiKey
6777
+ }) => {
6778
+ var _a;
6779
+ const token = (_a = apiKey != null ? apiKey : scopedApiKey()) != null ? _a : process.env.LANGWATCH_API_KEY;
6780
+ if (!token) {
6781
+ throw new Error(
6782
+ "No API key configured. Set LANGWATCH_API_KEY, run `langwatch login`, or pass apiKey."
6783
+ );
6784
+ }
6785
+ return token;
6786
+ };
6787
+ var buildQueryString = (query) => {
6788
+ if (!query) return "";
6789
+ const params = new URLSearchParams();
6790
+ for (const [key, value] of Object.entries(query)) {
6791
+ if (value === void 0) continue;
6792
+ params.set(key, String(value));
6793
+ }
6794
+ const rendered = params.toString();
6795
+ return rendered ? `?${rendered}` : "";
6796
+ };
6797
+ var createManagementRequest = ({
6798
+ endpoint,
6799
+ token,
6800
+ errorFactory
6801
+ }) => {
6802
+ return async ({
6803
+ operation,
6804
+ path: path2,
6805
+ method,
6806
+ body,
6807
+ query,
6808
+ signal
6809
+ }) => {
6810
+ const response = await fetch(
6811
+ `${endpoint}${path2}${buildQueryString(query)}`,
6812
+ _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, method ? { method } : {}), {
6813
+ headers: {
6814
+ Authorization: `Bearer ${token}`,
6815
+ "Content-Type": "application/json"
6816
+ }
6817
+ }), body !== void 0 ? { body: JSON.stringify(body) } : {}), {
6818
+ signal: signal != null ? signal : AbortSignal.timeout(MANAGEMENT_REQUEST_TIMEOUT_MS)
6819
+ })
6820
+ );
6821
+ if (!response.ok) {
6822
+ const rawBody = await response.text();
6823
+ let parsedBody;
6824
+ try {
6825
+ parsedBody = JSON.parse(rawBody);
6826
+ } catch (e) {
6827
+ parsedBody = rawBody;
6828
+ }
6829
+ const message = formatApiErrorForOperation({
6830
+ operation,
6831
+ error: parsedBody,
6832
+ options: { status: response.status }
6833
+ });
6834
+ throwIfHandledError({
6835
+ operation,
6836
+ error: parsedBody,
6837
+ status: response.status,
6838
+ message
6839
+ });
6840
+ throw errorFactory({ message, operation, body: parsedBody });
6841
+ }
6842
+ if (response.status === 204) return void 0;
6843
+ return await response.json();
6844
+ };
6845
+ };
6846
+
6847
+ // src/client-sdk/services/teams/teams-api.service.ts
6848
+ var TeamsApiError = class extends Error {
6849
+ constructor(message, operation, originalError) {
6850
+ super(message);
6851
+ this.operation = operation;
6852
+ this.originalError = originalError;
6853
+ this.name = "TeamsApiError";
6854
+ }
6855
+ };
6856
+ var _request;
6857
+ var TeamsApiService = class {
6858
+ constructor(config) {
6859
+ _chunkCLTKABMOjs.__privateAdd.call(void 0, this, _request);
6860
+ _chunkCLTKABMOjs.__privateSet.call(void 0, this, _request, createManagementRequest({
6861
+ endpoint: _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint),
6862
+ token: resolveManagementToken({ apiKey: config == null ? void 0 : config.apiKey }),
6863
+ errorFactory: ({ message, operation, body }) => new TeamsApiError(message, operation, body)
6864
+ }));
6865
+ }
6866
+ async list(options = {}) {
6867
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6868
+ operation: "list teams",
6869
+ path: "/api/teams",
6870
+ query: _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, options)
6871
+ });
6872
+ }
6873
+ async get(id) {
6874
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6875
+ operation: `fetch team "${id}"`,
6876
+ path: `/api/teams/${encodeURIComponent(id)}`
6877
+ });
6878
+ }
6879
+ async create(input) {
6880
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6881
+ operation: "create team",
6882
+ path: "/api/teams",
6883
+ method: "POST",
6884
+ body: input
6885
+ });
6886
+ }
6887
+ async update({
6888
+ id,
6889
+ input
6890
+ }) {
6891
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6892
+ operation: `update team "${id}"`,
6893
+ path: `/api/teams/${encodeURIComponent(id)}`,
6894
+ method: "PATCH",
6895
+ body: input
6896
+ });
6897
+ }
6898
+ async archive(id) {
6899
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6900
+ operation: `archive team "${id}"`,
6901
+ path: `/api/teams/${encodeURIComponent(id)}`,
6902
+ method: "DELETE"
6903
+ });
6904
+ }
6905
+ async listMembers(teamId) {
6906
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6907
+ operation: `list members of team "${teamId}"`,
6908
+ path: `/api/teams/${encodeURIComponent(teamId)}/members`
6909
+ });
6910
+ }
6911
+ async addMember({
6912
+ teamId,
6913
+ input
6914
+ }) {
6915
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6916
+ operation: `add a member to team "${teamId}"`,
6917
+ path: `/api/teams/${encodeURIComponent(teamId)}/members`,
6918
+ method: "POST",
6919
+ body: input
6920
+ });
6921
+ }
6922
+ async removeMember({
6923
+ teamId,
6924
+ userId
6925
+ }) {
6926
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _request).call(this, {
6927
+ operation: `remove member "${userId}" from team "${teamId}"`,
6928
+ path: `/api/teams/${encodeURIComponent(teamId)}/members/${encodeURIComponent(userId)}`,
6929
+ method: "DELETE"
6930
+ });
6931
+ }
6932
+ };
6933
+ _request = new WeakMap();
6934
+
6935
+ // src/client-sdk/services/projects/projects-api.service.ts
6936
+ var ProjectsApiError = class extends Error {
6937
+ constructor(message, operation, originalError) {
6938
+ super(message);
6939
+ this.operation = operation;
6940
+ this.originalError = originalError;
6941
+ this.name = "ProjectsApiError";
6942
+ }
6943
+ };
6944
+ var ProjectsApiService = class {
6945
+ constructor(config) {
6946
+ var _a, _b, _c;
6947
+ this.endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, config == null ? void 0 : config.endpoint);
6948
+ this.apiKey = (_c = (_b = (_a = config == null ? void 0 : config.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
6949
+ }
6950
+ headers() {
6951
+ return {
6952
+ Authorization: `Bearer ${this.apiKey}`,
6953
+ "Content-Type": "application/json"
6954
+ };
6955
+ }
6956
+ async request(operation, path2, init) {
6957
+ var _a;
6958
+ const response = await fetch(`${this.endpoint}${path2}`, _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, init), {
6959
+ headers: _chunkCLTKABMOjs.__spreadValues.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, this.headers()), (_a = init == null ? void 0 : init.headers) != null ? _a : {})
6960
+ }));
6961
+ if (!response.ok) {
6962
+ let parsedBody;
6963
+ try {
6964
+ parsedBody = await response.json();
6965
+ } catch (e) {
6966
+ parsedBody = await response.text();
6967
+ }
6968
+ const message = formatApiErrorForOperation({
6969
+ operation,
6970
+ error: parsedBody,
6971
+ options: { status: response.status }
6972
+ });
6973
+ throwIfHandledError({
6974
+ operation,
6975
+ error: parsedBody,
6976
+ status: response.status,
6977
+ message
6978
+ });
6979
+ throw new ProjectsApiError(message, operation, parsedBody);
6980
+ }
6981
+ return await response.json();
6982
+ }
6983
+ async list(options) {
6984
+ const params = new URLSearchParams();
6985
+ if (options == null ? void 0 : options.page) params.set("page", String(options.page));
6986
+ if (options == null ? void 0 : options.limit) params.set("limit", String(options.limit));
6987
+ const qs = params.toString();
6988
+ return this.request(
6989
+ "list projects",
6990
+ `/api/projects${qs ? `?${qs}` : ""}`
6991
+ );
6992
+ }
6993
+ async get(id) {
6994
+ return this.request(
6995
+ `get project "${id}"`,
6996
+ `/api/projects/${encodeURIComponent(id)}`
6997
+ );
6998
+ }
6999
+ async create(input) {
7000
+ return this.request(
7001
+ "create project",
7002
+ "/api/projects",
7003
+ { method: "POST", body: JSON.stringify(input) }
7004
+ );
7005
+ }
7006
+ async update(id, input) {
7007
+ return this.request(
7008
+ `update project "${id}"`,
7009
+ `/api/projects/${encodeURIComponent(id)}`,
7010
+ { method: "PATCH", body: JSON.stringify(input) }
7011
+ );
7012
+ }
7013
+ async archive(id) {
7014
+ return this.request(
7015
+ `archive project "${id}"`,
7016
+ `/api/projects/${encodeURIComponent(id)}`,
7017
+ { method: "DELETE" }
7018
+ );
7019
+ }
7020
+ };
7021
+
6305
7022
  // src/client-sdk/services/traces/types.ts
6306
7023
  var TracesError = class extends Error {
6307
7024
  constructor(message, operation, originalError) {
@@ -6313,7 +7030,7 @@ var TracesError = class extends Error {
6313
7030
  };
6314
7031
 
6315
7032
  // src/client-sdk/services/traces/tracing/tracer.ts
6316
- var tracer3 = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunkGOGMRTV5js.LANGWATCH_SDK_NAME_CLIENT}.traces`, _chunkGOGMRTV5js.LANGWATCH_SDK_VERSION);
7033
+ var tracer3 = _chunkK6KPNTQOjs.getLangWatchTracer.call(void 0, `${_chunk5ERLGHP2js.LANGWATCH_SDK_NAME_CLIENT}.traces`, _chunk5ERLGHP2js.LANGWATCH_SDK_VERSION);
6317
7034
 
6318
7035
  // src/client-sdk/services/traces/service.ts
6319
7036
  var TracesService = class {
@@ -6377,13 +7094,15 @@ var TracesFacade = class {
6377
7094
  _service = new WeakMap();
6378
7095
 
6379
7096
  // src/client-sdk/index.ts
6380
- var _LangWatch_instances, createInternalConfig_fn;
7097
+ var _teams, _projects, _LangWatch_instances, managementConfig_fn, createInternalConfig_fn;
6381
7098
  var LangWatch = class {
6382
7099
  constructor(options = {}) {
6383
7100
  _chunkCLTKABMOjs.__privateAdd.call(void 0, this, _LangWatch_instances);
7101
+ _chunkCLTKABMOjs.__privateAdd.call(void 0, this, _teams);
7102
+ _chunkCLTKABMOjs.__privateAdd.call(void 0, this, _projects);
6384
7103
  var _a, _b, _c;
6385
7104
  const apiKey = (_c = (_b = (_a = options.apiKey) != null ? _a : scopedApiKey()) != null ? _b : process.env.LANGWATCH_API_KEY) != null ? _c : "";
6386
- const endpoint = _chunkKUJACQJ2js.resolveEndpoint.call(void 0, options.endpoint);
7105
+ const endpoint = _chunkXIN5LXHQjs.resolveEndpoint.call(void 0, options.endpoint);
6387
7106
  this.config = _chunkCLTKABMOjs.__privateMethod.call(void 0, this, _LangWatch_instances, createInternalConfig_fn).call(this, {
6388
7107
  apiKey,
6389
7108
  endpoint,
@@ -6433,8 +7152,43 @@ var LangWatch = class {
6433
7152
  get apiClient() {
6434
7153
  return this.config.langwatchApiClient;
6435
7154
  }
7155
+ /**
7156
+ * Teams, which group projects and the members who can reach them. These
7157
+ * routes want an organization API key.
7158
+ *
7159
+ * Built on first use rather than in the constructor: the management
7160
+ * families resolve their credential when constructed and refuse an empty
7161
+ * one, so building this eagerly would make `new LangWatch()` throw for
7162
+ * every caller that never touches a team.
7163
+ */
7164
+ get teams() {
7165
+ var _a;
7166
+ (_a = _chunkCLTKABMOjs.__privateGet.call(void 0, this, _teams)) != null ? _a : _chunkCLTKABMOjs.__privateSet.call(void 0, this, _teams, new TeamsApiService(_chunkCLTKABMOjs.__privateMethod.call(void 0, this, _LangWatch_instances, managementConfig_fn).call(this)));
7167
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _teams);
7168
+ }
7169
+ /**
7170
+ * Projects, including provisioning one with its own service API key. These
7171
+ * routes want an organization API key.
7172
+ */
7173
+ get projects() {
7174
+ var _a;
7175
+ (_a = _chunkCLTKABMOjs.__privateGet.call(void 0, this, _projects)) != null ? _a : _chunkCLTKABMOjs.__privateSet.call(void 0, this, _projects, new ProjectsApiService(_chunkCLTKABMOjs.__privateMethod.call(void 0, this, _LangWatch_instances, managementConfig_fn).call(this)));
7176
+ return _chunkCLTKABMOjs.__privateGet.call(void 0, this, _projects);
7177
+ }
6436
7178
  };
7179
+ _teams = new WeakMap();
7180
+ _projects = new WeakMap();
6437
7181
  _LangWatch_instances = new WeakSet();
7182
+ /**
7183
+ * What the management families are constructed with. An empty key is left
7184
+ * off entirely so they resolve the ambient credential instead of
7185
+ * authenticating with a blank bearer token.
7186
+ */
7187
+ managementConfig_fn = function() {
7188
+ return _chunkCLTKABMOjs.__spreadProps.call(void 0, _chunkCLTKABMOjs.__spreadValues.call(void 0, {}, this.config.apiKey ? { apiKey: this.config.apiKey } : {}), {
7189
+ endpoint: this.config.endpoint
7190
+ });
7191
+ };
6438
7192
  createInternalConfig_fn = function({
6439
7193
  apiKey,
6440
7194
  endpoint,
@@ -6583,5 +7337,10 @@ var logger = {
6583
7337
 
6584
7338
 
6585
7339
 
6586
- exports.DatasetApiError = DatasetApiError; exports.DatasetError = DatasetError; exports.DatasetNotFoundError = DatasetNotFoundError; exports.DatasetPlanLimitError = DatasetPlanLimitError; exports.DatasetValidationError = DatasetValidationError; exports.DatasetsFacade = DatasetsFacade; exports.EvaluationError = EvaluationError; exports.EvaluationsApiError = EvaluationsApiError; exports.EvaluationsFacade = EvaluationsFacade; exports.EvaluatorCallError = EvaluatorCallError; exports.EvaluatorError = EvaluatorError; exports.EvaluatorNotFoundError = EvaluatorNotFoundError; exports.EvaluatorsApiError = EvaluatorsApiError; exports.EvaluatorsApiService = EvaluatorsApiService; exports.Experiment = Experiment; exports.ExperimentApiError = ExperimentApiError; exports.ExperimentError = ExperimentError; exports.ExperimentInitError = ExperimentInitError; exports.ExperimentsFacade = ExperimentsFacade; exports.FetchPolicy = FetchPolicy; exports.FilterableBatchSpanProcessor = _chunkZTOXEWNXjs.FilterableBatchSpanProcessor; exports.GatewayBudgetsApiError = GatewayBudgetsApiError; exports.GatewayBudgetsApiService = GatewayBudgetsApiService; exports.IDEMPOTENCY_KEY_HEADER = IDEMPOTENCY_KEY_HEADER; exports.IDEMPOTENT_REPLAY_HEADER = IDEMPOTENT_REPLAY_HEADER; exports.LangWatch = LangWatch; exports.LangWatchApiError = LangWatchApiError; exports.LangWatchExporter = _chunkGOGMRTV5js.LangWatchTraceExporter; exports.LangWatchHandledError = LangWatchHandledError; exports.SpendEventsApiError = SpendEventsApiError; exports.SpendEventsApiService = SpendEventsApiService; exports.TargetMetadataConflictError = TargetMetadataConflictError; exports.VirtualKeysApiError = VirtualKeysApiError; exports.VirtualKeysApiService = VirtualKeysApiService; exports.WEBHOOK_DELIVERY_ID_HEADER = WEBHOOK_DELIVERY_ID_HEADER; exports.WEBHOOK_EVENT_ID_HEADER = WEBHOOK_EVENT_ID_HEADER; exports.WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS = WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS; exports.WEBHOOK_SIGNATURE_HEADER = WEBHOOK_SIGNATURE_HEADER; exports.WebhookSignatureVerificationError = WebhookSignatureVerificationError; exports.WebhooksApiError = WebhooksApiError; exports.WebhooksApiService = WebhooksApiService; exports.attributes = _chunkCLTKABMOjs.attributes_exports; exports.getLangWatchLogger = _chunkGOGMRTV5js.getLangWatchLogger; exports.getLangWatchTracer = _chunkK6KPNTQOjs.getLangWatchTracer; exports.isLangWatchHandledError = isLangWatchHandledError; exports.logger = logger; exports.verifyWebhookSignature = verifyWebhookSignature;
7340
+
7341
+
7342
+
7343
+
7344
+
7345
+ exports.ComparisonError = ComparisonError; exports.DatasetApiError = DatasetApiError; exports.DatasetError = DatasetError; exports.DatasetNotFoundError = DatasetNotFoundError; exports.DatasetPlanLimitError = DatasetPlanLimitError; exports.DatasetValidationError = DatasetValidationError; exports.DatasetsFacade = DatasetsFacade; exports.EvaluationError = EvaluationError; exports.EvaluationsApiError = EvaluationsApiError; exports.EvaluationsFacade = EvaluationsFacade; exports.EvaluatorCallError = EvaluatorCallError; exports.EvaluatorError = EvaluatorError; exports.EvaluatorNotFoundError = EvaluatorNotFoundError; exports.EvaluatorsApiError = EvaluatorsApiError; exports.EvaluatorsApiService = EvaluatorsApiService; exports.Experiment = Experiment; exports.ExperimentApiError = ExperimentApiError; exports.ExperimentError = ExperimentError; exports.ExperimentInitError = ExperimentInitError; exports.ExperimentsFacade = ExperimentsFacade; exports.FetchPolicy = FetchPolicy; exports.FilterableBatchSpanProcessor = _chunkZTOXEWNXjs.FilterableBatchSpanProcessor; exports.GatewayBudgetsApiError = GatewayBudgetsApiError; exports.GatewayBudgetsApiService = GatewayBudgetsApiService; exports.IDEMPOTENCY_KEY_HEADER = IDEMPOTENCY_KEY_HEADER; exports.IDEMPOTENT_REPLAY_HEADER = IDEMPOTENT_REPLAY_HEADER; exports.LangWatch = LangWatch; exports.LangWatchApiError = LangWatchApiError; exports.LangWatchExporter = _chunk5ERLGHP2js.LangWatchTraceExporter; exports.LangWatchHandledError = LangWatchHandledError; exports.ProjectsApiError = ProjectsApiError; exports.ProjectsApiService = ProjectsApiService; exports.SpendEventsApiError = SpendEventsApiError; exports.SpendEventsApiService = SpendEventsApiService; exports.TargetMetadataConflictError = TargetMetadataConflictError; exports.TeamsApiError = TeamsApiError; exports.TeamsApiService = TeamsApiService; exports.VirtualKeysApiError = VirtualKeysApiError; exports.VirtualKeysApiService = VirtualKeysApiService; exports.WEBHOOK_DELIVERY_ID_HEADER = WEBHOOK_DELIVERY_ID_HEADER; exports.WEBHOOK_EVENT_ID_HEADER = WEBHOOK_EVENT_ID_HEADER; exports.WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS = WEBHOOK_SIGNATURE_DEFAULT_TOLERANCE_SECONDS; exports.WEBHOOK_SIGNATURE_HEADER = WEBHOOK_SIGNATURE_HEADER; exports.WebhookSignatureVerificationError = WebhookSignatureVerificationError; exports.WebhooksApiError = WebhooksApiError; exports.WebhooksApiService = WebhooksApiService; exports.attributes = _chunkCLTKABMOjs.attributes_exports; exports.getLangWatchLogger = _chunk5ERLGHP2js.getLangWatchLogger; exports.getLangWatchTracer = _chunkK6KPNTQOjs.getLangWatchTracer; exports.isLangWatchHandledError = isLangWatchHandledError; exports.logger = logger; exports.verifyWebhookSignature = verifyWebhookSignature;
6587
7346
  //# sourceMappingURL=index.js.map