braintrust 3.9.0 → 3.10.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 (42) hide show
  1. package/dev/dist/index.d.mts +107 -1
  2. package/dev/dist/index.d.ts +107 -1
  3. package/dev/dist/index.js +2126 -443
  4. package/dev/dist/index.mjs +1814 -131
  5. package/dist/auto-instrumentations/bundler/esbuild.cjs +166 -0
  6. package/dist/auto-instrumentations/bundler/esbuild.mjs +2 -2
  7. package/dist/auto-instrumentations/bundler/rollup.cjs +166 -0
  8. package/dist/auto-instrumentations/bundler/rollup.mjs +2 -2
  9. package/dist/auto-instrumentations/bundler/vite.cjs +166 -0
  10. package/dist/auto-instrumentations/bundler/vite.mjs +2 -2
  11. package/dist/auto-instrumentations/bundler/webpack-loader.cjs +163 -0
  12. package/dist/auto-instrumentations/bundler/webpack.cjs +166 -0
  13. package/dist/auto-instrumentations/bundler/webpack.mjs +2 -2
  14. package/dist/auto-instrumentations/{chunk-KIMMUFAK.mjs → chunk-GZNXBBPU.mjs} +164 -1
  15. package/dist/auto-instrumentations/{chunk-G7F6HZGE.mjs → chunk-XWEQQOQH.mjs} +8 -1
  16. package/dist/auto-instrumentations/hook.mjs +255 -8
  17. package/dist/auto-instrumentations/index.cjs +256 -7
  18. package/dist/auto-instrumentations/index.d.mts +5 -1
  19. package/dist/auto-instrumentations/index.d.ts +5 -1
  20. package/dist/auto-instrumentations/index.mjs +96 -8
  21. package/dist/browser.d.mts +141 -7
  22. package/dist/browser.d.ts +141 -7
  23. package/dist/browser.js +2035 -140
  24. package/dist/browser.mjs +2035 -140
  25. package/dist/cli.js +1822 -139
  26. package/dist/edge-light.d.mts +1 -1
  27. package/dist/edge-light.d.ts +1 -1
  28. package/dist/edge-light.js +2035 -140
  29. package/dist/edge-light.mjs +2035 -140
  30. package/dist/index.d.mts +141 -7
  31. package/dist/index.d.ts +141 -7
  32. package/dist/index.js +2397 -502
  33. package/dist/index.mjs +2035 -140
  34. package/dist/instrumentation/index.d.mts +7 -0
  35. package/dist/instrumentation/index.d.ts +7 -0
  36. package/dist/instrumentation/index.js +1662 -167
  37. package/dist/instrumentation/index.mjs +1662 -167
  38. package/dist/workerd.d.mts +1 -1
  39. package/dist/workerd.d.ts +1 -1
  40. package/dist/workerd.js +2035 -140
  41. package/dist/workerd.mjs +2035 -140
  42. package/package.json +6 -6
package/dist/browser.mjs CHANGED
@@ -1812,6 +1812,7 @@ var TopicMapData = z6.object({
1812
1812
  report_key: z6.string().optional(),
1813
1813
  topic_names: z6.record(z6.string()).optional(),
1814
1814
  generation_settings: TopicMapGenerationSettings.optional(),
1815
+ disable_reconciliation: z6.boolean().optional(),
1815
1816
  distance_threshold: z6.number().optional()
1816
1817
  });
1817
1818
  var BatchedFacetData = z6.object({
@@ -2142,28 +2143,6 @@ var EnvVar = z6.object({
2142
2143
  secret_type: z6.union([z6.string(), z6.null()]).optional(),
2143
2144
  secret_category: z6.enum(["env_var", "ai_provider", "sandbox_provider"]).optional().default("env_var")
2144
2145
  });
2145
- var EvalStatusPageTheme = z6.enum(["light", "dark"]);
2146
- var EvalStatusPageConfig = z6.object({
2147
- score_columns: z6.union([z6.array(z6.string()), z6.null()]),
2148
- metric_columns: z6.union([z6.array(z6.string()), z6.null()]),
2149
- grouping_field: z6.union([z6.string(), z6.null()]),
2150
- filter: z6.union([z6.string(), z6.null()]),
2151
- sort_by: z6.union([z6.string(), z6.null()]),
2152
- sort_order: z6.union([z6.enum(["asc", "desc"]), z6.null()]),
2153
- api_key: z6.union([z6.string(), z6.null()])
2154
- }).partial();
2155
- var EvalStatusPage = z6.object({
2156
- id: z6.string().uuid(),
2157
- project_id: z6.string().uuid(),
2158
- user_id: z6.union([z6.string(), z6.null()]).optional(),
2159
- created: z6.union([z6.string(), z6.null()]).optional(),
2160
- deleted_at: z6.union([z6.string(), z6.null()]).optional(),
2161
- name: z6.string(),
2162
- description: z6.union([z6.string(), z6.null()]).optional(),
2163
- logo_url: z6.union([z6.string(), z6.null()]).optional(),
2164
- theme: EvalStatusPageTheme,
2165
- config: EvalStatusPageConfig
2166
- });
2167
2146
  var RepoInfo = z6.union([
2168
2147
  z6.object({
2169
2148
  commit: z6.union([z6.string(), z6.null()]),
@@ -2190,6 +2169,15 @@ var Experiment = z6.object({
2190
2169
  deleted_at: z6.union([z6.string(), z6.null()]).optional(),
2191
2170
  dataset_id: z6.union([z6.string(), z6.null()]).optional(),
2192
2171
  dataset_version: z6.union([z6.string(), z6.null()]).optional(),
2172
+ internal_metadata: z6.union([
2173
+ z6.object({
2174
+ dataset_filter: z6.union([
2175
+ z6.object({}).partial().passthrough(),
2176
+ z6.null()
2177
+ ])
2178
+ }).partial().passthrough(),
2179
+ z6.null()
2180
+ ]).optional(),
2193
2181
  parameters_id: z6.union([z6.string(), z6.null()]).optional(),
2194
2182
  parameters_version: z6.union([z6.string(), z6.null()]).optional(),
2195
2183
  public: z6.boolean(),
@@ -2926,14 +2914,21 @@ var ProjectAutomation = z6.object({
2926
2914
  z6.object({ type: z6.literal("log_spans") }),
2927
2915
  z6.object({ type: z6.literal("btql_query"), btql_query: z6.string() })
2928
2916
  ]),
2917
+ scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
2929
2918
  export_path: z6.string(),
2930
2919
  format: z6.enum(["jsonl", "parquet"]),
2931
2920
  interval_seconds: z6.number().gte(1).lte(2592e3),
2932
- credentials: z6.object({
2933
- type: z6.literal("aws_iam"),
2934
- role_arn: z6.string(),
2935
- external_id: z6.string()
2936
- }),
2921
+ credentials: z6.union([
2922
+ z6.object({
2923
+ type: z6.literal("aws_iam"),
2924
+ role_arn: z6.string(),
2925
+ external_id: z6.string()
2926
+ }),
2927
+ z6.object({
2928
+ type: z6.literal("gcp_service_account"),
2929
+ service_account_email: z6.string()
2930
+ })
2931
+ ]),
2937
2932
  batch_size: z6.union([z6.number(), z6.null()]).optional()
2938
2933
  }),
2939
2934
  z6.object({
@@ -3313,7 +3308,7 @@ var ViewOptions = z6.union([
3313
3308
  z6.object({ from: z6.string(), to: z6.string() }),
3314
3309
  z6.null()
3315
3310
  ]),
3316
- queryShape: z6.union([z6.enum(["traces", "spans"]), z6.null()]),
3311
+ queryShape: z6.union([z6.enum(["traces", "spans", "topics"]), z6.null()]),
3317
3312
  cluster: z6.union([z6.string(), z6.null()]),
3318
3313
  freezeColumns: z6.union([z6.boolean(), z6.null()])
3319
3314
  }).partial(),
@@ -4329,6 +4324,19 @@ var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
4329
4324
  "braintrust.resetContextManagerState"
4330
4325
  );
4331
4326
  var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
4327
+ var datasetSnapshotRegisterResponseSchema = z8.object({
4328
+ dataset_snapshot: DatasetSnapshot,
4329
+ found_existing: z8.boolean().optional()
4330
+ });
4331
+ var datasetRestorePreviewResultSchema = z8.object({
4332
+ rows_to_restore: z8.number(),
4333
+ rows_to_delete: z8.number()
4334
+ });
4335
+ var datasetRestoreResultSchema = z8.object({
4336
+ xact_id: z8.string().nullable(),
4337
+ rows_restored: z8.number(),
4338
+ rows_deleted: z8.number()
4339
+ });
4332
4340
  var parametersRowSchema = z8.object({
4333
4341
  id: z8.string().uuid(),
4334
4342
  _xact_id: z8.string(),
@@ -6550,6 +6558,33 @@ Error: ${errorText}`;
6550
6558
  this.queue.enforceQueueSizeLimit(enforce);
6551
6559
  }
6552
6560
  };
6561
+ function isDatasetSnapshotNameLookup(lookup) {
6562
+ return "snapshotName" in lookup;
6563
+ }
6564
+ function assertDatasetSnapshotLookup(lookup) {
6565
+ const hasSnapshotName = lookup.snapshotName !== void 0;
6566
+ const hasXactId = lookup.xactId !== void 0;
6567
+ if (hasSnapshotName === hasXactId) {
6568
+ throw new Error("Exactly one of snapshotName or xactId must be provided");
6569
+ }
6570
+ }
6571
+ function getExperimentDatasetFilter({
6572
+ dataset,
6573
+ _internal_btql
6574
+ }) {
6575
+ if (_internal_btql !== void 0) {
6576
+ return _internal_btql;
6577
+ }
6578
+ if (!(dataset instanceof Dataset2)) {
6579
+ return void 0;
6580
+ }
6581
+ const datasetFilter = Reflect.get(dataset, "_internal_btql");
6582
+ return isObject(datasetFilter) ? datasetFilter : void 0;
6583
+ }
6584
+ function getInternalBtqlLimit(internalBtql) {
6585
+ const limit = internalBtql?.["limit"];
6586
+ return typeof limit === "number" ? limit : void 0;
6587
+ }
6553
6588
  function init(projectOrOptions, optionalOptions) {
6554
6589
  const options = (() => {
6555
6590
  if (typeof projectOrOptions === "string") {
@@ -6568,6 +6603,7 @@ function init(projectOrOptions, optionalOptions) {
6568
6603
  experiment,
6569
6604
  description,
6570
6605
  dataset,
6606
+ _internal_btql,
6571
6607
  parameters,
6572
6608
  baseExperiment,
6573
6609
  isPublic,
@@ -6676,16 +6712,24 @@ function init(projectOrOptions, optionalOptions) {
6676
6712
  args["ancestor_commits"] = await isomorph_default.getPastNAncestors();
6677
6713
  }
6678
6714
  if (dataset !== void 0) {
6679
- if ("id" in dataset && typeof dataset.id === "string" && !("__braintrust_dataset_marker" in dataset)) {
6680
- args["dataset_id"] = dataset.id;
6681
- if ("version" in dataset && dataset.version !== void 0) {
6682
- args["dataset_version"] = dataset.version;
6683
- }
6684
- } else {
6685
- args["dataset_id"] = await dataset.id;
6686
- args["dataset_version"] = await dataset.version();
6715
+ const datasetSelection = await serializeDatasetForExperiment({
6716
+ dataset,
6717
+ state
6718
+ });
6719
+ args["dataset_id"] = datasetSelection.datasetId;
6720
+ if (datasetSelection.datasetVersion !== void 0) {
6721
+ args["dataset_version"] = datasetSelection.datasetVersion;
6687
6722
  }
6688
6723
  }
6724
+ const datasetFilter = getExperimentDatasetFilter({
6725
+ dataset,
6726
+ _internal_btql
6727
+ });
6728
+ if (datasetFilter !== void 0) {
6729
+ args["internal_metadata"] = {
6730
+ dataset_filter: datasetFilter
6731
+ };
6732
+ }
6689
6733
  if (parameters !== void 0) {
6690
6734
  if (RemoteEvalParameters.isParameters(parameters)) {
6691
6735
  args["parameters_id"] = parameters.id;
@@ -6739,7 +6783,7 @@ function init(projectOrOptions, optionalOptions) {
6739
6783
  const ret = new Experiment2(
6740
6784
  state,
6741
6785
  lazyMetadata,
6742
- dataset !== void 0 && "version" in dataset ? dataset : void 0
6786
+ dataset !== void 0 ? dataset : void 0
6743
6787
  );
6744
6788
  if (options.setCurrent ?? true) {
6745
6789
  state.currentExperiment = ret;
@@ -6775,6 +6819,153 @@ function withLogger(callback, options = {}) {
6775
6819
  const logger = initLogger(options);
6776
6820
  return callback(logger);
6777
6821
  }
6822
+ async function getDatasetSnapshots(params) {
6823
+ const { state, datasetId } = params;
6824
+ return DatasetSnapshot.array().parse(
6825
+ await state.appConn().post_json("api/dataset_snapshot/get", {
6826
+ dataset_id: datasetId,
6827
+ ..."snapshotName" in params ? { name: params.snapshotName } : {},
6828
+ ..."xactId" in params ? { xact_id: params.xactId } : {}
6829
+ })
6830
+ );
6831
+ }
6832
+ async function getDatasetSnapshot(params) {
6833
+ assertDatasetSnapshotLookup(params);
6834
+ const snapshots = await getDatasetSnapshots(params);
6835
+ if (snapshots.length > 1) {
6836
+ throw new Error(
6837
+ isDatasetSnapshotNameLookup(params) ? `Expected a unique dataset snapshot named "${params.snapshotName}" for ${params.datasetId}` : `Expected a unique dataset snapshot for xact_id "${params.xactId}" in ${params.datasetId}`
6838
+ );
6839
+ }
6840
+ return snapshots[0];
6841
+ }
6842
+ function normalizeDatasetSelection({
6843
+ version,
6844
+ environment,
6845
+ snapshotName
6846
+ }) {
6847
+ if (version !== void 0) {
6848
+ return { version };
6849
+ }
6850
+ if (snapshotName !== void 0) {
6851
+ return { snapshotName };
6852
+ }
6853
+ if (environment !== void 0) {
6854
+ return { environment };
6855
+ }
6856
+ return {};
6857
+ }
6858
+ async function resolveDatasetSnapshotName({
6859
+ state,
6860
+ datasetId,
6861
+ snapshotName
6862
+ }) {
6863
+ const match = await getDatasetSnapshot({
6864
+ state,
6865
+ datasetId,
6866
+ snapshotName
6867
+ });
6868
+ if (match === void 0) {
6869
+ throw new Error(
6870
+ `Dataset snapshot "${snapshotName}" not found for ${datasetId}`
6871
+ );
6872
+ }
6873
+ return match.xact_id;
6874
+ }
6875
+ async function resolveDatasetSnapshotNameForMetadata({
6876
+ state,
6877
+ lazyMetadata,
6878
+ snapshotName
6879
+ }) {
6880
+ const metadata = await lazyMetadata.get();
6881
+ return await resolveDatasetSnapshotName({
6882
+ state,
6883
+ datasetId: metadata.dataset.id,
6884
+ snapshotName
6885
+ });
6886
+ }
6887
+ async function resolveDatasetEnvironment({
6888
+ state,
6889
+ datasetId,
6890
+ environment
6891
+ }) {
6892
+ const environmentObjectPath = `environment-object/dataset/${datasetId}/${encodeURIComponent(environment)}`;
6893
+ const response = state.orgName == null ? await state.apiConn().get_json(environmentObjectPath) : await state.apiConn().get_json(environmentObjectPath, {
6894
+ org_name: state.orgName
6895
+ });
6896
+ return z8.object({ object_version: z8.string() }).parse(response).object_version;
6897
+ }
6898
+ async function resolveDatasetEnvironmentForMetadata({
6899
+ state,
6900
+ lazyMetadata,
6901
+ environment
6902
+ }) {
6903
+ const metadata = await lazyMetadata.get();
6904
+ return await resolveDatasetEnvironment({
6905
+ state,
6906
+ datasetId: metadata.dataset.id,
6907
+ environment
6908
+ });
6909
+ }
6910
+ async function serializeDatasetForExperiment({
6911
+ dataset,
6912
+ state
6913
+ }) {
6914
+ if (!Dataset2.isDataset(dataset)) {
6915
+ const selection2 = normalizeDatasetSelection(dataset);
6916
+ if (selection2.version !== void 0) {
6917
+ return {
6918
+ datasetId: dataset.id,
6919
+ datasetVersion: selection2.version
6920
+ };
6921
+ }
6922
+ if (selection2.snapshotName !== void 0) {
6923
+ return {
6924
+ datasetId: dataset.id,
6925
+ datasetVersion: await resolveDatasetSnapshotName({
6926
+ state,
6927
+ datasetId: dataset.id,
6928
+ snapshotName: selection2.snapshotName
6929
+ })
6930
+ };
6931
+ }
6932
+ if (selection2.environment !== void 0) {
6933
+ return {
6934
+ datasetId: dataset.id,
6935
+ datasetVersion: await resolveDatasetEnvironment({
6936
+ state,
6937
+ datasetId: dataset.id,
6938
+ environment: selection2.environment
6939
+ })
6940
+ };
6941
+ }
6942
+ return {
6943
+ datasetId: dataset.id
6944
+ };
6945
+ }
6946
+ const evalData = await dataset.toEvalData();
6947
+ const selection = normalizeDatasetSelection({
6948
+ version: evalData.dataset_version,
6949
+ environment: evalData.dataset_environment,
6950
+ snapshotName: evalData.dataset_snapshot_name
6951
+ });
6952
+ if (selection.version !== void 0) {
6953
+ return {
6954
+ datasetId: evalData.dataset_id,
6955
+ datasetVersion: selection.version
6956
+ };
6957
+ }
6958
+ const datasetVersion = await dataset.version();
6959
+ if (datasetVersion !== void 0) {
6960
+ return {
6961
+ datasetId: evalData.dataset_id,
6962
+ datasetVersion
6963
+ };
6964
+ }
6965
+ return {
6966
+ datasetId: evalData.dataset_id
6967
+ };
6968
+ }
6778
6969
  function initDataset(projectOrOptions, optionalOptions) {
6779
6970
  const options = (() => {
6780
6971
  if (typeof projectOrOptions === "string") {
@@ -6793,6 +6984,8 @@ function initDataset(projectOrOptions, optionalOptions) {
6793
6984
  dataset,
6794
6985
  description,
6795
6986
  version,
6987
+ snapshotName,
6988
+ environment,
6796
6989
  appUrl,
6797
6990
  apiKey,
6798
6991
  orgName,
@@ -6804,6 +6997,14 @@ function initDataset(projectOrOptions, optionalOptions) {
6804
6997
  state: stateArg,
6805
6998
  _internal_btql
6806
6999
  } = options;
7000
+ const selection = normalizeDatasetSelection({
7001
+ version,
7002
+ environment,
7003
+ snapshotName
7004
+ });
7005
+ const normalizedVersion = selection.version;
7006
+ const normalizedEnvironment = selection.environment;
7007
+ const normalizedSnapshotName = selection.snapshotName;
6807
7008
  const state = stateArg ?? _globalState;
6808
7009
  const lazyMetadata = new LazyValue(
6809
7010
  async () => {
@@ -6837,13 +7038,38 @@ function initDataset(projectOrOptions, optionalOptions) {
6837
7038
  };
6838
7039
  }
6839
7040
  );
6840
- return new Dataset2(
7041
+ const resolvedVersion = normalizedVersion !== void 0 ? normalizedVersion : normalizedSnapshotName !== void 0 ? new LazyValue(async () => {
7042
+ return await resolveDatasetSnapshotNameForMetadata({
7043
+ state,
7044
+ lazyMetadata,
7045
+ snapshotName: normalizedSnapshotName
7046
+ });
7047
+ }) : normalizedEnvironment !== void 0 ? new LazyValue(async () => {
7048
+ return await resolveDatasetEnvironmentForMetadata({
7049
+ state,
7050
+ lazyMetadata,
7051
+ environment: normalizedEnvironment
7052
+ });
7053
+ }) : void 0;
7054
+ const datasetObject = new Dataset2(
6841
7055
  stateArg ?? _globalState,
6842
7056
  lazyMetadata,
6843
- version,
7057
+ typeof resolvedVersion === "string" ? resolvedVersion : void 0,
6844
7058
  legacy,
6845
- _internal_btql
7059
+ _internal_btql,
7060
+ resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
7061
+ ...resolvedVersion instanceof LazyValue ? {
7062
+ lazyPinnedVersion: resolvedVersion
7063
+ } : {},
7064
+ ...normalizedEnvironment !== void 0 ? {
7065
+ pinnedEnvironment: normalizedEnvironment
7066
+ } : {},
7067
+ ...normalizedSnapshotName !== void 0 ? {
7068
+ pinnedSnapshotName: normalizedSnapshotName
7069
+ } : {}
7070
+ } : void 0
6846
7071
  );
7072
+ return datasetObject;
6847
7073
  }
6848
7074
  function withDataset(project, callback, options = {}) {
6849
7075
  debugLogger.forState(options.state).warn(
@@ -7839,11 +8065,20 @@ var ObjectFetcher = class {
7839
8065
  async getState() {
7840
8066
  throw new Error("ObjectFetcher subclasses must have a 'getState' method");
7841
8067
  }
8068
+ getPinnedVersion() {
8069
+ return this.pinnedVersion;
8070
+ }
8071
+ setPinnedVersion(pinnedVersion) {
8072
+ this.pinnedVersion = pinnedVersion;
8073
+ }
8074
+ getInternalBtql() {
8075
+ return this._internal_btql;
8076
+ }
7842
8077
  async *fetchRecordsFromApi(batchSize) {
7843
8078
  const state = await this.getState();
7844
8079
  const objectId = await this.id;
7845
8080
  const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
7846
- const internalLimit = this._internal_btql?.limit;
8081
+ const internalLimit = getInternalBtqlLimit(this._internal_btql);
7847
8082
  const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
7848
8083
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
7849
8084
  Object.entries(this._internal_btql ?? {}).filter(
@@ -8657,7 +8892,7 @@ function splitLoggingData({
8657
8892
  return [serializableInternalData, lazyInternalData];
8658
8893
  }
8659
8894
  var Dataset2 = class extends ObjectFetcher {
8660
- constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql) {
8895
+ constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql, pinState) {
8661
8896
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
8662
8897
  if (isLegacyDataset) {
8663
8898
  debugLogger.forState(state).warn(
@@ -8678,10 +8913,16 @@ var Dataset2 = class extends ObjectFetcher {
8678
8913
  );
8679
8914
  this.state = state;
8680
8915
  this.lazyMetadata = lazyMetadata;
8916
+ this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
8917
+ this.pinnedEnvironment = pinState?.pinnedEnvironment;
8918
+ this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
8681
8919
  }
8682
8920
  lazyMetadata;
8683
8921
  __braintrust_dataset_marker = true;
8684
8922
  newRecords = 0;
8923
+ lazyPinnedVersion;
8924
+ pinnedEnvironment;
8925
+ pinnedSnapshotName;
8685
8926
  get id() {
8686
8927
  return (async () => {
8687
8928
  return (await this.lazyMetadata.get()).dataset.id;
@@ -8700,10 +8941,40 @@ var Dataset2 = class extends ObjectFetcher {
8700
8941
  get loggingState() {
8701
8942
  return this.state;
8702
8943
  }
8944
+ async toEvalData() {
8945
+ await this.getState();
8946
+ const metadata = await this.lazyMetadata.get();
8947
+ const pinnedVersion = this.getPinnedVersion();
8948
+ const internalBtql = this.getInternalBtql();
8949
+ return {
8950
+ dataset_id: metadata.dataset.id,
8951
+ ...this.pinnedEnvironment !== void 0 ? {
8952
+ dataset_environment: this.pinnedEnvironment
8953
+ } : {},
8954
+ ...this.pinnedEnvironment === void 0 && this.pinnedSnapshotName !== void 0 ? {
8955
+ dataset_snapshot_name: this.pinnedSnapshotName
8956
+ } : {},
8957
+ ...this.pinnedEnvironment === void 0 && this.pinnedSnapshotName === void 0 && pinnedVersion !== void 0 ? {
8958
+ dataset_version: pinnedVersion
8959
+ } : {},
8960
+ ...internalBtql !== void 0 ? { _internal_btql: internalBtql } : {}
8961
+ };
8962
+ }
8703
8963
  async getState() {
8704
8964
  await this.lazyMetadata.get();
8965
+ if (this.lazyPinnedVersion !== void 0 && this.getPinnedVersion() === void 0) {
8966
+ this.setPinnedVersion(await this.lazyPinnedVersion.get());
8967
+ }
8705
8968
  return this.state;
8706
8969
  }
8970
+ async version(options) {
8971
+ const pinnedVersion = this.getPinnedVersion();
8972
+ if (pinnedVersion !== void 0) {
8973
+ return pinnedVersion;
8974
+ }
8975
+ await this.getState();
8976
+ return await super.version(options);
8977
+ }
8707
8978
  validateEvent({
8708
8979
  metadata,
8709
8980
  expected,
@@ -8839,6 +9110,88 @@ var Dataset2 = class extends ObjectFetcher {
8839
9110
  this.state.bgLogger().log([args]);
8840
9111
  return id;
8841
9112
  }
9113
+ async createSnapshot({
9114
+ name,
9115
+ description,
9116
+ update
9117
+ }) {
9118
+ await this.flush();
9119
+ const state = await this.getState();
9120
+ const datasetId = await this.id;
9121
+ const currentVersion = await this.version();
9122
+ if (currentVersion === void 0) {
9123
+ throw new Error("Cannot create snapshot: dataset has no version");
9124
+ }
9125
+ const response = await state.appConn().post_json("api/dataset_snapshot/register", {
9126
+ dataset_id: datasetId,
9127
+ dataset_snapshot_name: name,
9128
+ description,
9129
+ xact_id: currentVersion,
9130
+ update
9131
+ });
9132
+ return datasetSnapshotRegisterResponseSchema.parse(response).dataset_snapshot;
9133
+ }
9134
+ async listSnapshots() {
9135
+ const state = await this.getState();
9136
+ return await getDatasetSnapshots({
9137
+ state,
9138
+ datasetId: await this.id
9139
+ });
9140
+ }
9141
+ async getSnapshot(lookup) {
9142
+ const state = await this.getState();
9143
+ const datasetId = await this.id;
9144
+ return await getDatasetSnapshot({
9145
+ state,
9146
+ datasetId,
9147
+ ...lookup
9148
+ });
9149
+ }
9150
+ async updateSnapshot(snapshotId, {
9151
+ name,
9152
+ description
9153
+ }) {
9154
+ const state = await this.getState();
9155
+ return DatasetSnapshot.parse(
9156
+ await state.appConn().post_json("api/dataset_snapshot/patch_id", {
9157
+ id: snapshotId,
9158
+ name,
9159
+ description
9160
+ })
9161
+ );
9162
+ }
9163
+ async deleteSnapshot(snapshotId) {
9164
+ const state = await this.getState();
9165
+ return DatasetSnapshot.parse(
9166
+ await state.appConn().post_json("api/dataset_snapshot/delete_id", {
9167
+ id: snapshotId
9168
+ })
9169
+ );
9170
+ }
9171
+ async restorePreview({
9172
+ version
9173
+ }) {
9174
+ await this.flush();
9175
+ const state = await this.getState();
9176
+ const datasetId = await this.id;
9177
+ return datasetRestorePreviewResultSchema.parse(
9178
+ await state.apiConn().post_json(`v1/dataset/${datasetId}/restore/preview`, {
9179
+ version
9180
+ })
9181
+ );
9182
+ }
9183
+ async restore({
9184
+ version
9185
+ }) {
9186
+ await this.flush();
9187
+ const state = await this.getState();
9188
+ const datasetId = await this.id;
9189
+ return datasetRestoreResultSchema.parse(
9190
+ await state.apiConn().post_json(`v1/dataset/${datasetId}/restore`, {
9191
+ version
9192
+ })
9193
+ );
9194
+ }
8842
9195
  /**
8843
9196
  * Summarize the dataset, including high level metrics about its size and other metadata.
8844
9197
  * @param summarizeData Whether to summarize the data. If false, only the metadata will be returned.
@@ -14096,6 +14449,9 @@ function llmParentKey(parentToolUseId) {
14096
14449
  function isSubAgentDelegationToolName(toolName) {
14097
14450
  return toolName === "Agent" || toolName === "Task";
14098
14451
  }
14452
+ function shouldParentToolAsTaskSibling(toolName) {
14453
+ return toolName === "Agent" || toolName === "Task" || toolName === "Bash";
14454
+ }
14099
14455
  function filterSerializableOptions(options) {
14100
14456
  const allowedKeys = [
14101
14457
  "model",
@@ -14195,6 +14551,11 @@ function resolveTaskToolUseId(taskIdToToolUseId, message) {
14195
14551
  }
14196
14552
  return void 0;
14197
14553
  }
14554
+ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
14555
+ if (typeof message.task_id === "string" && typeof message.tool_use_id === "string") {
14556
+ taskIdToToolUseId.set(message.task_id, message.tool_use_id);
14557
+ }
14558
+ }
14198
14559
  function extractUsageFromMessage(message) {
14199
14560
  const metrics = {};
14200
14561
  let usage;
@@ -14390,7 +14751,10 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
14390
14751
  }
14391
14752
  },
14392
14753
  name: parsed.displayName,
14393
- parent: await resolveParentSpan(toolUseID),
14754
+ parent: await resolveParentSpan(toolUseID, {
14755
+ agentId: input.agent_id,
14756
+ preferTaskSiblingParent: shouldParentToolAsTaskSibling(parsed.toolName)
14757
+ }),
14394
14758
  spanAttributes: { type: "tool" /* TOOL */ }
14395
14759
  });
14396
14760
  activeToolSpans.set(toolUseID, toolSpan);
@@ -14680,6 +15044,7 @@ async function finalizeCurrentMessageGroup(state) {
14680
15044
  state.currentMessages.length = 0;
14681
15045
  }
14682
15046
  function maybeTrackToolUseContext(state, message) {
15047
+ seedTaskToolUseIdMapping(state.taskIdToToolUseId, message);
14683
15048
  if (message.type !== "assistant" || !Array.isArray(message.message?.content)) {
14684
15049
  return;
14685
15050
  }
@@ -14734,6 +15099,34 @@ async function ensureSubAgentSpan(subAgentDetailsByToolUseId, rootSpan, activeTo
14734
15099
  subAgentSpans.set(parentToolUseId, subAgentSpan);
14735
15100
  return subAgentSpan;
14736
15101
  }
15102
+ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByParentToolUse, subAgentDetailsByToolUseId, activeToolSpans, subAgentSpans, parentToolUseId, startTime) {
15103
+ const parentKey = llmParentKey(parentToolUseId);
15104
+ const existingLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
15105
+ if (existingLlmSpan) {
15106
+ return existingLlmSpan;
15107
+ }
15108
+ let llmParentSpan = await rootSpan.export();
15109
+ if (parentToolUseId) {
15110
+ const subAgentSpan = await ensureSubAgentSpan(
15111
+ subAgentDetailsByToolUseId,
15112
+ rootSpan,
15113
+ activeToolSpans,
15114
+ subAgentSpans,
15115
+ parentToolUseId
15116
+ );
15117
+ llmParentSpan = await subAgentSpan.export();
15118
+ }
15119
+ const llmSpan = startSpan({
15120
+ name: "anthropic.messages.create",
15121
+ parent: llmParentSpan,
15122
+ spanAttributes: {
15123
+ type: "llm" /* LLM */
15124
+ },
15125
+ startTime
15126
+ });
15127
+ activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
15128
+ return llmSpan;
15129
+ }
14737
15130
  async function maybeHandleTaskLifecycleMessage(state, message) {
14738
15131
  if (message.type !== "system") {
14739
15132
  return false;
@@ -14843,29 +15236,15 @@ async function handleStreamMessage(state, message) {
14843
15236
  }
14844
15237
  if (message.type === "assistant" && message.message?.usage) {
14845
15238
  const parentToolUseId = message.parent_tool_use_id ?? null;
14846
- const parentKey = llmParentKey(parentToolUseId);
14847
- if (!state.activeLlmSpansByParentToolUse.has(parentKey)) {
14848
- let llmParentSpan = await state.span.export();
14849
- if (parentToolUseId) {
14850
- const subAgentSpan = await ensureSubAgentSpan(
14851
- state.subAgentDetailsByToolUseId,
14852
- state.span,
14853
- state.activeToolSpans,
14854
- state.subAgentSpans,
14855
- parentToolUseId
14856
- );
14857
- llmParentSpan = await subAgentSpan.export();
14858
- }
14859
- const llmSpan = startSpan({
14860
- name: "anthropic.messages.create",
14861
- parent: llmParentSpan,
14862
- spanAttributes: {
14863
- type: "llm" /* LLM */
14864
- },
14865
- startTime: state.currentMessageStartTime
14866
- });
14867
- state.activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
14868
- }
15239
+ await ensureActiveLlmSpanForParentToolUse(
15240
+ state.span,
15241
+ state.activeLlmSpansByParentToolUse,
15242
+ state.subAgentDetailsByToolUseId,
15243
+ state.activeToolSpans,
15244
+ state.subAgentSpans,
15245
+ parentToolUseId,
15246
+ state.currentMessageStartTime
15247
+ );
14869
15248
  state.currentMessages.push(message);
14870
15249
  }
14871
15250
  if (message.type !== "result" || !message.usage) {
@@ -15012,10 +15391,35 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
15012
15391
  const localToolContext = createClaudeLocalToolContext();
15013
15392
  const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
15014
15393
  const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
15015
- const resolveToolUseParentSpan = async (toolUseID) => {
15016
- const parentToolUseId = toolUseToParent.get(toolUseID) ?? null;
15394
+ const resolveToolUseParentSpan = async (toolUseID, context) => {
15395
+ const trackedParentToolUseId = toolUseToParent.get(toolUseID);
15396
+ const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
15017
15397
  const parentKey = llmParentKey(parentToolUseId);
15018
15398
  const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
15399
+ if (context?.preferTaskSiblingParent) {
15400
+ if (!activeLlmSpan) {
15401
+ await ensureActiveLlmSpanForParentToolUse(
15402
+ span,
15403
+ activeLlmSpansByParentToolUse,
15404
+ subAgentDetailsByToolUseId,
15405
+ activeToolSpans,
15406
+ subAgentSpans,
15407
+ parentToolUseId,
15408
+ getCurrentUnixTimestamp()
15409
+ );
15410
+ }
15411
+ if (parentToolUseId) {
15412
+ const subAgentSpan = await ensureSubAgentSpan(
15413
+ subAgentDetailsByToolUseId,
15414
+ span,
15415
+ activeToolSpans,
15416
+ subAgentSpans,
15417
+ parentToolUseId
15418
+ );
15419
+ return subAgentSpan.export();
15420
+ }
15421
+ return span.export();
15422
+ }
15019
15423
  if (activeLlmSpan) {
15020
15424
  return activeLlmSpan.export();
15021
15425
  }
@@ -15143,62 +15547,940 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
15143
15547
  }
15144
15548
  };
15145
15549
 
15146
- // src/instrumentation/plugins/google-genai-channels.ts
15147
- var googleGenAIChannels = defineChannels("@google/genai", {
15148
- generateContent: channel({
15149
- channelName: "models.generateContent",
15550
+ // src/instrumentation/plugins/cursor-sdk-channels.ts
15551
+ var cursorSDKChannels = defineChannels("@cursor/sdk", {
15552
+ create: channel({
15553
+ channelName: "Agent.create",
15150
15554
  kind: "async"
15151
15555
  }),
15152
- generateContentStream: channel({
15153
- channelName: "models.generateContentStream",
15556
+ resume: channel({
15557
+ channelName: "Agent.resume",
15154
15558
  kind: "async"
15155
15559
  }),
15156
- embedContent: channel({
15157
- channelName: "models.embedContent",
15560
+ prompt: channel({
15561
+ channelName: "Agent.prompt",
15562
+ kind: "async"
15563
+ }),
15564
+ send: channel({
15565
+ channelName: "agent.send",
15158
15566
  kind: "async"
15159
15567
  })
15160
15568
  });
15161
15569
 
15162
- // src/instrumentation/plugins/google-genai-plugin.ts
15163
- var GOOGLE_GENAI_INTERNAL_CONTEXT = {
15164
- caller_filename: "<node-internal>",
15165
- caller_functionname: "<node-internal>",
15166
- caller_lineno: 0
15167
- };
15168
- function createWrapperParityEvent(args) {
15169
- return {
15170
- context: GOOGLE_GENAI_INTERNAL_CONTEXT,
15171
- input: args.input,
15172
- metadata: args.metadata
15173
- };
15174
- }
15175
- var GoogleGenAIPlugin = class extends BasePlugin {
15570
+ // src/instrumentation/plugins/cursor-sdk-plugin.ts
15571
+ var PATCHED_AGENT = Symbol.for("braintrust.cursor-sdk.auto-patched-agent");
15572
+ var PATCHED_RUN = Symbol.for("braintrust.cursor-sdk.patched-run");
15573
+ var WRAPPED_AGENT = Symbol.for("braintrust.cursor-sdk.wrapped-agent");
15574
+ var CursorSDKPlugin = class extends BasePlugin {
15575
+ promptDepth = 0;
15176
15576
  onEnable() {
15177
- this.subscribeToGoogleGenAIChannels();
15577
+ this.subscribeToAgentFactories();
15578
+ this.subscribeToPrompt();
15579
+ this.subscribeToSend();
15178
15580
  }
15179
15581
  onDisable() {
15180
- this.unsubscribers = unsubscribeAll(this.unsubscribers);
15582
+ for (const unsubscribe of this.unsubscribers) {
15583
+ unsubscribe();
15584
+ }
15585
+ this.unsubscribers = [];
15586
+ this.promptDepth = 0;
15181
15587
  }
15182
- subscribeToGoogleGenAIChannels() {
15183
- this.subscribeToGenerateContentChannel();
15184
- this.subscribeToGenerateContentStreamChannel();
15185
- this.subscribeToEmbedContentChannel();
15588
+ subscribeToAgentFactories() {
15589
+ this.subscribeToAgentFactory(cursorSDKChannels.create);
15590
+ this.subscribeToAgentFactory(cursorSDKChannels.resume);
15186
15591
  }
15187
- subscribeToGenerateContentChannel() {
15188
- const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
15592
+ subscribeToAgentFactory(channel2) {
15593
+ const tracingChannel2 = channel2.tracingChannel();
15594
+ const handlers = {
15595
+ asyncEnd: (event) => {
15596
+ patchCursorAgentInPlace(event.result);
15597
+ },
15598
+ error: () => {
15599
+ }
15600
+ };
15601
+ tracingChannel2.subscribe(handlers);
15602
+ this.unsubscribers.push(() => {
15603
+ tracingChannel2.unsubscribe(handlers);
15604
+ });
15605
+ }
15606
+ subscribeToPrompt() {
15607
+ const channel2 = cursorSDKChannels.prompt.tracingChannel();
15189
15608
  const states = /* @__PURE__ */ new WeakMap();
15190
- const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
15191
- tracingChannel2,
15192
- states,
15193
- (event) => {
15194
- const params = event.arguments[0];
15195
- const input = serializeGenerateContentInput(params);
15196
- const metadata = extractGenerateContentMetadata(params);
15609
+ const handlers = {
15610
+ start: (event) => {
15611
+ this.promptDepth += 1;
15612
+ const message = event.arguments[0];
15613
+ const options = event.arguments[1];
15614
+ const metadata = {
15615
+ ...extractAgentOptionsMetadata(options),
15616
+ "cursor_sdk.operation": "Agent.prompt",
15617
+ provider: "cursor",
15618
+ ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
15619
+ };
15197
15620
  const span = startSpan({
15198
- name: "generate_content",
15199
- spanAttributes: {
15200
- type: "llm" /* LLM */
15201
- },
15621
+ name: "Cursor Agent",
15622
+ spanAttributes: { type: "task" /* TASK */ }
15623
+ });
15624
+ const startTime = getCurrentUnixTimestamp();
15625
+ safeLog(span, {
15626
+ input: sanitizeUserMessage(message),
15627
+ metadata
15628
+ });
15629
+ states.set(event, { metadata, span, startTime });
15630
+ },
15631
+ asyncEnd: (event) => {
15632
+ this.promptDepth = Math.max(0, this.promptDepth - 1);
15633
+ const state = states.get(event);
15634
+ if (!state) {
15635
+ return;
15636
+ }
15637
+ try {
15638
+ safeLog(state.span, {
15639
+ metadata: {
15640
+ ...state.metadata,
15641
+ ...extractRunResultMetadata(event.result)
15642
+ },
15643
+ metrics: buildDurationMetrics(state.startTime),
15644
+ output: event.result?.result ?? event.result
15645
+ });
15646
+ } finally {
15647
+ state.span.end();
15648
+ states.delete(event);
15649
+ }
15650
+ },
15651
+ error: (event) => {
15652
+ this.promptDepth = Math.max(0, this.promptDepth - 1);
15653
+ const state = states.get(event);
15654
+ if (!state || !event.error) {
15655
+ return;
15656
+ }
15657
+ safeLog(state.span, { error: event.error.message });
15658
+ state.span.end();
15659
+ states.delete(event);
15660
+ }
15661
+ };
15662
+ channel2.subscribe(handlers);
15663
+ this.unsubscribers.push(() => {
15664
+ channel2.unsubscribe(handlers);
15665
+ });
15666
+ }
15667
+ subscribeToSend() {
15668
+ const channel2 = cursorSDKChannels.send.tracingChannel();
15669
+ const states = /* @__PURE__ */ new WeakMap();
15670
+ const handlers = {
15671
+ start: (event) => {
15672
+ if (this.promptDepth > 0) {
15673
+ return;
15674
+ }
15675
+ const message = event.arguments[0];
15676
+ const sendOptions = event.arguments[1];
15677
+ const agent = event.agent;
15678
+ const metadata = {
15679
+ ...extractSendMetadata(sendOptions),
15680
+ ...agent ? extractAgentMetadata(agent) : {},
15681
+ "cursor_sdk.operation": "agent.send",
15682
+ provider: "cursor",
15683
+ ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
15684
+ };
15685
+ const span = startSpan({
15686
+ name: "Cursor Agent",
15687
+ spanAttributes: { type: "task" /* TASK */ }
15688
+ });
15689
+ const startTime = getCurrentUnixTimestamp();
15690
+ safeLog(span, {
15691
+ input: sanitizeUserMessage(message),
15692
+ metadata
15693
+ });
15694
+ const state = {
15695
+ activeToolSpans: /* @__PURE__ */ new Map(),
15696
+ agent,
15697
+ conversationText: [],
15698
+ deltaText: [],
15699
+ finalized: false,
15700
+ input: message,
15701
+ metadata,
15702
+ metrics: {},
15703
+ span,
15704
+ startTime,
15705
+ streamMessages: [],
15706
+ streamText: [],
15707
+ stepText: [],
15708
+ taskText: []
15709
+ };
15710
+ if (hasCursorCallbacks(sendOptions)) {
15711
+ event.arguments[1] = wrapSendOptionsCallbacks(sendOptions, state);
15712
+ }
15713
+ states.set(event, state);
15714
+ },
15715
+ asyncEnd: (event) => {
15716
+ const state = states.get(event);
15717
+ if (!state) {
15718
+ return;
15719
+ }
15720
+ if (!event.result) {
15721
+ return;
15722
+ }
15723
+ state.run = event.result;
15724
+ state.metadata = {
15725
+ ...state.metadata,
15726
+ ...extractRunMetadata(event.result)
15727
+ };
15728
+ patchCursorRun(event.result, state);
15729
+ },
15730
+ error: (event) => {
15731
+ const state = states.get(event);
15732
+ if (!state || !event.error) {
15733
+ return;
15734
+ }
15735
+ safeLog(state.span, { error: event.error.message });
15736
+ endOpenToolSpans(state, event.error.message);
15737
+ state.span.end();
15738
+ state.finalized = true;
15739
+ states.delete(event);
15740
+ }
15741
+ };
15742
+ channel2.subscribe(handlers);
15743
+ this.unsubscribers.push(() => {
15744
+ channel2.unsubscribe(handlers);
15745
+ });
15746
+ }
15747
+ };
15748
+ function patchCursorAgentInPlace(agent) {
15749
+ if (!agent || typeof agent !== "object") {
15750
+ return;
15751
+ }
15752
+ const agentRecord = agent;
15753
+ if (agentRecord[PATCHED_AGENT] || agentRecord[WRAPPED_AGENT] || typeof agentRecord.send !== "function") {
15754
+ return;
15755
+ }
15756
+ const originalSend = agentRecord.send.bind(agentRecord);
15757
+ try {
15758
+ Object.defineProperty(agentRecord, PATCHED_AGENT, {
15759
+ configurable: false,
15760
+ enumerable: false,
15761
+ value: true
15762
+ });
15763
+ Object.defineProperty(agentRecord, "send", {
15764
+ configurable: true,
15765
+ value(message, options) {
15766
+ const args = [message, options];
15767
+ return cursorSDKChannels.send.tracePromise(
15768
+ () => originalSend(...args),
15769
+ {
15770
+ agent: agentRecord,
15771
+ arguments: args,
15772
+ operation: "send"
15773
+ }
15774
+ );
15775
+ },
15776
+ writable: true
15777
+ });
15778
+ } catch {
15779
+ }
15780
+ }
15781
+ function wrapSendOptionsCallbacks(options, state) {
15782
+ const originalOnDelta = options.onDelta;
15783
+ const originalOnStep = options.onStep;
15784
+ return {
15785
+ ...options,
15786
+ async onDelta(args) {
15787
+ try {
15788
+ await handleInteractionUpdate(state, args.update);
15789
+ } catch (error) {
15790
+ logInstrumentationError("Cursor SDK onDelta", error);
15791
+ }
15792
+ if (originalOnDelta) {
15793
+ return originalOnDelta(args);
15794
+ }
15795
+ },
15796
+ async onStep(args) {
15797
+ try {
15798
+ handleStepUpdate(state, args.step);
15799
+ } catch (error) {
15800
+ logInstrumentationError("Cursor SDK onStep", error);
15801
+ }
15802
+ if (originalOnStep) {
15803
+ return originalOnStep(args);
15804
+ }
15805
+ }
15806
+ };
15807
+ }
15808
+ function hasCursorCallbacks(options) {
15809
+ return !!options && (typeof options.onDelta === "function" || typeof options.onStep === "function");
15810
+ }
15811
+ function patchCursorRun(run, state) {
15812
+ if (!run || typeof run !== "object") {
15813
+ return;
15814
+ }
15815
+ const runRecord = run;
15816
+ if (runRecord[PATCHED_RUN]) {
15817
+ return;
15818
+ }
15819
+ try {
15820
+ Object.defineProperty(runRecord, PATCHED_RUN, {
15821
+ configurable: false,
15822
+ enumerable: false,
15823
+ value: true
15824
+ });
15825
+ if (typeof runRecord.stream === "function") {
15826
+ const originalStream = runRecord.stream.bind(runRecord);
15827
+ Object.defineProperty(runRecord, "stream", {
15828
+ configurable: true,
15829
+ value() {
15830
+ const stream = originalStream();
15831
+ return patchCursorStream(stream, state);
15832
+ },
15833
+ writable: true
15834
+ });
15835
+ }
15836
+ if (typeof runRecord.wait === "function") {
15837
+ const originalWait = runRecord.wait.bind(runRecord);
15838
+ Object.defineProperty(runRecord, "wait", {
15839
+ configurable: true,
15840
+ async value() {
15841
+ try {
15842
+ const result = await originalWait();
15843
+ state.lastResult = result;
15844
+ await finalizeCursorRun(state, { result });
15845
+ return result;
15846
+ } catch (error) {
15847
+ await finalizeCursorRun(state, { error });
15848
+ throw error;
15849
+ }
15850
+ },
15851
+ writable: true
15852
+ });
15853
+ }
15854
+ if (typeof runRecord.conversation === "function") {
15855
+ const originalConversation = runRecord.conversation.bind(runRecord);
15856
+ Object.defineProperty(runRecord, "conversation", {
15857
+ configurable: true,
15858
+ async value() {
15859
+ try {
15860
+ const conversation = await originalConversation();
15861
+ await handleConversation(state, conversation);
15862
+ await finalizeCursorRun(state);
15863
+ return conversation;
15864
+ } catch (error) {
15865
+ await finalizeCursorRun(state, { error });
15866
+ throw error;
15867
+ }
15868
+ },
15869
+ writable: true
15870
+ });
15871
+ }
15872
+ } catch {
15873
+ void finalizeCursorRun(state, { output: run });
15874
+ }
15875
+ }
15876
+ async function* patchCursorStream(stream, state) {
15877
+ try {
15878
+ for await (const message of stream) {
15879
+ try {
15880
+ await handleStreamMessage2(state, message);
15881
+ } catch (error) {
15882
+ logInstrumentationError("Cursor SDK stream", error);
15883
+ }
15884
+ yield message;
15885
+ }
15886
+ await finalizeCursorRun(state);
15887
+ } catch (error) {
15888
+ await finalizeCursorRun(state, { error });
15889
+ throw error;
15890
+ }
15891
+ }
15892
+ async function handleInteractionUpdate(state, update) {
15893
+ switch (update.type) {
15894
+ case "text-delta":
15895
+ if (typeof update.text === "string") {
15896
+ state.deltaText.push(update.text);
15897
+ }
15898
+ return;
15899
+ case "token-delta":
15900
+ if (typeof update.tokens === "number") {
15901
+ state.metrics["cursor_sdk.delta_tokens"] = (state.metrics["cursor_sdk.delta_tokens"] ?? 0) + update.tokens;
15902
+ }
15903
+ return;
15904
+ case "tool-call-started":
15905
+ case "partial-tool-call":
15906
+ case "tool-call-completed":
15907
+ await handleToolUpdate(
15908
+ state,
15909
+ update
15910
+ );
15911
+ return;
15912
+ case "turn-ended":
15913
+ addUsageMetrics(
15914
+ state.metrics,
15915
+ update.usage
15916
+ );
15917
+ return;
15918
+ case "summary":
15919
+ if (typeof update.summary === "string") {
15920
+ state.taskText.push(update.summary);
15921
+ }
15922
+ return;
15923
+ case "step-completed":
15924
+ if (typeof update.stepDurationMs === "number") {
15925
+ state.metrics["cursor_sdk.step_duration_ms"] = (state.metrics["cursor_sdk.step_duration_ms"] ?? 0) + update.stepDurationMs;
15926
+ }
15927
+ state.metrics["cursor_sdk.steps"] = (state.metrics["cursor_sdk.steps"] ?? 0) + 1;
15928
+ return;
15929
+ default:
15930
+ return;
15931
+ }
15932
+ }
15933
+ async function handleToolUpdate(state, update) {
15934
+ const callId = update.callId;
15935
+ if (!callId) {
15936
+ return;
15937
+ }
15938
+ const toolCall = update.toolCall;
15939
+ const name = extractToolName(toolCall);
15940
+ const args = extractToolArgs(toolCall);
15941
+ const result = extractToolResult(toolCall);
15942
+ if (update.type === "tool-call-started" || update.type === "partial-tool-call") {
15943
+ if (!state.activeToolSpans.has(callId)) {
15944
+ state.activeToolSpans.set(
15945
+ callId,
15946
+ await startToolSpan(state, {
15947
+ args,
15948
+ callId,
15949
+ name,
15950
+ status: "running",
15951
+ toolCall
15952
+ })
15953
+ );
15954
+ }
15955
+ return;
15956
+ }
15957
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
15958
+ args,
15959
+ callId,
15960
+ name,
15961
+ status: "completed",
15962
+ toolCall
15963
+ });
15964
+ finishToolSpan(toolState, {
15965
+ error: toolCall?.status === "error" ? stringifyUnknown(result) : void 0,
15966
+ metadata: {
15967
+ "cursor_sdk.tool.status": toolCall?.status ?? "completed"
15968
+ },
15969
+ output: result
15970
+ });
15971
+ state.activeToolSpans.delete(callId);
15972
+ }
15973
+ async function handleStreamMessage2(state, message) {
15974
+ state.streamMessages.push(message);
15975
+ if (message.type === "system") {
15976
+ const systemMessage = message;
15977
+ state.metadata = {
15978
+ ...state.metadata,
15979
+ ...extractModelMetadata(systemMessage.model),
15980
+ ...systemMessage.agent_id ? { "cursor_sdk.agent_id": systemMessage.agent_id } : {},
15981
+ ...systemMessage.run_id ? { "cursor_sdk.run_id": systemMessage.run_id } : {},
15982
+ ...systemMessage.tools ? { "cursor_sdk.tools": systemMessage.tools } : {}
15983
+ };
15984
+ return;
15985
+ }
15986
+ if (message.type === "assistant") {
15987
+ const assistantMessage = message;
15988
+ for (const block of assistantMessage.message?.content ?? []) {
15989
+ if (block?.type === "text" && typeof block.text === "string") {
15990
+ state.streamText.push(block.text);
15991
+ } else if (block?.type === "tool_use" && block.id) {
15992
+ state.activeToolSpans.set(
15993
+ block.id,
15994
+ await startToolSpan(state, {
15995
+ args: block.input,
15996
+ callId: block.id,
15997
+ name: block.name,
15998
+ status: "running"
15999
+ })
16000
+ );
16001
+ }
16002
+ }
16003
+ return;
16004
+ }
16005
+ if (message.type === "tool_call") {
16006
+ await handleToolMessage(
16007
+ state,
16008
+ message
16009
+ );
16010
+ return;
16011
+ }
16012
+ if (message.type === "task" && typeof message.text === "string") {
16013
+ state.taskText.push(message.text);
16014
+ return;
16015
+ }
16016
+ if (message.type === "status" && message.status) {
16017
+ state.metadata["cursor_sdk.status"] = message.status;
16018
+ }
16019
+ }
16020
+ async function handleToolMessage(state, message) {
16021
+ const callId = message.call_id;
16022
+ if (!callId) {
16023
+ return;
16024
+ }
16025
+ if (message.status === "running") {
16026
+ if (!state.activeToolSpans.has(callId)) {
16027
+ state.activeToolSpans.set(
16028
+ callId,
16029
+ await startToolSpan(state, {
16030
+ args: message.args,
16031
+ callId,
16032
+ name: message.name,
16033
+ status: message.status,
16034
+ truncated: message.truncated
16035
+ })
16036
+ );
16037
+ }
16038
+ return;
16039
+ }
16040
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
16041
+ args: message.args,
16042
+ callId,
16043
+ name: message.name,
16044
+ status: message.status,
16045
+ truncated: message.truncated
16046
+ });
16047
+ finishToolSpan(toolState, {
16048
+ error: message.status === "error" ? stringifyUnknown(message.result) : void 0,
16049
+ metadata: {
16050
+ "cursor_sdk.tool.status": message.status
16051
+ },
16052
+ output: message.result
16053
+ });
16054
+ state.activeToolSpans.delete(callId);
16055
+ }
16056
+ async function handleConversation(state, turns) {
16057
+ state.conversationOutput = turns;
16058
+ for (const turn of turns) {
16059
+ if (turn.type === "agentConversationTurn") {
16060
+ for (const step of turn.turn?.steps ?? []) {
16061
+ await handleConversationStep(state, step);
16062
+ }
16063
+ } else if (turn.type === "shellConversationTurn") {
16064
+ const command = turn.turn?.shellCommand?.command;
16065
+ if (command) {
16066
+ const callId = `shell:${state.activeToolSpans.size}:${command}`;
16067
+ const toolState = await startToolSpan(state, {
16068
+ args: turn.turn?.shellCommand,
16069
+ callId,
16070
+ name: "shell",
16071
+ status: "completed"
16072
+ });
16073
+ finishToolSpan(toolState, {
16074
+ metadata: { "cursor_sdk.tool.status": "completed" },
16075
+ output: turn.turn?.shellOutput
16076
+ });
16077
+ }
16078
+ }
16079
+ }
16080
+ }
16081
+ async function handleConversationStep(state, step) {
16082
+ if (step.type === "assistantMessage" && typeof step.message?.text === "string") {
16083
+ state.conversationText.push(step.message.text);
16084
+ return;
16085
+ }
16086
+ if (step.type !== "toolCall") {
16087
+ return;
16088
+ }
16089
+ const toolCall = step.message;
16090
+ const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
16091
+ const toolState = await startToolSpan(state, {
16092
+ args: extractToolArgs(toolCall),
16093
+ callId,
16094
+ name: extractToolName(toolCall),
16095
+ status: toolCall?.status,
16096
+ toolCall
16097
+ });
16098
+ finishToolSpan(toolState, {
16099
+ error: toolCall?.status === "error" ? stringifyUnknown(toolCall.result) : void 0,
16100
+ metadata: {
16101
+ "cursor_sdk.tool.status": toolCall?.status ?? "completed"
16102
+ },
16103
+ output: extractToolResult(toolCall)
16104
+ });
16105
+ }
16106
+ function handleStepUpdate(state, step) {
16107
+ state.metrics["cursor_sdk.steps"] = (state.metrics["cursor_sdk.steps"] ?? 0) + 1;
16108
+ if (step.type) {
16109
+ const stepTypes = state.metadata["cursor_sdk.step_types"];
16110
+ if (Array.isArray(stepTypes)) {
16111
+ if (!stepTypes.includes(step.type)) {
16112
+ stepTypes.push(step.type);
16113
+ }
16114
+ } else {
16115
+ state.metadata["cursor_sdk.step_types"] = [step.type];
16116
+ }
16117
+ }
16118
+ if (step.type === "assistantMessage" && typeof step.message?.text === "string") {
16119
+ state.stepText.push(step.message.text);
16120
+ }
16121
+ }
16122
+ async function startToolSpan(state, args) {
16123
+ const name = args.name || "unknown";
16124
+ const metadata = {
16125
+ "cursor_sdk.tool.status": args.status,
16126
+ "gen_ai.tool.call.id": args.callId,
16127
+ "gen_ai.tool.name": name
16128
+ };
16129
+ if (args.truncated?.args !== void 0) {
16130
+ metadata["cursor_sdk.tool.args_truncated"] = args.truncated.args;
16131
+ }
16132
+ if (args.truncated?.result !== void 0) {
16133
+ metadata["cursor_sdk.tool.result_truncated"] = args.truncated.result;
16134
+ }
16135
+ const span = startSpan({
16136
+ event: {
16137
+ input: args.args,
16138
+ metadata
16139
+ },
16140
+ name: `tool: ${name}`,
16141
+ parent: await state.span.export(),
16142
+ spanAttributes: { type: "tool" /* TOOL */ }
16143
+ });
16144
+ let subAgentSpan;
16145
+ if (isSubAgentToolName(name)) {
16146
+ subAgentSpan = startSpan({
16147
+ event: {
16148
+ input: args.args,
16149
+ metadata: {
16150
+ "cursor_sdk.subagent.tool_call_id": args.callId,
16151
+ "gen_ai.tool.name": name
16152
+ }
16153
+ },
16154
+ name: formatSubAgentSpanName2(args.toolCall, args.args),
16155
+ parent: await span.export(),
16156
+ spanAttributes: { type: "task" /* TASK */ }
16157
+ });
16158
+ }
16159
+ return { span, subAgentSpan };
16160
+ }
16161
+ function finishToolSpan(toolState, result) {
16162
+ try {
16163
+ if (result.error) {
16164
+ safeLog(toolState.span, {
16165
+ error: result.error,
16166
+ metadata: result.metadata,
16167
+ output: result.output
16168
+ });
16169
+ if (toolState.subAgentSpan) {
16170
+ safeLog(toolState.subAgentSpan, {
16171
+ error: result.error,
16172
+ metadata: result.metadata,
16173
+ output: result.output
16174
+ });
16175
+ }
16176
+ } else {
16177
+ safeLog(toolState.span, {
16178
+ metadata: result.metadata,
16179
+ output: result.output
16180
+ });
16181
+ if (toolState.subAgentSpan) {
16182
+ safeLog(toolState.subAgentSpan, {
16183
+ metadata: result.metadata,
16184
+ output: result.output
16185
+ });
16186
+ }
16187
+ }
16188
+ } finally {
16189
+ toolState.subAgentSpan?.end();
16190
+ toolState.span.end();
16191
+ }
16192
+ }
16193
+ async function finalizeCursorRun(state, params = {}) {
16194
+ if (state.finalized) {
16195
+ return;
16196
+ }
16197
+ state.finalized = true;
16198
+ const error = params.error;
16199
+ const result = params.result ?? state.lastResult;
16200
+ const output = params.output ?? result?.result ?? state.run?.result ?? (state.conversationText.length > 0 ? state.conversationText.join("\n") : void 0) ?? state.conversationOutput ?? (state.streamText.length > 0 ? state.streamText.join("") : void 0) ?? (state.deltaText.length > 0 ? state.deltaText.join("") : void 0) ?? (state.stepText.length > 0 ? state.stepText.join("\n") : void 0) ?? (state.taskText.length > 0 ? state.taskText.join("\n") : void 0);
16201
+ try {
16202
+ const metadata = {
16203
+ ...state.metadata,
16204
+ ...state.run ? extractRunMetadata(state.run) : {},
16205
+ ...result ? extractRunResultMetadata(result) : {}
16206
+ };
16207
+ if (error) {
16208
+ safeLog(state.span, {
16209
+ error: error instanceof Error ? error.message : String(error),
16210
+ metadata,
16211
+ metrics: {
16212
+ ...cleanMetrics(state.metrics),
16213
+ ...buildDurationMetrics(state.startTime)
16214
+ },
16215
+ output
16216
+ });
16217
+ } else {
16218
+ safeLog(state.span, {
16219
+ metadata,
16220
+ metrics: {
16221
+ ...cleanMetrics(state.metrics),
16222
+ ...buildDurationMetrics(state.startTime)
16223
+ },
16224
+ output
16225
+ });
16226
+ }
16227
+ } finally {
16228
+ endOpenToolSpans(state);
16229
+ state.span.end();
16230
+ }
16231
+ }
16232
+ function endOpenToolSpans(state, error) {
16233
+ for (const [, toolState] of state.activeToolSpans) {
16234
+ finishToolSpan(toolState, { error });
16235
+ }
16236
+ state.activeToolSpans.clear();
16237
+ }
16238
+ function sanitizeUserMessage(message) {
16239
+ if (typeof message === "string" || message === void 0) {
16240
+ return message;
16241
+ }
16242
+ return {
16243
+ ...message,
16244
+ images: message.images?.map((image) => {
16245
+ const imageRecord = image;
16246
+ return {
16247
+ ...typeof imageRecord.url === "string" ? { url: imageRecord.url } : {},
16248
+ ...typeof imageRecord.mimeType === "string" ? { mimeType: imageRecord.mimeType } : {},
16249
+ ...image.dimension ? { dimension: image.dimension } : {},
16250
+ hasData: typeof imageRecord.data === "string"
16251
+ };
16252
+ })
16253
+ };
16254
+ }
16255
+ function extractAgentOptionsMetadata(options) {
16256
+ if (!options) {
16257
+ return {};
16258
+ }
16259
+ return {
16260
+ ...extractModelMetadata(options.model),
16261
+ ...options.agentId ? { "cursor_sdk.agent_id": options.agentId } : {},
16262
+ ...options.name ? { "cursor_sdk.agent_name": options.name } : {},
16263
+ ...options.local ? {
16264
+ "cursor_sdk.runtime": "local",
16265
+ "cursor_sdk.local.cwd": Array.isArray(options.local.cwd) ? options.local.cwd.join(",") : options.local.cwd
16266
+ } : {},
16267
+ ...options.cloud ? {
16268
+ "cursor_sdk.runtime": "cloud",
16269
+ "cursor_sdk.cloud.auto_create_pr": options.cloud.autoCreatePR,
16270
+ "cursor_sdk.cloud.env_type": options.cloud.env?.type,
16271
+ "cursor_sdk.cloud.env_name": options.cloud.env?.name,
16272
+ "cursor_sdk.cloud.repos": options.cloud.repos?.map((repo) => repo.url).filter((url) => typeof url === "string")
16273
+ } : {}
16274
+ };
16275
+ }
16276
+ function extractSendMetadata(options) {
16277
+ if (!options) {
16278
+ return {};
16279
+ }
16280
+ return {
16281
+ ...extractModelMetadata(options.model),
16282
+ ...options.local?.force !== void 0 ? { "cursor_sdk.local.force": options.local.force } : {}
16283
+ };
16284
+ }
16285
+ function extractAgentMetadata(agent) {
16286
+ return {
16287
+ ...agent.agentId ? { "cursor_sdk.agent_id": agent.agentId } : {},
16288
+ ...extractModelMetadata(agent.model)
16289
+ };
16290
+ }
16291
+ function extractRunMetadata(run) {
16292
+ if (!run) {
16293
+ return {};
16294
+ }
16295
+ return {
16296
+ ...run.id ? { "cursor_sdk.run_id": run.id } : {},
16297
+ ...run.agentId ? { "cursor_sdk.agent_id": run.agentId } : {},
16298
+ ...run.status ? { "cursor_sdk.status": run.status } : {},
16299
+ ...run.durationMs !== void 0 ? { "cursor_sdk.duration_ms": run.durationMs } : {},
16300
+ ...extractModelMetadata(run.model),
16301
+ ...extractGitMetadata(run.git)
16302
+ };
16303
+ }
16304
+ function extractRunResultMetadata(result) {
16305
+ if (!result) {
16306
+ return {};
16307
+ }
16308
+ return {
16309
+ ...result.id ? { "cursor_sdk.run_id": result.id } : {},
16310
+ ...result.status ? { "cursor_sdk.status": result.status } : {},
16311
+ ...result.durationMs !== void 0 ? { "cursor_sdk.duration_ms": result.durationMs } : {},
16312
+ ...extractModelMetadata(result.model),
16313
+ ...extractGitMetadata(result.git)
16314
+ };
16315
+ }
16316
+ function extractGitMetadata(git) {
16317
+ const branches = git?.branches;
16318
+ if (!branches || branches.length === 0) {
16319
+ return {};
16320
+ }
16321
+ return {
16322
+ "cursor_sdk.git.branches": branches.map((branch) => ({
16323
+ branch: branch.branch,
16324
+ prUrl: branch.prUrl,
16325
+ repoUrl: branch.repoUrl
16326
+ }))
16327
+ };
16328
+ }
16329
+ function extractModelMetadata(model) {
16330
+ if (!model?.id) {
16331
+ return {};
16332
+ }
16333
+ return {
16334
+ model: model.id,
16335
+ "cursor_sdk.model": model.id,
16336
+ ...model.params ? { "cursor_sdk.model.params": model.params } : {}
16337
+ };
16338
+ }
16339
+ function addUsageMetrics(metrics, usage) {
16340
+ if (!usage) {
16341
+ return;
16342
+ }
16343
+ if (usage.inputTokens !== void 0) {
16344
+ metrics.prompt_tokens = (metrics.prompt_tokens ?? 0) + usage.inputTokens;
16345
+ }
16346
+ if (usage.outputTokens !== void 0) {
16347
+ metrics.completion_tokens = (metrics.completion_tokens ?? 0) + usage.outputTokens;
16348
+ }
16349
+ if (usage.cacheReadTokens !== void 0) {
16350
+ metrics.prompt_cached_tokens = (metrics.prompt_cached_tokens ?? 0) + usage.cacheReadTokens;
16351
+ }
16352
+ if (usage.cacheWriteTokens !== void 0) {
16353
+ metrics.prompt_cache_creation_tokens = (metrics.prompt_cache_creation_tokens ?? 0) + usage.cacheWriteTokens;
16354
+ }
16355
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0) + (metrics.prompt_cached_tokens ?? 0) + (metrics.prompt_cache_creation_tokens ?? 0);
16356
+ }
16357
+ function buildDurationMetrics(startTime) {
16358
+ const end = getCurrentUnixTimestamp();
16359
+ return {
16360
+ duration: end - startTime,
16361
+ end,
16362
+ start: startTime
16363
+ };
16364
+ }
16365
+ function extractToolName(toolCall) {
16366
+ if (!toolCall) {
16367
+ return "unknown";
16368
+ }
16369
+ if (typeof toolCall.name === "string") {
16370
+ return toolCall.name;
16371
+ }
16372
+ if (typeof toolCall.type === "string") {
16373
+ return toolCall.type;
16374
+ }
16375
+ return "unknown";
16376
+ }
16377
+ function extractToolArgs(toolCall) {
16378
+ return toolCall && "args" in toolCall ? toolCall.args : void 0;
16379
+ }
16380
+ function extractToolResult(toolCall) {
16381
+ return toolCall && "result" in toolCall ? toolCall.result : void 0;
16382
+ }
16383
+ function isSubAgentToolName(name) {
16384
+ return name === "Agent" || name === "Task" || name === "task";
16385
+ }
16386
+ function formatSubAgentSpanName2(toolCall, args) {
16387
+ const details = toolCall ?? args;
16388
+ const description = getString(details, "description") ?? getString(details, "subagent_type") ?? getString(details, "type") ?? getString(details, "name");
16389
+ return description ? `Agent: ${description}` : "Agent: sub-agent";
16390
+ }
16391
+ function getString(obj, key) {
16392
+ const value = obj?.[key];
16393
+ return typeof value === "string" ? value : void 0;
16394
+ }
16395
+ function stringifyUnknown(value) {
16396
+ if (value instanceof Error) {
16397
+ return value.message;
16398
+ }
16399
+ if (typeof value === "string") {
16400
+ return value;
16401
+ }
16402
+ try {
16403
+ return JSON.stringify(value);
16404
+ } catch {
16405
+ return String(value);
16406
+ }
16407
+ }
16408
+ function safeLog(span, event) {
16409
+ try {
16410
+ span.log(event);
16411
+ } catch (error) {
16412
+ logInstrumentationError("Cursor SDK span log", error);
16413
+ }
16414
+ }
16415
+ function logInstrumentationError(context, error) {
16416
+ debugLogger.error(`Error processing ${context}:`, error);
16417
+ }
16418
+ function cleanMetrics(metrics) {
16419
+ const cleaned = {};
16420
+ for (const [key, value] of Object.entries(metrics)) {
16421
+ if (value !== void 0 && Number.isFinite(value)) {
16422
+ cleaned[key] = value;
16423
+ }
16424
+ }
16425
+ return cleaned;
16426
+ }
16427
+
16428
+ // src/instrumentation/plugins/google-genai-channels.ts
16429
+ var googleGenAIChannels = defineChannels("@google/genai", {
16430
+ generateContent: channel({
16431
+ channelName: "models.generateContent",
16432
+ kind: "async"
16433
+ }),
16434
+ generateContentStream: channel({
16435
+ channelName: "models.generateContentStream",
16436
+ kind: "async"
16437
+ }),
16438
+ embedContent: channel({
16439
+ channelName: "models.embedContent",
16440
+ kind: "async"
16441
+ })
16442
+ });
16443
+
16444
+ // src/instrumentation/plugins/google-genai-plugin.ts
16445
+ var GOOGLE_GENAI_INTERNAL_CONTEXT = {
16446
+ caller_filename: "<node-internal>",
16447
+ caller_functionname: "<node-internal>",
16448
+ caller_lineno: 0
16449
+ };
16450
+ function createWrapperParityEvent(args) {
16451
+ return {
16452
+ context: GOOGLE_GENAI_INTERNAL_CONTEXT,
16453
+ input: args.input,
16454
+ metadata: args.metadata
16455
+ };
16456
+ }
16457
+ var GoogleGenAIPlugin = class extends BasePlugin {
16458
+ onEnable() {
16459
+ this.subscribeToGoogleGenAIChannels();
16460
+ }
16461
+ onDisable() {
16462
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
16463
+ }
16464
+ subscribeToGoogleGenAIChannels() {
16465
+ this.subscribeToGenerateContentChannel();
16466
+ this.subscribeToGenerateContentStreamChannel();
16467
+ this.subscribeToEmbedContentChannel();
16468
+ }
16469
+ subscribeToGenerateContentChannel() {
16470
+ const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
16471
+ const states = /* @__PURE__ */ new WeakMap();
16472
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
16473
+ tracingChannel2,
16474
+ states,
16475
+ (event) => {
16476
+ const params = event.arguments[0];
16477
+ const input = serializeGenerateContentInput(params);
16478
+ const metadata = extractGenerateContentMetadata(params);
16479
+ const span = startSpan({
16480
+ name: "generate_content",
16481
+ spanAttributes: {
16482
+ type: "llm" /* LLM */
16483
+ },
15202
16484
  event: createWrapperParityEvent({ input, metadata })
15203
16485
  });
15204
16486
  return {
@@ -15235,7 +16517,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
15235
16517
  const responseMetadata = extractResponseMetadata(event.result);
15236
16518
  spanState.span.log({
15237
16519
  ...responseMetadata ? { metadata: responseMetadata } : {},
15238
- metrics: cleanMetrics(
16520
+ metrics: cleanMetrics2(
15239
16521
  extractGenerateContentMetrics(
15240
16522
  event.result,
15241
16523
  spanState.startTime
@@ -15336,7 +16618,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
15336
16618
  const output = summarizeEmbedContentOutput(event.result);
15337
16619
  spanState.span.log({
15338
16620
  ...output ? { output } : {},
15339
- metrics: cleanMetrics(
16621
+ metrics: cleanMetrics2(
15340
16622
  extractEmbedContentMetrics(event.result, spanState.startTime)
15341
16623
  )
15342
16624
  });
@@ -15433,7 +16715,7 @@ function patchGoogleGenAIStreamingResult(args) {
15433
16715
  );
15434
16716
  span.log({
15435
16717
  ...responseMetadata ? { metadata: responseMetadata } : {},
15436
- metrics: cleanMetrics(metricsWithoutEnd),
16718
+ metrics: cleanMetrics2(metricsWithoutEnd),
15437
16719
  output: options.result.aggregated
15438
16720
  });
15439
16721
  span.end(typeof end === "number" ? { endTime: end } : void 0);
@@ -15858,7 +17140,7 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
15858
17140
  }
15859
17141
  return { aggregated, metrics };
15860
17142
  }
15861
- function cleanMetrics(metrics) {
17143
+ function cleanMetrics2(metrics) {
15862
17144
  const cleaned = {};
15863
17145
  for (const [key, value] of Object.entries(metrics)) {
15864
17146
  if (value !== null && value !== void 0) {
@@ -15942,6 +17224,8 @@ var REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
15942
17224
  "stop",
15943
17225
  "stream",
15944
17226
  "temperature",
17227
+ "tool_choice",
17228
+ "tools",
15945
17229
  "top_p"
15946
17230
  ]);
15947
17231
  var RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
@@ -16204,7 +17488,10 @@ function aggregateChatCompletionChunks2(chunks) {
16204
17488
  for (const chunk of chunks) {
16205
17489
  for (const choice of chunk.choices ?? []) {
16206
17490
  const index = typeof choice.index === "number" ? choice.index : 0;
16207
- const existing = aggregatedChoices.get(index) ?? { content: "" };
17491
+ const existing = aggregatedChoices.get(index) ?? {
17492
+ content: "",
17493
+ toolCallsByIndex: /* @__PURE__ */ new Map()
17494
+ };
16208
17495
  const delta = isObject(choice.delta) ? choice.delta : void 0;
16209
17496
  const message = isObject(choice.message) ? choice.message : void 0;
16210
17497
  if (typeof delta?.content === "string") {
@@ -16220,6 +17507,10 @@ function aggregateChatCompletionChunks2(chunks) {
16220
17507
  if (choice.finish_reason !== void 0) {
16221
17508
  existing.finish_reason = choice.finish_reason;
16222
17509
  }
17510
+ const toolCallDeltas = getChatToolCallDeltas(delta) ?? getChatToolCallDeltas(message);
17511
+ if (toolCallDeltas) {
17512
+ mergeChatToolCallDeltas(existing.toolCallsByIndex, toolCallDeltas);
17513
+ }
16223
17514
  aggregatedChoices.set(index, existing);
16224
17515
  }
16225
17516
  }
@@ -16228,12 +17519,72 @@ function aggregateChatCompletionChunks2(chunks) {
16228
17519
  index,
16229
17520
  message: {
16230
17521
  content: choice.content,
16231
- role: choice.role ?? "assistant"
17522
+ role: choice.role ?? "assistant",
17523
+ ...choice.toolCallsByIndex.size > 0 ? {
17524
+ tool_calls: [...choice.toolCallsByIndex.entries()].sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([, toolCall]) => toolCall)
17525
+ } : {}
16232
17526
  },
16233
17527
  ...choice.finish_reason !== void 0 ? { finish_reason: choice.finish_reason } : {}
16234
17528
  }))
16235
17529
  };
16236
17530
  }
17531
+ function getChatToolCallDeltas(value) {
17532
+ if (!Array.isArray(value?.tool_calls)) {
17533
+ return void 0;
17534
+ }
17535
+ const toolCalls = value.tool_calls.filter((toolCall) => isObject(toolCall));
17536
+ return toolCalls.length > 0 ? toolCalls : void 0;
17537
+ }
17538
+ function mergeChatToolCallDeltas(toolCallsByIndex, toolCallDeltas) {
17539
+ for (const toolDelta of toolCallDeltas) {
17540
+ const toolIndex = typeof toolDelta.index === "number" && toolDelta.index >= 0 ? toolDelta.index : 0;
17541
+ const existing = toolCallsByIndex.get(toolIndex);
17542
+ if (!existing) {
17543
+ toolCallsByIndex.set(toolIndex, createChatToolCall(toolDelta));
17544
+ continue;
17545
+ }
17546
+ mergeChatToolCall(existing, toolDelta);
17547
+ }
17548
+ }
17549
+ function createChatToolCall(toolDelta) {
17550
+ const toolFunction = isObject(toolDelta.function) ? toolDelta.function : {};
17551
+ const toolCallFunction = {
17552
+ arguments: typeof toolFunction.arguments === "string" ? toolFunction.arguments : ""
17553
+ };
17554
+ if (typeof toolFunction.name === "string") {
17555
+ toolCallFunction.name = toolFunction.name;
17556
+ }
17557
+ const toolCall = {
17558
+ function: toolCallFunction
17559
+ };
17560
+ if (typeof toolDelta.id === "string") {
17561
+ toolCall.id = toolDelta.id;
17562
+ }
17563
+ if (typeof toolDelta.type === "string") {
17564
+ toolCall.type = toolDelta.type;
17565
+ }
17566
+ return toolCall;
17567
+ }
17568
+ function mergeChatToolCall(existing, toolDelta) {
17569
+ const currentFunction = isObject(existing.function) ? existing.function : {};
17570
+ const deltaFunction = isObject(toolDelta.function) ? toolDelta.function : {};
17571
+ const currentArguments = typeof currentFunction.arguments === "string" ? currentFunction.arguments : "";
17572
+ const deltaArguments = typeof deltaFunction.arguments === "string" ? deltaFunction.arguments : "";
17573
+ if (typeof toolDelta.id === "string" && typeof existing.id !== "string") {
17574
+ existing.id = toolDelta.id;
17575
+ }
17576
+ if (typeof toolDelta.type === "string" && typeof existing.type !== "string") {
17577
+ existing.type = toolDelta.type;
17578
+ }
17579
+ const nextFunction = {
17580
+ ...currentFunction,
17581
+ arguments: `${currentArguments}${deltaArguments}`
17582
+ };
17583
+ if (typeof deltaFunction.name === "string" && typeof currentFunction.name !== "string") {
17584
+ nextFunction.name = deltaFunction.name;
17585
+ }
17586
+ existing.function = nextFunction;
17587
+ }
16237
17588
  function aggregateTextGenerationStreamChunks(chunks) {
16238
17589
  if (chunks.length === 0) {
16239
17590
  return void 0;
@@ -18278,6 +19629,8 @@ var MISTRAL_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
18278
19629
  "presence_penalty",
18279
19630
  "randomSeed",
18280
19631
  "random_seed",
19632
+ "reasoningEffort",
19633
+ "reasoning_effort",
18281
19634
  "responseFormat",
18282
19635
  "response_format",
18283
19636
  "safePrompt",
@@ -18401,22 +19754,114 @@ function extractMistralStreamingMetrics(result, startTime) {
18401
19754
  if (startTime) {
18402
19755
  metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
18403
19756
  }
18404
- return metrics;
19757
+ return metrics;
19758
+ }
19759
+ function extractDeltaText(content) {
19760
+ if (typeof content === "string") {
19761
+ return content;
19762
+ }
19763
+ if (!Array.isArray(content)) {
19764
+ return void 0;
19765
+ }
19766
+ const textParts = content.map((part) => {
19767
+ if (!isObject(part) || part.type !== "text") {
19768
+ return "";
19769
+ }
19770
+ return typeof part.text === "string" ? part.text : "";
19771
+ }).filter((part) => part.length > 0);
19772
+ return textParts.length > 0 ? textParts.join("") : void 0;
19773
+ }
19774
+ function normalizeMistralTextContentPart(part) {
19775
+ if (!isObject(part) || part.type !== "text" || typeof part.text !== "string") {
19776
+ return void 0;
19777
+ }
19778
+ return {
19779
+ type: "text",
19780
+ text: part.text
19781
+ };
19782
+ }
19783
+ function normalizeMistralThinkingContentPart(part) {
19784
+ if (!isObject(part) || part.type !== "thinking") {
19785
+ return void 0;
19786
+ }
19787
+ const thinking = Array.isArray(part.thinking) ? part.thinking.map((thinkingPart) => normalizeMistralTextContentPart(thinkingPart)).filter(
19788
+ (thinkingPart) => thinkingPart !== void 0 && typeof thinkingPart.text === "string"
19789
+ ) : [];
19790
+ return {
19791
+ type: "thinking",
19792
+ thinking
19793
+ };
19794
+ }
19795
+ function normalizeMistralContentParts(content) {
19796
+ if (!Array.isArray(content)) {
19797
+ return [];
19798
+ }
19799
+ return content.map((part) => {
19800
+ return normalizeMistralTextContentPart(part) || normalizeMistralThinkingContentPart(part);
19801
+ }).filter((part) => part !== void 0);
19802
+ }
19803
+ function mergeMistralTextSegments(left, right) {
19804
+ const merged = left.map((part) => ({ ...part }));
19805
+ for (const part of right) {
19806
+ const lastPart = merged[merged.length - 1];
19807
+ if (lastPart && lastPart.type === "text" && typeof lastPart.text === "string" && typeof part.text === "string") {
19808
+ lastPart.text += part.text;
19809
+ continue;
19810
+ }
19811
+ merged.push({ ...part });
19812
+ }
19813
+ return merged;
19814
+ }
19815
+ function mergeMistralContentParts(left, right) {
19816
+ const merged = [...(left || []).map((part) => structuredClone(part))];
19817
+ for (const part of right) {
19818
+ const lastPart = merged[merged.length - 1];
19819
+ if (part.type === "text" && lastPart?.type === "text" && typeof lastPart.text === "string" && typeof part.text === "string") {
19820
+ lastPart.text += part.text;
19821
+ continue;
19822
+ }
19823
+ if (part.type === "thinking" && lastPart?.type === "thinking" && Array.isArray(lastPart.thinking) && Array.isArray(part.thinking)) {
19824
+ lastPart.thinking = mergeMistralTextSegments(
19825
+ lastPart.thinking,
19826
+ part.thinking
19827
+ );
19828
+ continue;
19829
+ }
19830
+ merged.push(structuredClone(part));
19831
+ }
19832
+ return merged;
18405
19833
  }
18406
- function extractDeltaText(content) {
19834
+ function appendMistralContent(accumulator, content) {
18407
19835
  if (typeof content === "string") {
18408
- return content;
19836
+ if (accumulator.contentParts) {
19837
+ accumulator.contentParts = mergeMistralContentParts(
19838
+ accumulator.contentParts,
19839
+ [{ type: "text", text: content }]
19840
+ );
19841
+ return;
19842
+ }
19843
+ accumulator.content = `${accumulator.content || ""}${content}`;
19844
+ return;
18409
19845
  }
18410
- if (!Array.isArray(content)) {
18411
- return void 0;
19846
+ const normalizedContentParts = normalizeMistralContentParts(content);
19847
+ if (normalizedContentParts.length === 0) {
19848
+ return;
18412
19849
  }
18413
- const textParts = content.map((part) => {
18414
- if (!isObject(part) || part.type !== "text") {
18415
- return "";
19850
+ const hasStructuredContent = normalizedContentParts.some(
19851
+ (part) => part.type !== "text"
19852
+ );
19853
+ if (!accumulator.contentParts && !hasStructuredContent) {
19854
+ const text = extractDeltaText(content);
19855
+ if (text) {
19856
+ accumulator.content = `${accumulator.content || ""}${text}`;
18416
19857
  }
18417
- return typeof part.text === "string" ? part.text : "";
18418
- }).filter((part) => part.length > 0);
18419
- return textParts.length > 0 ? textParts.join("") : void 0;
19858
+ return;
19859
+ }
19860
+ accumulator.contentParts = mergeMistralContentParts(
19861
+ accumulator.contentParts || (accumulator.content ? [{ type: "text", text: accumulator.content }] : []),
19862
+ normalizedContentParts
19863
+ );
19864
+ delete accumulator.content;
18420
19865
  }
18421
19866
  function getDeltaToolCalls(delta) {
18422
19867
  const toolCalls = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
@@ -18586,10 +20031,7 @@ function aggregateMistralStreamChunks(chunks) {
18586
20031
  if (!accumulator.role && typeof delta.role === "string") {
18587
20032
  accumulator.role = delta.role;
18588
20033
  }
18589
- const deltaText = extractDeltaText(delta.content);
18590
- if (deltaText) {
18591
- accumulator.content = `${accumulator.content || ""}${deltaText}`;
18592
- }
20034
+ appendMistralContent(accumulator, delta.content);
18593
20035
  accumulator.toolCalls = mergeToolCallDeltas(
18594
20036
  accumulator.toolCalls,
18595
20037
  getDeltaToolCalls(delta)
@@ -18607,7 +20049,7 @@ function aggregateMistralStreamChunks(chunks) {
18607
20049
  index: choice.index,
18608
20050
  message: {
18609
20051
  ...choice.role ? { role: choice.role } : {},
18610
- content: choice.content ?? null,
20052
+ content: choice.contentParts ?? choice.content ?? null,
18611
20053
  ...choice.toolCalls ? { toolCalls: choice.toolCalls } : {}
18612
20054
  },
18613
20055
  ...choice.finishReason !== void 0 ? { finishReason: choice.finishReason } : {}
@@ -18846,7 +20288,7 @@ var GoogleADKPlugin = class extends BasePlugin {
18846
20288
  start: (event) => {
18847
20289
  const req = event.arguments[0] ?? {};
18848
20290
  const tool = event.self;
18849
- const toolName = extractToolName(req, tool);
20291
+ const toolName = extractToolName2(req, tool);
18850
20292
  const parentSpan = findToolParentSpan(
18851
20293
  req,
18852
20294
  this.activeAgentSpans,
@@ -18885,7 +20327,7 @@ var GoogleADKPlugin = class extends BasePlugin {
18885
20327
  metrics.duration = end - state.startTime;
18886
20328
  state.span.log({
18887
20329
  output: event.result,
18888
- metrics: cleanMetrics2(metrics)
20330
+ metrics: cleanMetrics3(metrics)
18889
20331
  });
18890
20332
  } finally {
18891
20333
  state.span.end();
@@ -19104,7 +20546,7 @@ function extractToolCallId(req) {
19104
20546
  const toolContext = req.toolContext;
19105
20547
  return toolContext?.functionCallId;
19106
20548
  }
19107
- function extractToolName(req, tool) {
20549
+ function extractToolName2(req, tool) {
19108
20550
  if (typeof tool?.name === "string" && tool.name.length > 0) {
19109
20551
  return tool.name;
19110
20552
  }
@@ -19152,7 +20594,7 @@ function finalizeRunnerSpan(state, activeRunnerSpans) {
19152
20594
  }
19153
20595
  state.span.log({
19154
20596
  output: lastEvent ? extractEventOutput(lastEvent) : void 0,
19155
- metrics: cleanMetrics2(metrics)
20597
+ metrics: cleanMetrics3(metrics)
19156
20598
  });
19157
20599
  } finally {
19158
20600
  cleanupActiveRunnerSpan(state, activeRunnerSpans);
@@ -19169,7 +20611,7 @@ function finalizeAgentSpan(state, activeAgentSpans) {
19169
20611
  metrics.duration = end - state.startTime;
19170
20612
  state.span.log({
19171
20613
  output: lastEvent ? extractEventOutput(lastEvent) : void 0,
19172
- metrics: cleanMetrics2(metrics)
20614
+ metrics: cleanMetrics3(metrics)
19173
20615
  });
19174
20616
  } finally {
19175
20617
  cleanupActiveAgentSpan(state, activeAgentSpans);
@@ -19255,7 +20697,7 @@ function populateUsageMetrics2(metrics, usage) {
19255
20697
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
19256
20698
  }
19257
20699
  }
19258
- function cleanMetrics2(metrics) {
20700
+ function cleanMetrics3(metrics) {
19259
20701
  const cleaned = {};
19260
20702
  for (const [key, value] of Object.entries(metrics)) {
19261
20703
  if (value !== null && value !== void 0) {
@@ -19383,6 +20825,11 @@ var CHAT_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
19383
20825
  "strictTools",
19384
20826
  "strict_tools",
19385
20827
  "temperature",
20828
+ "thinking",
20829
+ "thinkingTokenBudget",
20830
+ "thinkingType",
20831
+ "thinking_token_budget",
20832
+ "thinking_type",
19386
20833
  "toolChoice",
19387
20834
  "tool_choice"
19388
20835
  ]);
@@ -19603,6 +21050,11 @@ function mergeUsageMetrics(metrics, usage) {
19603
21050
  "tokens",
19604
21051
  tokenContainer.totalTokens ?? tokenContainer.total_tokens
19605
21052
  );
21053
+ setMetricIfNumber(
21054
+ metrics,
21055
+ "reasoning_tokens",
21056
+ tokenContainer.reasoningTokens ?? tokenContainer.reasoning_tokens ?? tokenContainer.thinkingTokens ?? tokenContainer.thinking_tokens
21057
+ );
19606
21058
  }
19607
21059
  const billedUnits = (isObject(source.billedUnits) ? source.billedUnits : void 0) || (isObject(source.billed_units) ? source.billed_units : void 0);
19608
21060
  if (billedUnits) {
@@ -19683,13 +21135,87 @@ function extractV8DeltaText(chunk) {
19683
21135
  }
19684
21136
  return void 0;
19685
21137
  }
21138
+ function getV8ContentIndex(chunk) {
21139
+ return typeof chunk.index === "number" ? chunk.index : 0;
21140
+ }
21141
+ function toContentBlockType(value) {
21142
+ return value === "text" || value === "thinking" ? value : void 0;
21143
+ }
21144
+ function getOrCreateContentBlock(contentBlocksByIndex, contentBlockOrder, index) {
21145
+ if (!contentBlockOrder.includes(index)) {
21146
+ contentBlockOrder.push(index);
21147
+ }
21148
+ if (!(index in contentBlocksByIndex)) {
21149
+ contentBlocksByIndex[index] = {
21150
+ text: "",
21151
+ thinking: ""
21152
+ };
21153
+ }
21154
+ return contentBlocksByIndex[index];
21155
+ }
21156
+ function appendV8ContentBlock(contentBlocksByIndex, contentBlockOrder, index, content) {
21157
+ if (typeof content === "string") {
21158
+ const block2 = getOrCreateContentBlock(
21159
+ contentBlocksByIndex,
21160
+ contentBlockOrder,
21161
+ index
21162
+ );
21163
+ block2.type ??= "text";
21164
+ block2.text += content;
21165
+ return;
21166
+ }
21167
+ if (!isObject(content)) {
21168
+ return;
21169
+ }
21170
+ const block = getOrCreateContentBlock(
21171
+ contentBlocksByIndex,
21172
+ contentBlockOrder,
21173
+ index
21174
+ );
21175
+ const contentType = toContentBlockType(content.type);
21176
+ if (contentType) {
21177
+ block.type = contentType;
21178
+ }
21179
+ if (typeof content.text === "string") {
21180
+ block.type ??= "text";
21181
+ block.text += content.text;
21182
+ }
21183
+ if (typeof content.thinking === "string") {
21184
+ block.type ??= "thinking";
21185
+ block.thinking += content.thinking;
21186
+ }
21187
+ }
21188
+ function serializeAggregatedContentBlocks(contentBlocksByIndex, contentBlockOrder) {
21189
+ return contentBlockOrder.sort((left, right) => left - right).flatMap((index) => {
21190
+ const block = contentBlocksByIndex[index];
21191
+ if (!block) {
21192
+ return [];
21193
+ }
21194
+ if (block.type === "thinking" && block.thinking.length > 0) {
21195
+ return [{ type: "thinking", thinking: block.thinking }];
21196
+ }
21197
+ if (block.text.length > 0) {
21198
+ return [{ type: "text", text: block.text }];
21199
+ }
21200
+ if (block.thinking.length > 0) {
21201
+ return [{ type: "thinking", thinking: block.thinking }];
21202
+ }
21203
+ return [];
21204
+ });
21205
+ }
21206
+ function hasThinkingContent(contentBlocks) {
21207
+ return contentBlocks.some((block) => block.type === "thinking");
21208
+ }
19686
21209
  function aggregateCohereChatStreamChunks(chunks) {
19687
21210
  const textDeltas = [];
21211
+ const contentBlocksByIndex = {};
21212
+ const contentBlockOrder = [];
19688
21213
  const toolCallsByIndex = {};
19689
21214
  const toolCallOrder = [];
19690
21215
  let terminalResponse;
19691
21216
  let role;
19692
21217
  let finishReason;
21218
+ let toolPlan = "";
19693
21219
  let metadata = {};
19694
21220
  let metrics = {};
19695
21221
  for (const chunk of chunks) {
@@ -19747,12 +21273,36 @@ function aggregateCohereChatStreamChunks(chunks) {
19747
21273
  continue;
19748
21274
  }
19749
21275
  if (eventType === "content-delta") {
21276
+ appendV8ContentBlock(
21277
+ contentBlocksByIndex,
21278
+ contentBlockOrder,
21279
+ getV8ContentIndex(chunk),
21280
+ isObject(chunk.delta) && isObject(chunk.delta.message) ? chunk.delta.message.content : void 0
21281
+ );
19750
21282
  const text = extractV8DeltaText(chunk);
19751
21283
  if (text) {
19752
21284
  textDeltas.push(text);
19753
21285
  }
19754
21286
  continue;
19755
21287
  }
21288
+ if (eventType === "content-start") {
21289
+ appendV8ContentBlock(
21290
+ contentBlocksByIndex,
21291
+ contentBlockOrder,
21292
+ getV8ContentIndex(chunk),
21293
+ isObject(chunk.delta) && isObject(chunk.delta.message) ? chunk.delta.message.content : void 0
21294
+ );
21295
+ continue;
21296
+ }
21297
+ if (eventType === "tool-plan-delta") {
21298
+ if (isObject(chunk.delta) && isObject(chunk.delta.message)) {
21299
+ const deltaToolPlan = typeof chunk.delta.message.toolPlan === "string" ? chunk.delta.message.toolPlan : typeof chunk.delta.message.tool_plan === "string" ? chunk.delta.message.tool_plan : void 0;
21300
+ if (deltaToolPlan) {
21301
+ toolPlan += deltaToolPlan;
21302
+ }
21303
+ }
21304
+ continue;
21305
+ }
19756
21306
  if (eventType === "tool-call-start") {
19757
21307
  const toolCalls = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
19758
21308
  Array.isArray(chunk.delta.message.toolCalls) ? chunk.delta.message.toolCalls : chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
@@ -19806,13 +21356,26 @@ function aggregateCohereChatStreamChunks(chunks) {
19806
21356
  }
19807
21357
  }
19808
21358
  const mergedToolCalls = toolCallOrder.sort((left, right) => left - right).map((index) => toolCallsByIndex[index]).filter((toolCall) => isObject(toolCall));
21359
+ const aggregatedContentBlocks = serializeAggregatedContentBlocks(
21360
+ contentBlocksByIndex,
21361
+ contentBlockOrder
21362
+ );
19809
21363
  let output = extractCohereChatOutput(terminalResponse);
19810
21364
  if (output === void 0) {
19811
21365
  const mergedText = textDeltas.join("");
19812
- if (mergedToolCalls.length > 0 || role || mergedText.length > 0) {
21366
+ const shouldUseStructuredContent = hasThinkingContent(aggregatedContentBlocks) || toolPlan.length > 0;
21367
+ if (shouldUseStructuredContent) {
21368
+ output = {
21369
+ ...role ? { role } : {},
21370
+ ...aggregatedContentBlocks.length > 0 ? { content: aggregatedContentBlocks } : {},
21371
+ ...toolPlan.length > 0 ? { toolPlan } : {},
21372
+ ...mergedToolCalls.length > 0 ? { toolCalls: mergedToolCalls } : {}
21373
+ };
21374
+ } else if (mergedToolCalls.length > 0 || role || mergedText.length > 0 || aggregatedContentBlocks.length > 0) {
21375
+ const textContent = mergedText.length > 0 ? mergedText : aggregatedContentBlocks[0]?.type === "text" ? aggregatedContentBlocks[0].text : void 0;
19813
21376
  output = {
19814
21377
  ...role ? { role } : {},
19815
- ...mergedText.length > 0 ? { content: mergedText } : {},
21378
+ ...textContent ? { content: textContent } : {},
19816
21379
  ...mergedToolCalls.length > 0 ? { toolCalls: mergedToolCalls } : {}
19817
21380
  };
19818
21381
  }
@@ -19830,6 +21393,98 @@ function aggregateCohereChatStreamChunks(chunks) {
19830
21393
  };
19831
21394
  }
19832
21395
 
21396
+ // src/instrumentation/plugins/groq-channels.ts
21397
+ var groqChannels = defineChannels("groq-sdk", {
21398
+ chatCompletionsCreate: channel({
21399
+ channelName: "chat.completions.create",
21400
+ kind: "async"
21401
+ }),
21402
+ embeddingsCreate: channel(
21403
+ {
21404
+ channelName: "embeddings.create",
21405
+ kind: "async"
21406
+ }
21407
+ )
21408
+ });
21409
+
21410
+ // src/instrumentation/plugins/groq-plugin.ts
21411
+ var GroqPlugin = class extends BasePlugin {
21412
+ onEnable() {
21413
+ this.unsubscribers.push(
21414
+ traceStreamingChannel(groqChannels.chatCompletionsCreate, {
21415
+ name: "groq.chat.completions.create",
21416
+ type: "llm" /* LLM */,
21417
+ extractInput: ([params]) => {
21418
+ const { messages, ...metadata } = params;
21419
+ return {
21420
+ input: processInputAttachments(messages),
21421
+ metadata: { ...metadata, provider: "groq" }
21422
+ };
21423
+ },
21424
+ extractOutput: (result) => result?.choices,
21425
+ extractMetrics: (result, startTime) => {
21426
+ const metrics = parseGroqMetrics(result);
21427
+ if (startTime) {
21428
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
21429
+ }
21430
+ return metrics;
21431
+ },
21432
+ aggregateChunks: aggregateGroqChatCompletionChunks
21433
+ })
21434
+ );
21435
+ this.unsubscribers.push(
21436
+ traceAsyncChannel(groqChannels.embeddingsCreate, {
21437
+ name: "groq.embeddings.create",
21438
+ type: "llm" /* LLM */,
21439
+ extractInput: ([params]) => {
21440
+ const { input, ...metadata } = params;
21441
+ return {
21442
+ input,
21443
+ metadata: { ...metadata, provider: "groq" }
21444
+ };
21445
+ },
21446
+ extractOutput: (result) => {
21447
+ const embedding = result?.data?.[0]?.embedding;
21448
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
21449
+ },
21450
+ extractMetrics: (result) => parseGroqMetrics(result)
21451
+ })
21452
+ );
21453
+ }
21454
+ onDisable() {
21455
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
21456
+ }
21457
+ };
21458
+ function parseGroqMetrics(result) {
21459
+ const metrics = parseMetricsFromUsage(result?.usage);
21460
+ const xGroq = result?.x_groq;
21461
+ if (!xGroq || typeof xGroq !== "object") {
21462
+ return metrics;
21463
+ }
21464
+ const extraUsage = "usage" in xGroq ? xGroq.usage : void 0;
21465
+ if (!extraUsage || typeof extraUsage !== "object") {
21466
+ return metrics;
21467
+ }
21468
+ const dramCachedTokens = extraUsage["dram_cached_tokens"];
21469
+ const sramCachedTokens = extraUsage["sram_cached_tokens"];
21470
+ return {
21471
+ ...metrics,
21472
+ ...typeof dramCachedTokens === "number" ? { dram_cached_tokens: dramCachedTokens } : {},
21473
+ ...typeof sramCachedTokens === "number" ? { sram_cached_tokens: sramCachedTokens } : {}
21474
+ };
21475
+ }
21476
+ function aggregateGroqChatCompletionChunks(chunks, streamResult, endEvent) {
21477
+ const aggregated = aggregateChatCompletionChunks(
21478
+ chunks,
21479
+ streamResult,
21480
+ endEvent
21481
+ );
21482
+ return {
21483
+ metrics: aggregated.metrics,
21484
+ output: aggregated.output
21485
+ };
21486
+ }
21487
+
19833
21488
  // src/instrumentation/braintrust-plugin.ts
19834
21489
  var BraintrustPlugin = class extends BasePlugin {
19835
21490
  config;
@@ -19837,6 +21492,7 @@ var BraintrustPlugin = class extends BasePlugin {
19837
21492
  anthropicPlugin = null;
19838
21493
  aiSDKPlugin = null;
19839
21494
  claudeAgentSDKPlugin = null;
21495
+ cursorSDKPlugin = null;
19840
21496
  googleGenAIPlugin = null;
19841
21497
  huggingFacePlugin = null;
19842
21498
  openRouterPlugin = null;
@@ -19844,6 +21500,7 @@ var BraintrustPlugin = class extends BasePlugin {
19844
21500
  mistralPlugin = null;
19845
21501
  googleADKPlugin = null;
19846
21502
  coherePlugin = null;
21503
+ groqPlugin = null;
19847
21504
  constructor(config = {}) {
19848
21505
  super();
19849
21506
  this.config = config;
@@ -19866,6 +21523,10 @@ var BraintrustPlugin = class extends BasePlugin {
19866
21523
  this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
19867
21524
  this.claudeAgentSDKPlugin.enable();
19868
21525
  }
21526
+ if (integrations.cursorSDK !== false && integrations.cursor !== false) {
21527
+ this.cursorSDKPlugin = new CursorSDKPlugin();
21528
+ this.cursorSDKPlugin.enable();
21529
+ }
19869
21530
  if (integrations.googleGenAI !== false && integrations.google !== false) {
19870
21531
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
19871
21532
  this.googleGenAIPlugin.enable();
@@ -19894,6 +21555,10 @@ var BraintrustPlugin = class extends BasePlugin {
19894
21555
  this.coherePlugin = new CoherePlugin();
19895
21556
  this.coherePlugin.enable();
19896
21557
  }
21558
+ if (integrations.groq !== false) {
21559
+ this.groqPlugin = new GroqPlugin();
21560
+ this.groqPlugin.enable();
21561
+ }
19897
21562
  }
19898
21563
  onDisable() {
19899
21564
  if (this.openaiPlugin) {
@@ -19912,6 +21577,10 @@ var BraintrustPlugin = class extends BasePlugin {
19912
21577
  this.claudeAgentSDKPlugin.disable();
19913
21578
  this.claudeAgentSDKPlugin = null;
19914
21579
  }
21580
+ if (this.cursorSDKPlugin) {
21581
+ this.cursorSDKPlugin.disable();
21582
+ this.cursorSDKPlugin = null;
21583
+ }
19915
21584
  if (this.googleGenAIPlugin) {
19916
21585
  this.googleGenAIPlugin.disable();
19917
21586
  this.googleGenAIPlugin = null;
@@ -19940,6 +21609,10 @@ var BraintrustPlugin = class extends BasePlugin {
19940
21609
  this.coherePlugin.disable();
19941
21610
  this.coherePlugin = null;
19942
21611
  }
21612
+ if (this.groqPlugin) {
21613
+ this.groqPlugin.disable();
21614
+ this.groqPlugin = null;
21615
+ }
19943
21616
  }
19944
21617
  };
19945
21618
 
@@ -20013,6 +21686,8 @@ var PluginRegistry = class {
20013
21686
  google: true,
20014
21687
  huggingface: true,
20015
21688
  claudeAgentSDK: true,
21689
+ cursor: true,
21690
+ cursorSDK: true,
20016
21691
  openrouter: true,
20017
21692
  openrouterAgent: true,
20018
21693
  mistral: true,
@@ -20029,7 +21704,11 @@ var PluginRegistry = class {
20029
21704
  if (disabledList) {
20030
21705
  const disabled = disabledList.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
20031
21706
  for (const sdk of disabled) {
20032
- integrations[sdk] = false;
21707
+ if (sdk === "cursor-sdk") {
21708
+ integrations.cursorSDK = false;
21709
+ } else {
21710
+ integrations[sdk] = false;
21711
+ }
20033
21712
  }
20034
21713
  }
20035
21714
  return { integrations };
@@ -20289,8 +21968,10 @@ __export(exports_exports, {
20289
21968
  wrapAnthropic: () => wrapAnthropic,
20290
21969
  wrapClaudeAgentSDK: () => wrapClaudeAgentSDK,
20291
21970
  wrapCohere: () => wrapCohere,
21971
+ wrapCursorSDK: () => wrapCursorSDK,
20292
21972
  wrapGoogleADK: () => wrapGoogleADK,
20293
21973
  wrapGoogleGenAI: () => wrapGoogleGenAI,
21974
+ wrapGroq: () => wrapGroq,
20294
21975
  wrapHuggingFace: () => wrapHuggingFace,
20295
21976
  wrapMastraAgent: () => wrapMastraAgent,
20296
21977
  wrapMistral: () => wrapMistral,
@@ -21905,6 +23586,130 @@ function claudeAgentSDKProxy(sdk) {
21905
23586
  });
21906
23587
  }
21907
23588
 
23589
+ // src/wrappers/cursor-sdk.ts
23590
+ var WRAPPED_AGENT2 = Symbol.for("braintrust.cursor-sdk.wrapped-agent");
23591
+ function wrapCursorSDK(sdk) {
23592
+ if (!sdk || typeof sdk !== "object") {
23593
+ return sdk;
23594
+ }
23595
+ const maybeSDK = sdk;
23596
+ if (!maybeSDK.Agent || typeof maybeSDK.Agent !== "function") {
23597
+ console.warn("Unsupported Cursor SDK. Not wrapping.");
23598
+ return sdk;
23599
+ }
23600
+ const target = isModuleNamespace2(sdk) ? Object.setPrototypeOf({}, sdk) : sdk;
23601
+ return new Proxy(target, {
23602
+ get(target2, prop, receiver) {
23603
+ const value = Reflect.get(target2, prop, receiver);
23604
+ if (prop === "Agent" && typeof value === "function") {
23605
+ return wrapCursorAgentClass(value);
23606
+ }
23607
+ if (typeof value === "function") {
23608
+ return value.bind(target2);
23609
+ }
23610
+ return value;
23611
+ }
23612
+ });
23613
+ }
23614
+ function isModuleNamespace2(obj) {
23615
+ if (!obj || typeof obj !== "object") {
23616
+ return false;
23617
+ }
23618
+ if (obj.constructor?.name === "Module") {
23619
+ return true;
23620
+ }
23621
+ const keys = Object.keys(obj);
23622
+ if (keys.length === 0) {
23623
+ return false;
23624
+ }
23625
+ const descriptor = Object.getOwnPropertyDescriptor(obj, keys[0]);
23626
+ return descriptor ? !descriptor.configurable && !descriptor.writable : false;
23627
+ }
23628
+ function wrapCursorAgentClass(Agent) {
23629
+ const cache = /* @__PURE__ */ new Map();
23630
+ return new Proxy(Agent, {
23631
+ get(target, prop, receiver) {
23632
+ if (cache.has(prop)) {
23633
+ return cache.get(prop);
23634
+ }
23635
+ const value = Reflect.get(target, prop, receiver);
23636
+ if (prop === "create" && typeof value === "function") {
23637
+ const wrapped = async function(options) {
23638
+ const args = [options];
23639
+ return cursorSDKChannels.create.tracePromise(
23640
+ async () => wrapCursorAgent(await Reflect.apply(value, target, args)),
23641
+ { arguments: args }
23642
+ );
23643
+ };
23644
+ cache.set(prop, wrapped);
23645
+ return wrapped;
23646
+ }
23647
+ if (prop === "resume" && typeof value === "function") {
23648
+ const wrapped = async function(agentId, options) {
23649
+ const args = [agentId, options];
23650
+ return cursorSDKChannels.resume.tracePromise(
23651
+ async () => wrapCursorAgent(await Reflect.apply(value, target, args)),
23652
+ { arguments: args }
23653
+ );
23654
+ };
23655
+ cache.set(prop, wrapped);
23656
+ return wrapped;
23657
+ }
23658
+ if (prop === "prompt" && typeof value === "function") {
23659
+ const wrapped = async function(message, options) {
23660
+ const args = [message, options];
23661
+ return cursorSDKChannels.prompt.tracePromise(
23662
+ () => Reflect.apply(value, target, args),
23663
+ { arguments: args }
23664
+ );
23665
+ };
23666
+ cache.set(prop, wrapped);
23667
+ return wrapped;
23668
+ }
23669
+ if (typeof value === "function") {
23670
+ const bound = value.bind(target);
23671
+ cache.set(prop, bound);
23672
+ return bound;
23673
+ }
23674
+ return value;
23675
+ }
23676
+ });
23677
+ }
23678
+ function wrapCursorAgent(agent) {
23679
+ if (!agent || typeof agent !== "object") {
23680
+ return agent;
23681
+ }
23682
+ if (agent[WRAPPED_AGENT2]) {
23683
+ return agent;
23684
+ }
23685
+ const proxy = new Proxy(agent, {
23686
+ get(target, prop, receiver) {
23687
+ if (prop === WRAPPED_AGENT2) {
23688
+ return true;
23689
+ }
23690
+ const value = Reflect.get(target, prop, receiver);
23691
+ if (prop === "send" && typeof value === "function") {
23692
+ return function(message, options) {
23693
+ const args = [message, options];
23694
+ return cursorSDKChannels.send.tracePromise(
23695
+ () => Reflect.apply(value, target, args),
23696
+ {
23697
+ agent: target,
23698
+ arguments: args,
23699
+ operation: "send"
23700
+ }
23701
+ );
23702
+ };
23703
+ }
23704
+ if (typeof value === "function") {
23705
+ return value.bind(target);
23706
+ }
23707
+ return value;
23708
+ }
23709
+ });
23710
+ return proxy;
23711
+ }
23712
+
21908
23713
  // src/wrappers/google-genai.ts
21909
23714
  function wrapGoogleGenAI(googleGenAI) {
21910
23715
  if (!googleGenAI || typeof googleGenAI !== "object") {
@@ -22658,6 +24463,94 @@ function wrapRerank3(rerank) {
22658
24463
  });
22659
24464
  }
22660
24465
 
24466
+ // src/wrappers/groq.ts
24467
+ function wrapGroq(groq) {
24468
+ if (isSupportedGroqClient(groq)) {
24469
+ return groqProxy(groq);
24470
+ }
24471
+ console.warn("Unsupported Groq library. Not wrapping.");
24472
+ return groq;
24473
+ }
24474
+ function isRecord3(value) {
24475
+ return typeof value === "object" && value !== null;
24476
+ }
24477
+ function hasFunction4(value, methodName) {
24478
+ return isRecord3(value) && methodName in value && typeof value[methodName] === "function";
24479
+ }
24480
+ function hasChat2(value) {
24481
+ return isRecord3(value) && isRecord3(value.completions) && hasFunction4(value.completions, "create");
24482
+ }
24483
+ function hasEmbeddings2(value) {
24484
+ return hasFunction4(value, "create");
24485
+ }
24486
+ function isSupportedGroqClient(value) {
24487
+ return isRecord3(value) && (value.chat !== void 0 && hasChat2(value.chat) || value.embeddings !== void 0 && hasEmbeddings2(value.embeddings));
24488
+ }
24489
+ function groqProxy(groq) {
24490
+ const privateMethodWorkaroundCache = /* @__PURE__ */ new WeakMap();
24491
+ const completionProxy = groq.chat?.completions ? new Proxy(groq.chat.completions, {
24492
+ get(target, prop, receiver) {
24493
+ if (prop === "create") {
24494
+ return wrapChatCompletionsCreate(target.create.bind(target));
24495
+ }
24496
+ return Reflect.get(target, prop, receiver);
24497
+ }
24498
+ }) : void 0;
24499
+ const chatProxy3 = groq.chat ? new Proxy(groq.chat, {
24500
+ get(target, prop, receiver) {
24501
+ if (prop === "completions") {
24502
+ return completionProxy ?? target.completions;
24503
+ }
24504
+ return Reflect.get(target, prop, receiver);
24505
+ }
24506
+ }) : void 0;
24507
+ const embeddingsProxy3 = groq.embeddings ? new Proxy(groq.embeddings, {
24508
+ get(target, prop, receiver) {
24509
+ if (prop === "create") {
24510
+ return wrapEmbeddingsCreate2(target.create.bind(target));
24511
+ }
24512
+ return Reflect.get(target, prop, receiver);
24513
+ }
24514
+ }) : void 0;
24515
+ const topLevelProxy = new Proxy(groq, {
24516
+ get(target, prop, receiver) {
24517
+ switch (prop) {
24518
+ case "chat":
24519
+ return chatProxy3 ?? target.chat;
24520
+ case "embeddings":
24521
+ return embeddingsProxy3 ?? target.embeddings;
24522
+ }
24523
+ const value = Reflect.get(target, prop, target);
24524
+ if (typeof value !== "function") {
24525
+ return value;
24526
+ }
24527
+ const cachedValue = privateMethodWorkaroundCache.get(value);
24528
+ if (cachedValue) {
24529
+ return cachedValue;
24530
+ }
24531
+ const thisBoundValue = function(...args) {
24532
+ const thisArg = this === topLevelProxy ? target : this;
24533
+ const output = Reflect.apply(value, thisArg, args);
24534
+ return output === target ? topLevelProxy : output;
24535
+ };
24536
+ privateMethodWorkaroundCache.set(value, thisBoundValue);
24537
+ return thisBoundValue;
24538
+ }
24539
+ });
24540
+ return topLevelProxy;
24541
+ }
24542
+ function wrapChatCompletionsCreate(create) {
24543
+ return (request, options) => groqChannels.chatCompletionsCreate.tracePromise(
24544
+ () => create(request, options),
24545
+ { arguments: [request] }
24546
+ );
24547
+ }
24548
+ function wrapEmbeddingsCreate2(create) {
24549
+ return (request, options) => groqChannels.embeddingsCreate.tracePromise(() => create(request, options), {
24550
+ arguments: [request]
24551
+ });
24552
+ }
24553
+
22661
24554
  // src/wrappers/vitest/context-manager.ts
22662
24555
  var VitestContextManager = class {
22663
24556
  /**
@@ -26638,8 +28531,10 @@ export {
26638
28531
  wrapAnthropic,
26639
28532
  wrapClaudeAgentSDK,
26640
28533
  wrapCohere,
28534
+ wrapCursorSDK,
26641
28535
  wrapGoogleADK,
26642
28536
  wrapGoogleGenAI,
28537
+ wrapGroq,
26643
28538
  wrapHuggingFace,
26644
28539
  wrapMastraAgent,
26645
28540
  wrapMistral,