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
@@ -2123,6 +2123,7 @@ var TopicMapData = z6.object({
2123
2123
  report_key: z6.string().optional(),
2124
2124
  topic_names: z6.record(z6.string()).optional(),
2125
2125
  generation_settings: TopicMapGenerationSettings.optional(),
2126
+ disable_reconciliation: z6.boolean().optional(),
2126
2127
  distance_threshold: z6.number().optional()
2127
2128
  });
2128
2129
  var BatchedFacetData = z6.object({
@@ -2453,28 +2454,6 @@ var EnvVar = z6.object({
2453
2454
  secret_type: z6.union([z6.string(), z6.null()]).optional(),
2454
2455
  secret_category: z6.enum(["env_var", "ai_provider", "sandbox_provider"]).optional().default("env_var")
2455
2456
  });
2456
- var EvalStatusPageTheme = z6.enum(["light", "dark"]);
2457
- var EvalStatusPageConfig = z6.object({
2458
- score_columns: z6.union([z6.array(z6.string()), z6.null()]),
2459
- metric_columns: z6.union([z6.array(z6.string()), z6.null()]),
2460
- grouping_field: z6.union([z6.string(), z6.null()]),
2461
- filter: z6.union([z6.string(), z6.null()]),
2462
- sort_by: z6.union([z6.string(), z6.null()]),
2463
- sort_order: z6.union([z6.enum(["asc", "desc"]), z6.null()]),
2464
- api_key: z6.union([z6.string(), z6.null()])
2465
- }).partial();
2466
- var EvalStatusPage = z6.object({
2467
- id: z6.string().uuid(),
2468
- project_id: z6.string().uuid(),
2469
- user_id: z6.union([z6.string(), z6.null()]).optional(),
2470
- created: z6.union([z6.string(), z6.null()]).optional(),
2471
- deleted_at: z6.union([z6.string(), z6.null()]).optional(),
2472
- name: z6.string(),
2473
- description: z6.union([z6.string(), z6.null()]).optional(),
2474
- logo_url: z6.union([z6.string(), z6.null()]).optional(),
2475
- theme: EvalStatusPageTheme,
2476
- config: EvalStatusPageConfig
2477
- });
2478
2457
  var RepoInfo = z6.union([
2479
2458
  z6.object({
2480
2459
  commit: z6.union([z6.string(), z6.null()]),
@@ -2501,6 +2480,15 @@ var Experiment = z6.object({
2501
2480
  deleted_at: z6.union([z6.string(), z6.null()]).optional(),
2502
2481
  dataset_id: z6.union([z6.string(), z6.null()]).optional(),
2503
2482
  dataset_version: z6.union([z6.string(), z6.null()]).optional(),
2483
+ internal_metadata: z6.union([
2484
+ z6.object({
2485
+ dataset_filter: z6.union([
2486
+ z6.object({}).partial().passthrough(),
2487
+ z6.null()
2488
+ ])
2489
+ }).partial().passthrough(),
2490
+ z6.null()
2491
+ ]).optional(),
2504
2492
  parameters_id: z6.union([z6.string(), z6.null()]).optional(),
2505
2493
  parameters_version: z6.union([z6.string(), z6.null()]).optional(),
2506
2494
  public: z6.boolean(),
@@ -3237,14 +3225,21 @@ var ProjectAutomation = z6.object({
3237
3225
  z6.object({ type: z6.literal("log_spans") }),
3238
3226
  z6.object({ type: z6.literal("btql_query"), btql_query: z6.string() })
3239
3227
  ]),
3228
+ scope: z6.union([SpanScope, TraceScope, GroupScope, z6.null()]).optional(),
3240
3229
  export_path: z6.string(),
3241
3230
  format: z6.enum(["jsonl", "parquet"]),
3242
3231
  interval_seconds: z6.number().gte(1).lte(2592e3),
3243
- credentials: z6.object({
3244
- type: z6.literal("aws_iam"),
3245
- role_arn: z6.string(),
3246
- external_id: z6.string()
3247
- }),
3232
+ credentials: z6.union([
3233
+ z6.object({
3234
+ type: z6.literal("aws_iam"),
3235
+ role_arn: z6.string(),
3236
+ external_id: z6.string()
3237
+ }),
3238
+ z6.object({
3239
+ type: z6.literal("gcp_service_account"),
3240
+ service_account_email: z6.string()
3241
+ })
3242
+ ]),
3248
3243
  batch_size: z6.union([z6.number(), z6.null()]).optional()
3249
3244
  }),
3250
3245
  z6.object({
@@ -3624,7 +3619,7 @@ var ViewOptions = z6.union([
3624
3619
  z6.object({ from: z6.string(), to: z6.string() }),
3625
3620
  z6.null()
3626
3621
  ]),
3627
- queryShape: z6.union([z6.enum(["traces", "spans"]), z6.null()]),
3622
+ queryShape: z6.union([z6.enum(["traces", "spans", "topics"]), z6.null()]),
3628
3623
  cluster: z6.union([z6.string(), z6.null()]),
3629
3624
  freezeColumns: z6.union([z6.boolean(), z6.null()])
3630
3625
  }).partial(),
@@ -4640,6 +4635,19 @@ var RESET_CONTEXT_MANAGER_STATE = Symbol.for(
4640
4635
  "braintrust.resetContextManagerState"
4641
4636
  );
4642
4637
  var DEFAULT_MAX_REQUEST_SIZE = 6 * 1024 * 1024;
4638
+ var datasetSnapshotRegisterResponseSchema = z8.object({
4639
+ dataset_snapshot: DatasetSnapshot,
4640
+ found_existing: z8.boolean().optional()
4641
+ });
4642
+ var datasetRestorePreviewResultSchema = z8.object({
4643
+ rows_to_restore: z8.number(),
4644
+ rows_to_delete: z8.number()
4645
+ });
4646
+ var datasetRestoreResultSchema = z8.object({
4647
+ xact_id: z8.string().nullable(),
4648
+ rows_restored: z8.number(),
4649
+ rows_deleted: z8.number()
4650
+ });
4643
4651
  var parametersRowSchema = z8.object({
4644
4652
  id: z8.string().uuid(),
4645
4653
  _xact_id: z8.string(),
@@ -6649,6 +6657,33 @@ Error: ${errorText}`;
6649
6657
  this.queue.enforceQueueSizeLimit(enforce);
6650
6658
  }
6651
6659
  };
6660
+ function isDatasetSnapshotNameLookup(lookup) {
6661
+ return "snapshotName" in lookup;
6662
+ }
6663
+ function assertDatasetSnapshotLookup(lookup) {
6664
+ const hasSnapshotName = lookup.snapshotName !== void 0;
6665
+ const hasXactId = lookup.xactId !== void 0;
6666
+ if (hasSnapshotName === hasXactId) {
6667
+ throw new Error("Exactly one of snapshotName or xactId must be provided");
6668
+ }
6669
+ }
6670
+ function getExperimentDatasetFilter({
6671
+ dataset,
6672
+ _internal_btql
6673
+ }) {
6674
+ if (_internal_btql !== void 0) {
6675
+ return _internal_btql;
6676
+ }
6677
+ if (!(dataset instanceof Dataset2)) {
6678
+ return void 0;
6679
+ }
6680
+ const datasetFilter = Reflect.get(dataset, "_internal_btql");
6681
+ return isObject(datasetFilter) ? datasetFilter : void 0;
6682
+ }
6683
+ function getInternalBtqlLimit(internalBtql) {
6684
+ const limit = internalBtql?.["limit"];
6685
+ return typeof limit === "number" ? limit : void 0;
6686
+ }
6652
6687
  function init(projectOrOptions, optionalOptions) {
6653
6688
  const options = (() => {
6654
6689
  if (typeof projectOrOptions === "string") {
@@ -6667,6 +6702,7 @@ function init(projectOrOptions, optionalOptions) {
6667
6702
  experiment,
6668
6703
  description,
6669
6704
  dataset,
6705
+ _internal_btql,
6670
6706
  parameters,
6671
6707
  baseExperiment,
6672
6708
  isPublic,
@@ -6775,16 +6811,24 @@ function init(projectOrOptions, optionalOptions) {
6775
6811
  args["ancestor_commits"] = await isomorph_default.getPastNAncestors();
6776
6812
  }
6777
6813
  if (dataset !== void 0) {
6778
- if ("id" in dataset && typeof dataset.id === "string" && !("__braintrust_dataset_marker" in dataset)) {
6779
- args["dataset_id"] = dataset.id;
6780
- if ("version" in dataset && dataset.version !== void 0) {
6781
- args["dataset_version"] = dataset.version;
6782
- }
6783
- } else {
6784
- args["dataset_id"] = await dataset.id;
6785
- args["dataset_version"] = await dataset.version();
6814
+ const datasetSelection = await serializeDatasetForExperiment({
6815
+ dataset,
6816
+ state
6817
+ });
6818
+ args["dataset_id"] = datasetSelection.datasetId;
6819
+ if (datasetSelection.datasetVersion !== void 0) {
6820
+ args["dataset_version"] = datasetSelection.datasetVersion;
6786
6821
  }
6787
6822
  }
6823
+ const datasetFilter = getExperimentDatasetFilter({
6824
+ dataset,
6825
+ _internal_btql
6826
+ });
6827
+ if (datasetFilter !== void 0) {
6828
+ args["internal_metadata"] = {
6829
+ dataset_filter: datasetFilter
6830
+ };
6831
+ }
6788
6832
  if (parameters !== void 0) {
6789
6833
  if (RemoteEvalParameters.isParameters(parameters)) {
6790
6834
  args["parameters_id"] = parameters.id;
@@ -6838,13 +6882,160 @@ function init(projectOrOptions, optionalOptions) {
6838
6882
  const ret = new Experiment2(
6839
6883
  state,
6840
6884
  lazyMetadata,
6841
- dataset !== void 0 && "version" in dataset ? dataset : void 0
6885
+ dataset !== void 0 ? dataset : void 0
6842
6886
  );
6843
6887
  if (options.setCurrent ?? true) {
6844
6888
  state.currentExperiment = ret;
6845
6889
  }
6846
6890
  return ret;
6847
6891
  }
6892
+ async function getDatasetSnapshots(params) {
6893
+ const { state, datasetId } = params;
6894
+ return DatasetSnapshot.array().parse(
6895
+ await state.appConn().post_json("api/dataset_snapshot/get", {
6896
+ dataset_id: datasetId,
6897
+ ..."snapshotName" in params ? { name: params.snapshotName } : {},
6898
+ ..."xactId" in params ? { xact_id: params.xactId } : {}
6899
+ })
6900
+ );
6901
+ }
6902
+ async function getDatasetSnapshot(params) {
6903
+ assertDatasetSnapshotLookup(params);
6904
+ const snapshots = await getDatasetSnapshots(params);
6905
+ if (snapshots.length > 1) {
6906
+ throw new Error(
6907
+ 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}`
6908
+ );
6909
+ }
6910
+ return snapshots[0];
6911
+ }
6912
+ function normalizeDatasetSelection({
6913
+ version,
6914
+ environment,
6915
+ snapshotName
6916
+ }) {
6917
+ if (version !== void 0) {
6918
+ return { version };
6919
+ }
6920
+ if (snapshotName !== void 0) {
6921
+ return { snapshotName };
6922
+ }
6923
+ if (environment !== void 0) {
6924
+ return { environment };
6925
+ }
6926
+ return {};
6927
+ }
6928
+ async function resolveDatasetSnapshotName({
6929
+ state,
6930
+ datasetId,
6931
+ snapshotName
6932
+ }) {
6933
+ const match = await getDatasetSnapshot({
6934
+ state,
6935
+ datasetId,
6936
+ snapshotName
6937
+ });
6938
+ if (match === void 0) {
6939
+ throw new Error(
6940
+ `Dataset snapshot "${snapshotName}" not found for ${datasetId}`
6941
+ );
6942
+ }
6943
+ return match.xact_id;
6944
+ }
6945
+ async function resolveDatasetSnapshotNameForMetadata({
6946
+ state,
6947
+ lazyMetadata,
6948
+ snapshotName
6949
+ }) {
6950
+ const metadata = await lazyMetadata.get();
6951
+ return await resolveDatasetSnapshotName({
6952
+ state,
6953
+ datasetId: metadata.dataset.id,
6954
+ snapshotName
6955
+ });
6956
+ }
6957
+ async function resolveDatasetEnvironment({
6958
+ state,
6959
+ datasetId,
6960
+ environment
6961
+ }) {
6962
+ const environmentObjectPath = `environment-object/dataset/${datasetId}/${encodeURIComponent(environment)}`;
6963
+ const response = state.orgName == null ? await state.apiConn().get_json(environmentObjectPath) : await state.apiConn().get_json(environmentObjectPath, {
6964
+ org_name: state.orgName
6965
+ });
6966
+ return z8.object({ object_version: z8.string() }).parse(response).object_version;
6967
+ }
6968
+ async function resolveDatasetEnvironmentForMetadata({
6969
+ state,
6970
+ lazyMetadata,
6971
+ environment
6972
+ }) {
6973
+ const metadata = await lazyMetadata.get();
6974
+ return await resolveDatasetEnvironment({
6975
+ state,
6976
+ datasetId: metadata.dataset.id,
6977
+ environment
6978
+ });
6979
+ }
6980
+ async function serializeDatasetForExperiment({
6981
+ dataset,
6982
+ state
6983
+ }) {
6984
+ if (!Dataset2.isDataset(dataset)) {
6985
+ const selection2 = normalizeDatasetSelection(dataset);
6986
+ if (selection2.version !== void 0) {
6987
+ return {
6988
+ datasetId: dataset.id,
6989
+ datasetVersion: selection2.version
6990
+ };
6991
+ }
6992
+ if (selection2.snapshotName !== void 0) {
6993
+ return {
6994
+ datasetId: dataset.id,
6995
+ datasetVersion: await resolveDatasetSnapshotName({
6996
+ state,
6997
+ datasetId: dataset.id,
6998
+ snapshotName: selection2.snapshotName
6999
+ })
7000
+ };
7001
+ }
7002
+ if (selection2.environment !== void 0) {
7003
+ return {
7004
+ datasetId: dataset.id,
7005
+ datasetVersion: await resolveDatasetEnvironment({
7006
+ state,
7007
+ datasetId: dataset.id,
7008
+ environment: selection2.environment
7009
+ })
7010
+ };
7011
+ }
7012
+ return {
7013
+ datasetId: dataset.id
7014
+ };
7015
+ }
7016
+ const evalData = await dataset.toEvalData();
7017
+ const selection = normalizeDatasetSelection({
7018
+ version: evalData.dataset_version,
7019
+ environment: evalData.dataset_environment,
7020
+ snapshotName: evalData.dataset_snapshot_name
7021
+ });
7022
+ if (selection.version !== void 0) {
7023
+ return {
7024
+ datasetId: evalData.dataset_id,
7025
+ datasetVersion: selection.version
7026
+ };
7027
+ }
7028
+ const datasetVersion = await dataset.version();
7029
+ if (datasetVersion !== void 0) {
7030
+ return {
7031
+ datasetId: evalData.dataset_id,
7032
+ datasetVersion
7033
+ };
7034
+ }
7035
+ return {
7036
+ datasetId: evalData.dataset_id
7037
+ };
7038
+ }
6848
7039
  function initDataset(projectOrOptions, optionalOptions) {
6849
7040
  const options = (() => {
6850
7041
  if (typeof projectOrOptions === "string") {
@@ -6863,6 +7054,8 @@ function initDataset(projectOrOptions, optionalOptions) {
6863
7054
  dataset,
6864
7055
  description,
6865
7056
  version,
7057
+ snapshotName,
7058
+ environment,
6866
7059
  appUrl,
6867
7060
  apiKey,
6868
7061
  orgName,
@@ -6874,6 +7067,14 @@ function initDataset(projectOrOptions, optionalOptions) {
6874
7067
  state: stateArg,
6875
7068
  _internal_btql
6876
7069
  } = options;
7070
+ const selection = normalizeDatasetSelection({
7071
+ version,
7072
+ environment,
7073
+ snapshotName
7074
+ });
7075
+ const normalizedVersion = selection.version;
7076
+ const normalizedEnvironment = selection.environment;
7077
+ const normalizedSnapshotName = selection.snapshotName;
6877
7078
  const state = stateArg ?? _globalState;
6878
7079
  const lazyMetadata = new LazyValue(
6879
7080
  async () => {
@@ -6907,13 +7108,38 @@ function initDataset(projectOrOptions, optionalOptions) {
6907
7108
  };
6908
7109
  }
6909
7110
  );
6910
- return new Dataset2(
7111
+ const resolvedVersion = normalizedVersion !== void 0 ? normalizedVersion : normalizedSnapshotName !== void 0 ? new LazyValue(async () => {
7112
+ return await resolveDatasetSnapshotNameForMetadata({
7113
+ state,
7114
+ lazyMetadata,
7115
+ snapshotName: normalizedSnapshotName
7116
+ });
7117
+ }) : normalizedEnvironment !== void 0 ? new LazyValue(async () => {
7118
+ return await resolveDatasetEnvironmentForMetadata({
7119
+ state,
7120
+ lazyMetadata,
7121
+ environment: normalizedEnvironment
7122
+ });
7123
+ }) : void 0;
7124
+ const datasetObject = new Dataset2(
6911
7125
  stateArg ?? _globalState,
6912
7126
  lazyMetadata,
6913
- version,
7127
+ typeof resolvedVersion === "string" ? resolvedVersion : void 0,
6914
7128
  legacy,
6915
- _internal_btql
7129
+ _internal_btql,
7130
+ resolvedVersion instanceof LazyValue || normalizedEnvironment !== void 0 || normalizedSnapshotName !== void 0 ? {
7131
+ ...resolvedVersion instanceof LazyValue ? {
7132
+ lazyPinnedVersion: resolvedVersion
7133
+ } : {},
7134
+ ...normalizedEnvironment !== void 0 ? {
7135
+ pinnedEnvironment: normalizedEnvironment
7136
+ } : {},
7137
+ ...normalizedSnapshotName !== void 0 ? {
7138
+ pinnedSnapshotName: normalizedSnapshotName
7139
+ } : {}
7140
+ } : void 0
6916
7141
  );
7142
+ return datasetObject;
6917
7143
  }
6918
7144
  async function computeLoggerMetadata(state, {
6919
7145
  project_name,
@@ -7405,11 +7631,20 @@ var ObjectFetcher = class {
7405
7631
  async getState() {
7406
7632
  throw new Error("ObjectFetcher subclasses must have a 'getState' method");
7407
7633
  }
7634
+ getPinnedVersion() {
7635
+ return this.pinnedVersion;
7636
+ }
7637
+ setPinnedVersion(pinnedVersion) {
7638
+ this.pinnedVersion = pinnedVersion;
7639
+ }
7640
+ getInternalBtql() {
7641
+ return this._internal_btql;
7642
+ }
7408
7643
  async *fetchRecordsFromApi(batchSize) {
7409
7644
  const state = await this.getState();
7410
7645
  const objectId = await this.id;
7411
7646
  const batchLimit = batchSize ?? DEFAULT_FETCH_BATCH_SIZE;
7412
- const internalLimit = this._internal_btql?.limit;
7647
+ const internalLimit = getInternalBtqlLimit(this._internal_btql);
7413
7648
  const limit = batchSize !== void 0 ? batchSize : internalLimit ?? batchLimit;
7414
7649
  const internalBtqlWithoutReservedQueryKeys = Object.fromEntries(
7415
7650
  Object.entries(this._internal_btql ?? {}).filter(
@@ -8223,7 +8458,7 @@ function splitLoggingData({
8223
8458
  return [serializableInternalData, lazyInternalData];
8224
8459
  }
8225
8460
  var Dataset2 = class extends ObjectFetcher {
8226
- constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql) {
8461
+ constructor(state, lazyMetadata, pinnedVersion, legacy, _internal_btql, pinState) {
8227
8462
  const isLegacyDataset = legacy ?? DEFAULT_IS_LEGACY_DATASET;
8228
8463
  if (isLegacyDataset) {
8229
8464
  debugLogger.forState(state).warn(
@@ -8244,10 +8479,16 @@ var Dataset2 = class extends ObjectFetcher {
8244
8479
  );
8245
8480
  this.state = state;
8246
8481
  this.lazyMetadata = lazyMetadata;
8482
+ this.lazyPinnedVersion = pinState?.lazyPinnedVersion;
8483
+ this.pinnedEnvironment = pinState?.pinnedEnvironment;
8484
+ this.pinnedSnapshotName = pinState?.pinnedSnapshotName;
8247
8485
  }
8248
8486
  lazyMetadata;
8249
8487
  __braintrust_dataset_marker = true;
8250
8488
  newRecords = 0;
8489
+ lazyPinnedVersion;
8490
+ pinnedEnvironment;
8491
+ pinnedSnapshotName;
8251
8492
  get id() {
8252
8493
  return (async () => {
8253
8494
  return (await this.lazyMetadata.get()).dataset.id;
@@ -8266,10 +8507,40 @@ var Dataset2 = class extends ObjectFetcher {
8266
8507
  get loggingState() {
8267
8508
  return this.state;
8268
8509
  }
8510
+ async toEvalData() {
8511
+ await this.getState();
8512
+ const metadata = await this.lazyMetadata.get();
8513
+ const pinnedVersion = this.getPinnedVersion();
8514
+ const internalBtql = this.getInternalBtql();
8515
+ return {
8516
+ dataset_id: metadata.dataset.id,
8517
+ ...this.pinnedEnvironment !== void 0 ? {
8518
+ dataset_environment: this.pinnedEnvironment
8519
+ } : {},
8520
+ ...this.pinnedEnvironment === void 0 && this.pinnedSnapshotName !== void 0 ? {
8521
+ dataset_snapshot_name: this.pinnedSnapshotName
8522
+ } : {},
8523
+ ...this.pinnedEnvironment === void 0 && this.pinnedSnapshotName === void 0 && pinnedVersion !== void 0 ? {
8524
+ dataset_version: pinnedVersion
8525
+ } : {},
8526
+ ...internalBtql !== void 0 ? { _internal_btql: internalBtql } : {}
8527
+ };
8528
+ }
8269
8529
  async getState() {
8270
8530
  await this.lazyMetadata.get();
8531
+ if (this.lazyPinnedVersion !== void 0 && this.getPinnedVersion() === void 0) {
8532
+ this.setPinnedVersion(await this.lazyPinnedVersion.get());
8533
+ }
8271
8534
  return this.state;
8272
8535
  }
8536
+ async version(options) {
8537
+ const pinnedVersion = this.getPinnedVersion();
8538
+ if (pinnedVersion !== void 0) {
8539
+ return pinnedVersion;
8540
+ }
8541
+ await this.getState();
8542
+ return await super.version(options);
8543
+ }
8273
8544
  validateEvent({
8274
8545
  metadata,
8275
8546
  expected,
@@ -8405,6 +8676,88 @@ var Dataset2 = class extends ObjectFetcher {
8405
8676
  this.state.bgLogger().log([args]);
8406
8677
  return id;
8407
8678
  }
8679
+ async createSnapshot({
8680
+ name,
8681
+ description,
8682
+ update
8683
+ }) {
8684
+ await this.flush();
8685
+ const state = await this.getState();
8686
+ const datasetId = await this.id;
8687
+ const currentVersion = await this.version();
8688
+ if (currentVersion === void 0) {
8689
+ throw new Error("Cannot create snapshot: dataset has no version");
8690
+ }
8691
+ const response = await state.appConn().post_json("api/dataset_snapshot/register", {
8692
+ dataset_id: datasetId,
8693
+ dataset_snapshot_name: name,
8694
+ description,
8695
+ xact_id: currentVersion,
8696
+ update
8697
+ });
8698
+ return datasetSnapshotRegisterResponseSchema.parse(response).dataset_snapshot;
8699
+ }
8700
+ async listSnapshots() {
8701
+ const state = await this.getState();
8702
+ return await getDatasetSnapshots({
8703
+ state,
8704
+ datasetId: await this.id
8705
+ });
8706
+ }
8707
+ async getSnapshot(lookup) {
8708
+ const state = await this.getState();
8709
+ const datasetId = await this.id;
8710
+ return await getDatasetSnapshot({
8711
+ state,
8712
+ datasetId,
8713
+ ...lookup
8714
+ });
8715
+ }
8716
+ async updateSnapshot(snapshotId, {
8717
+ name,
8718
+ description
8719
+ }) {
8720
+ const state = await this.getState();
8721
+ return DatasetSnapshot.parse(
8722
+ await state.appConn().post_json("api/dataset_snapshot/patch_id", {
8723
+ id: snapshotId,
8724
+ name,
8725
+ description
8726
+ })
8727
+ );
8728
+ }
8729
+ async deleteSnapshot(snapshotId) {
8730
+ const state = await this.getState();
8731
+ return DatasetSnapshot.parse(
8732
+ await state.appConn().post_json("api/dataset_snapshot/delete_id", {
8733
+ id: snapshotId
8734
+ })
8735
+ );
8736
+ }
8737
+ async restorePreview({
8738
+ version
8739
+ }) {
8740
+ await this.flush();
8741
+ const state = await this.getState();
8742
+ const datasetId = await this.id;
8743
+ return datasetRestorePreviewResultSchema.parse(
8744
+ await state.apiConn().post_json(`v1/dataset/${datasetId}/restore/preview`, {
8745
+ version
8746
+ })
8747
+ );
8748
+ }
8749
+ async restore({
8750
+ version
8751
+ }) {
8752
+ await this.flush();
8753
+ const state = await this.getState();
8754
+ const datasetId = await this.id;
8755
+ return datasetRestoreResultSchema.parse(
8756
+ await state.apiConn().post_json(`v1/dataset/${datasetId}/restore`, {
8757
+ version
8758
+ })
8759
+ );
8760
+ }
8408
8761
  /**
8409
8762
  * Summarize the dataset, including high level metrics about its size and other metadata.
8410
8763
  * @param summarizeData Whether to summarize the data. If false, only the metadata will be returned.
@@ -13566,6 +13919,9 @@ function llmParentKey(parentToolUseId) {
13566
13919
  function isSubAgentDelegationToolName(toolName) {
13567
13920
  return toolName === "Agent" || toolName === "Task";
13568
13921
  }
13922
+ function shouldParentToolAsTaskSibling(toolName) {
13923
+ return toolName === "Agent" || toolName === "Task" || toolName === "Bash";
13924
+ }
13569
13925
  function filterSerializableOptions(options) {
13570
13926
  const allowedKeys = [
13571
13927
  "model",
@@ -13665,6 +14021,11 @@ function resolveTaskToolUseId(taskIdToToolUseId, message) {
13665
14021
  }
13666
14022
  return void 0;
13667
14023
  }
14024
+ function seedTaskToolUseIdMapping(taskIdToToolUseId, message) {
14025
+ if (typeof message.task_id === "string" && typeof message.tool_use_id === "string") {
14026
+ taskIdToToolUseId.set(message.task_id, message.tool_use_id);
14027
+ }
14028
+ }
13668
14029
  function extractUsageFromMessage(message) {
13669
14030
  const metrics = {};
13670
14031
  let usage;
@@ -13860,7 +14221,10 @@ function createToolTracingHooks(resolveParentSpan, activeToolSpans, mcpServers,
13860
14221
  }
13861
14222
  },
13862
14223
  name: parsed.displayName,
13863
- parent: await resolveParentSpan(toolUseID),
14224
+ parent: await resolveParentSpan(toolUseID, {
14225
+ agentId: input.agent_id,
14226
+ preferTaskSiblingParent: shouldParentToolAsTaskSibling(parsed.toolName)
14227
+ }),
13864
14228
  spanAttributes: { type: "tool" /* TOOL */ }
13865
14229
  });
13866
14230
  activeToolSpans.set(toolUseID, toolSpan);
@@ -14150,6 +14514,7 @@ async function finalizeCurrentMessageGroup(state) {
14150
14514
  state.currentMessages.length = 0;
14151
14515
  }
14152
14516
  function maybeTrackToolUseContext(state, message) {
14517
+ seedTaskToolUseIdMapping(state.taskIdToToolUseId, message);
14153
14518
  if (message.type !== "assistant" || !Array.isArray(message.message?.content)) {
14154
14519
  return;
14155
14520
  }
@@ -14204,6 +14569,34 @@ async function ensureSubAgentSpan(subAgentDetailsByToolUseId, rootSpan, activeTo
14204
14569
  subAgentSpans.set(parentToolUseId, subAgentSpan);
14205
14570
  return subAgentSpan;
14206
14571
  }
14572
+ async function ensureActiveLlmSpanForParentToolUse(rootSpan, activeLlmSpansByParentToolUse, subAgentDetailsByToolUseId, activeToolSpans, subAgentSpans, parentToolUseId, startTime) {
14573
+ const parentKey = llmParentKey(parentToolUseId);
14574
+ const existingLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
14575
+ if (existingLlmSpan) {
14576
+ return existingLlmSpan;
14577
+ }
14578
+ let llmParentSpan = await rootSpan.export();
14579
+ if (parentToolUseId) {
14580
+ const subAgentSpan = await ensureSubAgentSpan(
14581
+ subAgentDetailsByToolUseId,
14582
+ rootSpan,
14583
+ activeToolSpans,
14584
+ subAgentSpans,
14585
+ parentToolUseId
14586
+ );
14587
+ llmParentSpan = await subAgentSpan.export();
14588
+ }
14589
+ const llmSpan = startSpan({
14590
+ name: "anthropic.messages.create",
14591
+ parent: llmParentSpan,
14592
+ spanAttributes: {
14593
+ type: "llm" /* LLM */
14594
+ },
14595
+ startTime
14596
+ });
14597
+ activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
14598
+ return llmSpan;
14599
+ }
14207
14600
  async function maybeHandleTaskLifecycleMessage(state, message) {
14208
14601
  if (message.type !== "system") {
14209
14602
  return false;
@@ -14313,29 +14706,15 @@ async function handleStreamMessage(state, message) {
14313
14706
  }
14314
14707
  if (message.type === "assistant" && message.message?.usage) {
14315
14708
  const parentToolUseId = message.parent_tool_use_id ?? null;
14316
- const parentKey = llmParentKey(parentToolUseId);
14317
- if (!state.activeLlmSpansByParentToolUse.has(parentKey)) {
14318
- let llmParentSpan = await state.span.export();
14319
- if (parentToolUseId) {
14320
- const subAgentSpan = await ensureSubAgentSpan(
14321
- state.subAgentDetailsByToolUseId,
14322
- state.span,
14323
- state.activeToolSpans,
14324
- state.subAgentSpans,
14325
- parentToolUseId
14326
- );
14327
- llmParentSpan = await subAgentSpan.export();
14328
- }
14329
- const llmSpan = startSpan({
14330
- name: "anthropic.messages.create",
14331
- parent: llmParentSpan,
14332
- spanAttributes: {
14333
- type: "llm" /* LLM */
14334
- },
14335
- startTime: state.currentMessageStartTime
14336
- });
14337
- state.activeLlmSpansByParentToolUse.set(parentKey, llmSpan);
14338
- }
14709
+ await ensureActiveLlmSpanForParentToolUse(
14710
+ state.span,
14711
+ state.activeLlmSpansByParentToolUse,
14712
+ state.subAgentDetailsByToolUseId,
14713
+ state.activeToolSpans,
14714
+ state.subAgentSpans,
14715
+ parentToolUseId,
14716
+ state.currentMessageStartTime
14717
+ );
14339
14718
  state.currentMessages.push(message);
14340
14719
  }
14341
14720
  if (message.type !== "result" || !message.usage) {
@@ -14482,10 +14861,35 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
14482
14861
  const localToolContext = createClaudeLocalToolContext();
14483
14862
  const { hasLocalToolHandlers, localToolHookNames } = prepareLocalToolHandlersInMcpServers(options.mcpServers);
14484
14863
  const skipLocalToolHooks = options[CLAUDE_AGENT_SDK_SKIP_LOCAL_TOOL_HOOKS_OPTION] === true || hasLocalToolHandlers;
14485
- const resolveToolUseParentSpan = async (toolUseID) => {
14486
- const parentToolUseId = toolUseToParent.get(toolUseID) ?? null;
14864
+ const resolveToolUseParentSpan = async (toolUseID, context) => {
14865
+ const trackedParentToolUseId = toolUseToParent.get(toolUseID);
14866
+ const parentToolUseId = trackedParentToolUseId ?? (context?.agentId ? taskIdToToolUseId.get(context.agentId) ?? null : null);
14487
14867
  const parentKey = llmParentKey(parentToolUseId);
14488
14868
  const activeLlmSpan = activeLlmSpansByParentToolUse.get(parentKey);
14869
+ if (context?.preferTaskSiblingParent) {
14870
+ if (!activeLlmSpan) {
14871
+ await ensureActiveLlmSpanForParentToolUse(
14872
+ span,
14873
+ activeLlmSpansByParentToolUse,
14874
+ subAgentDetailsByToolUseId,
14875
+ activeToolSpans,
14876
+ subAgentSpans,
14877
+ parentToolUseId,
14878
+ getCurrentUnixTimestamp()
14879
+ );
14880
+ }
14881
+ if (parentToolUseId) {
14882
+ const subAgentSpan = await ensureSubAgentSpan(
14883
+ subAgentDetailsByToolUseId,
14884
+ span,
14885
+ activeToolSpans,
14886
+ subAgentSpans,
14887
+ parentToolUseId
14888
+ );
14889
+ return subAgentSpan.export();
14890
+ }
14891
+ return span.export();
14892
+ }
14489
14893
  if (activeLlmSpan) {
14490
14894
  return activeLlmSpan.export();
14491
14895
  }
@@ -14613,65 +15017,943 @@ var ClaudeAgentSDKPlugin = class extends BasePlugin {
14613
15017
  }
14614
15018
  };
14615
15019
 
14616
- // src/instrumentation/plugins/google-genai-channels.ts
14617
- var googleGenAIChannels = defineChannels("@google/genai", {
14618
- generateContent: channel({
14619
- channelName: "models.generateContent",
15020
+ // src/instrumentation/plugins/cursor-sdk-channels.ts
15021
+ var cursorSDKChannels = defineChannels("@cursor/sdk", {
15022
+ create: channel({
15023
+ channelName: "Agent.create",
14620
15024
  kind: "async"
14621
15025
  }),
14622
- generateContentStream: channel({
14623
- channelName: "models.generateContentStream",
15026
+ resume: channel({
15027
+ channelName: "Agent.resume",
14624
15028
  kind: "async"
14625
15029
  }),
14626
- embedContent: channel({
14627
- channelName: "models.embedContent",
15030
+ prompt: channel({
15031
+ channelName: "Agent.prompt",
15032
+ kind: "async"
15033
+ }),
15034
+ send: channel({
15035
+ channelName: "agent.send",
14628
15036
  kind: "async"
14629
15037
  })
14630
15038
  });
14631
15039
 
14632
- // src/instrumentation/plugins/google-genai-plugin.ts
14633
- var GOOGLE_GENAI_INTERNAL_CONTEXT = {
14634
- caller_filename: "<node-internal>",
14635
- caller_functionname: "<node-internal>",
14636
- caller_lineno: 0
14637
- };
14638
- function createWrapperParityEvent(args) {
14639
- return {
14640
- context: GOOGLE_GENAI_INTERNAL_CONTEXT,
14641
- input: args.input,
14642
- metadata: args.metadata
14643
- };
14644
- }
14645
- var GoogleGenAIPlugin = class extends BasePlugin {
15040
+ // src/instrumentation/plugins/cursor-sdk-plugin.ts
15041
+ var PATCHED_AGENT = Symbol.for("braintrust.cursor-sdk.auto-patched-agent");
15042
+ var PATCHED_RUN = Symbol.for("braintrust.cursor-sdk.patched-run");
15043
+ var WRAPPED_AGENT = Symbol.for("braintrust.cursor-sdk.wrapped-agent");
15044
+ var CursorSDKPlugin = class extends BasePlugin {
15045
+ promptDepth = 0;
14646
15046
  onEnable() {
14647
- this.subscribeToGoogleGenAIChannels();
15047
+ this.subscribeToAgentFactories();
15048
+ this.subscribeToPrompt();
15049
+ this.subscribeToSend();
14648
15050
  }
14649
15051
  onDisable() {
14650
- this.unsubscribers = unsubscribeAll(this.unsubscribers);
15052
+ for (const unsubscribe of this.unsubscribers) {
15053
+ unsubscribe();
15054
+ }
15055
+ this.unsubscribers = [];
15056
+ this.promptDepth = 0;
14651
15057
  }
14652
- subscribeToGoogleGenAIChannels() {
14653
- this.subscribeToGenerateContentChannel();
14654
- this.subscribeToGenerateContentStreamChannel();
14655
- this.subscribeToEmbedContentChannel();
15058
+ subscribeToAgentFactories() {
15059
+ this.subscribeToAgentFactory(cursorSDKChannels.create);
15060
+ this.subscribeToAgentFactory(cursorSDKChannels.resume);
14656
15061
  }
14657
- subscribeToGenerateContentChannel() {
14658
- const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
15062
+ subscribeToAgentFactory(channel2) {
15063
+ const tracingChannel2 = channel2.tracingChannel();
15064
+ const handlers = {
15065
+ asyncEnd: (event) => {
15066
+ patchCursorAgentInPlace(event.result);
15067
+ },
15068
+ error: () => {
15069
+ }
15070
+ };
15071
+ tracingChannel2.subscribe(handlers);
15072
+ this.unsubscribers.push(() => {
15073
+ tracingChannel2.unsubscribe(handlers);
15074
+ });
15075
+ }
15076
+ subscribeToPrompt() {
15077
+ const channel2 = cursorSDKChannels.prompt.tracingChannel();
14659
15078
  const states = /* @__PURE__ */ new WeakMap();
14660
- const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
14661
- tracingChannel2,
14662
- states,
14663
- (event) => {
14664
- const params = event.arguments[0];
14665
- const input = serializeGenerateContentInput(params);
14666
- const metadata = extractGenerateContentMetadata(params);
15079
+ const handlers = {
15080
+ start: (event) => {
15081
+ this.promptDepth += 1;
15082
+ const message = event.arguments[0];
15083
+ const options = event.arguments[1];
15084
+ const metadata = {
15085
+ ...extractAgentOptionsMetadata(options),
15086
+ "cursor_sdk.operation": "Agent.prompt",
15087
+ provider: "cursor",
15088
+ ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
15089
+ };
14667
15090
  const span = startSpan({
14668
- name: "generate_content",
14669
- spanAttributes: {
14670
- type: "llm" /* LLM */
14671
- },
14672
- event: createWrapperParityEvent({ input, metadata })
15091
+ name: "Cursor Agent",
15092
+ spanAttributes: { type: "task" /* TASK */ }
14673
15093
  });
14674
- return {
15094
+ const startTime = getCurrentUnixTimestamp();
15095
+ safeLog(span, {
15096
+ input: sanitizeUserMessage(message),
15097
+ metadata
15098
+ });
15099
+ states.set(event, { metadata, span, startTime });
15100
+ },
15101
+ asyncEnd: (event) => {
15102
+ this.promptDepth = Math.max(0, this.promptDepth - 1);
15103
+ const state = states.get(event);
15104
+ if (!state) {
15105
+ return;
15106
+ }
15107
+ try {
15108
+ safeLog(state.span, {
15109
+ metadata: {
15110
+ ...state.metadata,
15111
+ ...extractRunResultMetadata(event.result)
15112
+ },
15113
+ metrics: buildDurationMetrics(state.startTime),
15114
+ output: event.result?.result ?? event.result
15115
+ });
15116
+ } finally {
15117
+ state.span.end();
15118
+ states.delete(event);
15119
+ }
15120
+ },
15121
+ error: (event) => {
15122
+ this.promptDepth = Math.max(0, this.promptDepth - 1);
15123
+ const state = states.get(event);
15124
+ if (!state || !event.error) {
15125
+ return;
15126
+ }
15127
+ safeLog(state.span, { error: event.error.message });
15128
+ state.span.end();
15129
+ states.delete(event);
15130
+ }
15131
+ };
15132
+ channel2.subscribe(handlers);
15133
+ this.unsubscribers.push(() => {
15134
+ channel2.unsubscribe(handlers);
15135
+ });
15136
+ }
15137
+ subscribeToSend() {
15138
+ const channel2 = cursorSDKChannels.send.tracingChannel();
15139
+ const states = /* @__PURE__ */ new WeakMap();
15140
+ const handlers = {
15141
+ start: (event) => {
15142
+ if (this.promptDepth > 0) {
15143
+ return;
15144
+ }
15145
+ const message = event.arguments[0];
15146
+ const sendOptions = event.arguments[1];
15147
+ const agent = event.agent;
15148
+ const metadata = {
15149
+ ...extractSendMetadata(sendOptions),
15150
+ ...agent ? extractAgentMetadata(agent) : {},
15151
+ "cursor_sdk.operation": "agent.send",
15152
+ provider: "cursor",
15153
+ ...event.moduleVersion ? { "cursor_sdk.version": event.moduleVersion } : {}
15154
+ };
15155
+ const span = startSpan({
15156
+ name: "Cursor Agent",
15157
+ spanAttributes: { type: "task" /* TASK */ }
15158
+ });
15159
+ const startTime = getCurrentUnixTimestamp();
15160
+ safeLog(span, {
15161
+ input: sanitizeUserMessage(message),
15162
+ metadata
15163
+ });
15164
+ const state = {
15165
+ activeToolSpans: /* @__PURE__ */ new Map(),
15166
+ agent,
15167
+ conversationText: [],
15168
+ deltaText: [],
15169
+ finalized: false,
15170
+ input: message,
15171
+ metadata,
15172
+ metrics: {},
15173
+ span,
15174
+ startTime,
15175
+ streamMessages: [],
15176
+ streamText: [],
15177
+ stepText: [],
15178
+ taskText: []
15179
+ };
15180
+ if (hasCursorCallbacks(sendOptions)) {
15181
+ event.arguments[1] = wrapSendOptionsCallbacks(sendOptions, state);
15182
+ }
15183
+ states.set(event, state);
15184
+ },
15185
+ asyncEnd: (event) => {
15186
+ const state = states.get(event);
15187
+ if (!state) {
15188
+ return;
15189
+ }
15190
+ if (!event.result) {
15191
+ return;
15192
+ }
15193
+ state.run = event.result;
15194
+ state.metadata = {
15195
+ ...state.metadata,
15196
+ ...extractRunMetadata(event.result)
15197
+ };
15198
+ patchCursorRun(event.result, state);
15199
+ },
15200
+ error: (event) => {
15201
+ const state = states.get(event);
15202
+ if (!state || !event.error) {
15203
+ return;
15204
+ }
15205
+ safeLog(state.span, { error: event.error.message });
15206
+ endOpenToolSpans(state, event.error.message);
15207
+ state.span.end();
15208
+ state.finalized = true;
15209
+ states.delete(event);
15210
+ }
15211
+ };
15212
+ channel2.subscribe(handlers);
15213
+ this.unsubscribers.push(() => {
15214
+ channel2.unsubscribe(handlers);
15215
+ });
15216
+ }
15217
+ };
15218
+ function patchCursorAgentInPlace(agent) {
15219
+ if (!agent || typeof agent !== "object") {
15220
+ return;
15221
+ }
15222
+ const agentRecord = agent;
15223
+ if (agentRecord[PATCHED_AGENT] || agentRecord[WRAPPED_AGENT] || typeof agentRecord.send !== "function") {
15224
+ return;
15225
+ }
15226
+ const originalSend = agentRecord.send.bind(agentRecord);
15227
+ try {
15228
+ Object.defineProperty(agentRecord, PATCHED_AGENT, {
15229
+ configurable: false,
15230
+ enumerable: false,
15231
+ value: true
15232
+ });
15233
+ Object.defineProperty(agentRecord, "send", {
15234
+ configurable: true,
15235
+ value(message, options) {
15236
+ const args = [message, options];
15237
+ return cursorSDKChannels.send.tracePromise(
15238
+ () => originalSend(...args),
15239
+ {
15240
+ agent: agentRecord,
15241
+ arguments: args,
15242
+ operation: "send"
15243
+ }
15244
+ );
15245
+ },
15246
+ writable: true
15247
+ });
15248
+ } catch {
15249
+ }
15250
+ }
15251
+ function wrapSendOptionsCallbacks(options, state) {
15252
+ const originalOnDelta = options.onDelta;
15253
+ const originalOnStep = options.onStep;
15254
+ return {
15255
+ ...options,
15256
+ async onDelta(args) {
15257
+ try {
15258
+ await handleInteractionUpdate(state, args.update);
15259
+ } catch (error) {
15260
+ logInstrumentationError("Cursor SDK onDelta", error);
15261
+ }
15262
+ if (originalOnDelta) {
15263
+ return originalOnDelta(args);
15264
+ }
15265
+ },
15266
+ async onStep(args) {
15267
+ try {
15268
+ handleStepUpdate(state, args.step);
15269
+ } catch (error) {
15270
+ logInstrumentationError("Cursor SDK onStep", error);
15271
+ }
15272
+ if (originalOnStep) {
15273
+ return originalOnStep(args);
15274
+ }
15275
+ }
15276
+ };
15277
+ }
15278
+ function hasCursorCallbacks(options) {
15279
+ return !!options && (typeof options.onDelta === "function" || typeof options.onStep === "function");
15280
+ }
15281
+ function patchCursorRun(run, state) {
15282
+ if (!run || typeof run !== "object") {
15283
+ return;
15284
+ }
15285
+ const runRecord = run;
15286
+ if (runRecord[PATCHED_RUN]) {
15287
+ return;
15288
+ }
15289
+ try {
15290
+ Object.defineProperty(runRecord, PATCHED_RUN, {
15291
+ configurable: false,
15292
+ enumerable: false,
15293
+ value: true
15294
+ });
15295
+ if (typeof runRecord.stream === "function") {
15296
+ const originalStream = runRecord.stream.bind(runRecord);
15297
+ Object.defineProperty(runRecord, "stream", {
15298
+ configurable: true,
15299
+ value() {
15300
+ const stream = originalStream();
15301
+ return patchCursorStream(stream, state);
15302
+ },
15303
+ writable: true
15304
+ });
15305
+ }
15306
+ if (typeof runRecord.wait === "function") {
15307
+ const originalWait = runRecord.wait.bind(runRecord);
15308
+ Object.defineProperty(runRecord, "wait", {
15309
+ configurable: true,
15310
+ async value() {
15311
+ try {
15312
+ const result = await originalWait();
15313
+ state.lastResult = result;
15314
+ await finalizeCursorRun(state, { result });
15315
+ return result;
15316
+ } catch (error) {
15317
+ await finalizeCursorRun(state, { error });
15318
+ throw error;
15319
+ }
15320
+ },
15321
+ writable: true
15322
+ });
15323
+ }
15324
+ if (typeof runRecord.conversation === "function") {
15325
+ const originalConversation = runRecord.conversation.bind(runRecord);
15326
+ Object.defineProperty(runRecord, "conversation", {
15327
+ configurable: true,
15328
+ async value() {
15329
+ try {
15330
+ const conversation = await originalConversation();
15331
+ await handleConversation(state, conversation);
15332
+ await finalizeCursorRun(state);
15333
+ return conversation;
15334
+ } catch (error) {
15335
+ await finalizeCursorRun(state, { error });
15336
+ throw error;
15337
+ }
15338
+ },
15339
+ writable: true
15340
+ });
15341
+ }
15342
+ } catch {
15343
+ void finalizeCursorRun(state, { output: run });
15344
+ }
15345
+ }
15346
+ async function* patchCursorStream(stream, state) {
15347
+ try {
15348
+ for await (const message of stream) {
15349
+ try {
15350
+ await handleStreamMessage2(state, message);
15351
+ } catch (error) {
15352
+ logInstrumentationError("Cursor SDK stream", error);
15353
+ }
15354
+ yield message;
15355
+ }
15356
+ await finalizeCursorRun(state);
15357
+ } catch (error) {
15358
+ await finalizeCursorRun(state, { error });
15359
+ throw error;
15360
+ }
15361
+ }
15362
+ async function handleInteractionUpdate(state, update) {
15363
+ switch (update.type) {
15364
+ case "text-delta":
15365
+ if (typeof update.text === "string") {
15366
+ state.deltaText.push(update.text);
15367
+ }
15368
+ return;
15369
+ case "token-delta":
15370
+ if (typeof update.tokens === "number") {
15371
+ state.metrics["cursor_sdk.delta_tokens"] = (state.metrics["cursor_sdk.delta_tokens"] ?? 0) + update.tokens;
15372
+ }
15373
+ return;
15374
+ case "tool-call-started":
15375
+ case "partial-tool-call":
15376
+ case "tool-call-completed":
15377
+ await handleToolUpdate(
15378
+ state,
15379
+ update
15380
+ );
15381
+ return;
15382
+ case "turn-ended":
15383
+ addUsageMetrics(
15384
+ state.metrics,
15385
+ update.usage
15386
+ );
15387
+ return;
15388
+ case "summary":
15389
+ if (typeof update.summary === "string") {
15390
+ state.taskText.push(update.summary);
15391
+ }
15392
+ return;
15393
+ case "step-completed":
15394
+ if (typeof update.stepDurationMs === "number") {
15395
+ state.metrics["cursor_sdk.step_duration_ms"] = (state.metrics["cursor_sdk.step_duration_ms"] ?? 0) + update.stepDurationMs;
15396
+ }
15397
+ state.metrics["cursor_sdk.steps"] = (state.metrics["cursor_sdk.steps"] ?? 0) + 1;
15398
+ return;
15399
+ default:
15400
+ return;
15401
+ }
15402
+ }
15403
+ async function handleToolUpdate(state, update) {
15404
+ const callId = update.callId;
15405
+ if (!callId) {
15406
+ return;
15407
+ }
15408
+ const toolCall = update.toolCall;
15409
+ const name = extractToolName(toolCall);
15410
+ const args = extractToolArgs(toolCall);
15411
+ const result = extractToolResult(toolCall);
15412
+ if (update.type === "tool-call-started" || update.type === "partial-tool-call") {
15413
+ if (!state.activeToolSpans.has(callId)) {
15414
+ state.activeToolSpans.set(
15415
+ callId,
15416
+ await startToolSpan(state, {
15417
+ args,
15418
+ callId,
15419
+ name,
15420
+ status: "running",
15421
+ toolCall
15422
+ })
15423
+ );
15424
+ }
15425
+ return;
15426
+ }
15427
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
15428
+ args,
15429
+ callId,
15430
+ name,
15431
+ status: "completed",
15432
+ toolCall
15433
+ });
15434
+ finishToolSpan(toolState, {
15435
+ error: toolCall?.status === "error" ? stringifyUnknown(result) : void 0,
15436
+ metadata: {
15437
+ "cursor_sdk.tool.status": toolCall?.status ?? "completed"
15438
+ },
15439
+ output: result
15440
+ });
15441
+ state.activeToolSpans.delete(callId);
15442
+ }
15443
+ async function handleStreamMessage2(state, message) {
15444
+ state.streamMessages.push(message);
15445
+ if (message.type === "system") {
15446
+ const systemMessage = message;
15447
+ state.metadata = {
15448
+ ...state.metadata,
15449
+ ...extractModelMetadata(systemMessage.model),
15450
+ ...systemMessage.agent_id ? { "cursor_sdk.agent_id": systemMessage.agent_id } : {},
15451
+ ...systemMessage.run_id ? { "cursor_sdk.run_id": systemMessage.run_id } : {},
15452
+ ...systemMessage.tools ? { "cursor_sdk.tools": systemMessage.tools } : {}
15453
+ };
15454
+ return;
15455
+ }
15456
+ if (message.type === "assistant") {
15457
+ const assistantMessage = message;
15458
+ for (const block of assistantMessage.message?.content ?? []) {
15459
+ if (block?.type === "text" && typeof block.text === "string") {
15460
+ state.streamText.push(block.text);
15461
+ } else if (block?.type === "tool_use" && block.id) {
15462
+ state.activeToolSpans.set(
15463
+ block.id,
15464
+ await startToolSpan(state, {
15465
+ args: block.input,
15466
+ callId: block.id,
15467
+ name: block.name,
15468
+ status: "running"
15469
+ })
15470
+ );
15471
+ }
15472
+ }
15473
+ return;
15474
+ }
15475
+ if (message.type === "tool_call") {
15476
+ await handleToolMessage(
15477
+ state,
15478
+ message
15479
+ );
15480
+ return;
15481
+ }
15482
+ if (message.type === "task" && typeof message.text === "string") {
15483
+ state.taskText.push(message.text);
15484
+ return;
15485
+ }
15486
+ if (message.type === "status" && message.status) {
15487
+ state.metadata["cursor_sdk.status"] = message.status;
15488
+ }
15489
+ }
15490
+ async function handleToolMessage(state, message) {
15491
+ const callId = message.call_id;
15492
+ if (!callId) {
15493
+ return;
15494
+ }
15495
+ if (message.status === "running") {
15496
+ if (!state.activeToolSpans.has(callId)) {
15497
+ state.activeToolSpans.set(
15498
+ callId,
15499
+ await startToolSpan(state, {
15500
+ args: message.args,
15501
+ callId,
15502
+ name: message.name,
15503
+ status: message.status,
15504
+ truncated: message.truncated
15505
+ })
15506
+ );
15507
+ }
15508
+ return;
15509
+ }
15510
+ const toolState = state.activeToolSpans.get(callId) ?? await startToolSpan(state, {
15511
+ args: message.args,
15512
+ callId,
15513
+ name: message.name,
15514
+ status: message.status,
15515
+ truncated: message.truncated
15516
+ });
15517
+ finishToolSpan(toolState, {
15518
+ error: message.status === "error" ? stringifyUnknown(message.result) : void 0,
15519
+ metadata: {
15520
+ "cursor_sdk.tool.status": message.status
15521
+ },
15522
+ output: message.result
15523
+ });
15524
+ state.activeToolSpans.delete(callId);
15525
+ }
15526
+ async function handleConversation(state, turns) {
15527
+ state.conversationOutput = turns;
15528
+ for (const turn of turns) {
15529
+ if (turn.type === "agentConversationTurn") {
15530
+ for (const step of turn.turn?.steps ?? []) {
15531
+ await handleConversationStep(state, step);
15532
+ }
15533
+ } else if (turn.type === "shellConversationTurn") {
15534
+ const command = turn.turn?.shellCommand?.command;
15535
+ if (command) {
15536
+ const callId = `shell:${state.activeToolSpans.size}:${command}`;
15537
+ const toolState = await startToolSpan(state, {
15538
+ args: turn.turn?.shellCommand,
15539
+ callId,
15540
+ name: "shell",
15541
+ status: "completed"
15542
+ });
15543
+ finishToolSpan(toolState, {
15544
+ metadata: { "cursor_sdk.tool.status": "completed" },
15545
+ output: turn.turn?.shellOutput
15546
+ });
15547
+ }
15548
+ }
15549
+ }
15550
+ }
15551
+ async function handleConversationStep(state, step) {
15552
+ if (step.type === "assistantMessage" && typeof step.message?.text === "string") {
15553
+ state.conversationText.push(step.message.text);
15554
+ return;
15555
+ }
15556
+ if (step.type !== "toolCall") {
15557
+ return;
15558
+ }
15559
+ const toolCall = step.message;
15560
+ const callId = typeof toolCall?.callId === "string" ? toolCall.callId : `conversation-tool:${state.activeToolSpans.size}`;
15561
+ const toolState = await startToolSpan(state, {
15562
+ args: extractToolArgs(toolCall),
15563
+ callId,
15564
+ name: extractToolName(toolCall),
15565
+ status: toolCall?.status,
15566
+ toolCall
15567
+ });
15568
+ finishToolSpan(toolState, {
15569
+ error: toolCall?.status === "error" ? stringifyUnknown(toolCall.result) : void 0,
15570
+ metadata: {
15571
+ "cursor_sdk.tool.status": toolCall?.status ?? "completed"
15572
+ },
15573
+ output: extractToolResult(toolCall)
15574
+ });
15575
+ }
15576
+ function handleStepUpdate(state, step) {
15577
+ state.metrics["cursor_sdk.steps"] = (state.metrics["cursor_sdk.steps"] ?? 0) + 1;
15578
+ if (step.type) {
15579
+ const stepTypes = state.metadata["cursor_sdk.step_types"];
15580
+ if (Array.isArray(stepTypes)) {
15581
+ if (!stepTypes.includes(step.type)) {
15582
+ stepTypes.push(step.type);
15583
+ }
15584
+ } else {
15585
+ state.metadata["cursor_sdk.step_types"] = [step.type];
15586
+ }
15587
+ }
15588
+ if (step.type === "assistantMessage" && typeof step.message?.text === "string") {
15589
+ state.stepText.push(step.message.text);
15590
+ }
15591
+ }
15592
+ async function startToolSpan(state, args) {
15593
+ const name = args.name || "unknown";
15594
+ const metadata = {
15595
+ "cursor_sdk.tool.status": args.status,
15596
+ "gen_ai.tool.call.id": args.callId,
15597
+ "gen_ai.tool.name": name
15598
+ };
15599
+ if (args.truncated?.args !== void 0) {
15600
+ metadata["cursor_sdk.tool.args_truncated"] = args.truncated.args;
15601
+ }
15602
+ if (args.truncated?.result !== void 0) {
15603
+ metadata["cursor_sdk.tool.result_truncated"] = args.truncated.result;
15604
+ }
15605
+ const span = startSpan({
15606
+ event: {
15607
+ input: args.args,
15608
+ metadata
15609
+ },
15610
+ name: `tool: ${name}`,
15611
+ parent: await state.span.export(),
15612
+ spanAttributes: { type: "tool" /* TOOL */ }
15613
+ });
15614
+ let subAgentSpan;
15615
+ if (isSubAgentToolName(name)) {
15616
+ subAgentSpan = startSpan({
15617
+ event: {
15618
+ input: args.args,
15619
+ metadata: {
15620
+ "cursor_sdk.subagent.tool_call_id": args.callId,
15621
+ "gen_ai.tool.name": name
15622
+ }
15623
+ },
15624
+ name: formatSubAgentSpanName2(args.toolCall, args.args),
15625
+ parent: await span.export(),
15626
+ spanAttributes: { type: "task" /* TASK */ }
15627
+ });
15628
+ }
15629
+ return { span, subAgentSpan };
15630
+ }
15631
+ function finishToolSpan(toolState, result) {
15632
+ try {
15633
+ if (result.error) {
15634
+ safeLog(toolState.span, {
15635
+ error: result.error,
15636
+ metadata: result.metadata,
15637
+ output: result.output
15638
+ });
15639
+ if (toolState.subAgentSpan) {
15640
+ safeLog(toolState.subAgentSpan, {
15641
+ error: result.error,
15642
+ metadata: result.metadata,
15643
+ output: result.output
15644
+ });
15645
+ }
15646
+ } else {
15647
+ safeLog(toolState.span, {
15648
+ metadata: result.metadata,
15649
+ output: result.output
15650
+ });
15651
+ if (toolState.subAgentSpan) {
15652
+ safeLog(toolState.subAgentSpan, {
15653
+ metadata: result.metadata,
15654
+ output: result.output
15655
+ });
15656
+ }
15657
+ }
15658
+ } finally {
15659
+ toolState.subAgentSpan?.end();
15660
+ toolState.span.end();
15661
+ }
15662
+ }
15663
+ async function finalizeCursorRun(state, params = {}) {
15664
+ if (state.finalized) {
15665
+ return;
15666
+ }
15667
+ state.finalized = true;
15668
+ const error = params.error;
15669
+ const result = params.result ?? state.lastResult;
15670
+ 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);
15671
+ try {
15672
+ const metadata = {
15673
+ ...state.metadata,
15674
+ ...state.run ? extractRunMetadata(state.run) : {},
15675
+ ...result ? extractRunResultMetadata(result) : {}
15676
+ };
15677
+ if (error) {
15678
+ safeLog(state.span, {
15679
+ error: error instanceof Error ? error.message : String(error),
15680
+ metadata,
15681
+ metrics: {
15682
+ ...cleanMetrics(state.metrics),
15683
+ ...buildDurationMetrics(state.startTime)
15684
+ },
15685
+ output
15686
+ });
15687
+ } else {
15688
+ safeLog(state.span, {
15689
+ metadata,
15690
+ metrics: {
15691
+ ...cleanMetrics(state.metrics),
15692
+ ...buildDurationMetrics(state.startTime)
15693
+ },
15694
+ output
15695
+ });
15696
+ }
15697
+ } finally {
15698
+ endOpenToolSpans(state);
15699
+ state.span.end();
15700
+ }
15701
+ }
15702
+ function endOpenToolSpans(state, error) {
15703
+ for (const [, toolState] of state.activeToolSpans) {
15704
+ finishToolSpan(toolState, { error });
15705
+ }
15706
+ state.activeToolSpans.clear();
15707
+ }
15708
+ function sanitizeUserMessage(message) {
15709
+ if (typeof message === "string" || message === void 0) {
15710
+ return message;
15711
+ }
15712
+ return {
15713
+ ...message,
15714
+ images: message.images?.map((image) => {
15715
+ const imageRecord = image;
15716
+ return {
15717
+ ...typeof imageRecord.url === "string" ? { url: imageRecord.url } : {},
15718
+ ...typeof imageRecord.mimeType === "string" ? { mimeType: imageRecord.mimeType } : {},
15719
+ ...image.dimension ? { dimension: image.dimension } : {},
15720
+ hasData: typeof imageRecord.data === "string"
15721
+ };
15722
+ })
15723
+ };
15724
+ }
15725
+ function extractAgentOptionsMetadata(options) {
15726
+ if (!options) {
15727
+ return {};
15728
+ }
15729
+ return {
15730
+ ...extractModelMetadata(options.model),
15731
+ ...options.agentId ? { "cursor_sdk.agent_id": options.agentId } : {},
15732
+ ...options.name ? { "cursor_sdk.agent_name": options.name } : {},
15733
+ ...options.local ? {
15734
+ "cursor_sdk.runtime": "local",
15735
+ "cursor_sdk.local.cwd": Array.isArray(options.local.cwd) ? options.local.cwd.join(",") : options.local.cwd
15736
+ } : {},
15737
+ ...options.cloud ? {
15738
+ "cursor_sdk.runtime": "cloud",
15739
+ "cursor_sdk.cloud.auto_create_pr": options.cloud.autoCreatePR,
15740
+ "cursor_sdk.cloud.env_type": options.cloud.env?.type,
15741
+ "cursor_sdk.cloud.env_name": options.cloud.env?.name,
15742
+ "cursor_sdk.cloud.repos": options.cloud.repos?.map((repo) => repo.url).filter((url) => typeof url === "string")
15743
+ } : {}
15744
+ };
15745
+ }
15746
+ function extractSendMetadata(options) {
15747
+ if (!options) {
15748
+ return {};
15749
+ }
15750
+ return {
15751
+ ...extractModelMetadata(options.model),
15752
+ ...options.local?.force !== void 0 ? { "cursor_sdk.local.force": options.local.force } : {}
15753
+ };
15754
+ }
15755
+ function extractAgentMetadata(agent) {
15756
+ return {
15757
+ ...agent.agentId ? { "cursor_sdk.agent_id": agent.agentId } : {},
15758
+ ...extractModelMetadata(agent.model)
15759
+ };
15760
+ }
15761
+ function extractRunMetadata(run) {
15762
+ if (!run) {
15763
+ return {};
15764
+ }
15765
+ return {
15766
+ ...run.id ? { "cursor_sdk.run_id": run.id } : {},
15767
+ ...run.agentId ? { "cursor_sdk.agent_id": run.agentId } : {},
15768
+ ...run.status ? { "cursor_sdk.status": run.status } : {},
15769
+ ...run.durationMs !== void 0 ? { "cursor_sdk.duration_ms": run.durationMs } : {},
15770
+ ...extractModelMetadata(run.model),
15771
+ ...extractGitMetadata(run.git)
15772
+ };
15773
+ }
15774
+ function extractRunResultMetadata(result) {
15775
+ if (!result) {
15776
+ return {};
15777
+ }
15778
+ return {
15779
+ ...result.id ? { "cursor_sdk.run_id": result.id } : {},
15780
+ ...result.status ? { "cursor_sdk.status": result.status } : {},
15781
+ ...result.durationMs !== void 0 ? { "cursor_sdk.duration_ms": result.durationMs } : {},
15782
+ ...extractModelMetadata(result.model),
15783
+ ...extractGitMetadata(result.git)
15784
+ };
15785
+ }
15786
+ function extractGitMetadata(git) {
15787
+ const branches = git?.branches;
15788
+ if (!branches || branches.length === 0) {
15789
+ return {};
15790
+ }
15791
+ return {
15792
+ "cursor_sdk.git.branches": branches.map((branch) => ({
15793
+ branch: branch.branch,
15794
+ prUrl: branch.prUrl,
15795
+ repoUrl: branch.repoUrl
15796
+ }))
15797
+ };
15798
+ }
15799
+ function extractModelMetadata(model) {
15800
+ if (!model?.id) {
15801
+ return {};
15802
+ }
15803
+ return {
15804
+ model: model.id,
15805
+ "cursor_sdk.model": model.id,
15806
+ ...model.params ? { "cursor_sdk.model.params": model.params } : {}
15807
+ };
15808
+ }
15809
+ function addUsageMetrics(metrics, usage) {
15810
+ if (!usage) {
15811
+ return;
15812
+ }
15813
+ if (usage.inputTokens !== void 0) {
15814
+ metrics.prompt_tokens = (metrics.prompt_tokens ?? 0) + usage.inputTokens;
15815
+ }
15816
+ if (usage.outputTokens !== void 0) {
15817
+ metrics.completion_tokens = (metrics.completion_tokens ?? 0) + usage.outputTokens;
15818
+ }
15819
+ if (usage.cacheReadTokens !== void 0) {
15820
+ metrics.prompt_cached_tokens = (metrics.prompt_cached_tokens ?? 0) + usage.cacheReadTokens;
15821
+ }
15822
+ if (usage.cacheWriteTokens !== void 0) {
15823
+ metrics.prompt_cache_creation_tokens = (metrics.prompt_cache_creation_tokens ?? 0) + usage.cacheWriteTokens;
15824
+ }
15825
+ metrics.tokens = (metrics.prompt_tokens ?? 0) + (metrics.completion_tokens ?? 0) + (metrics.prompt_cached_tokens ?? 0) + (metrics.prompt_cache_creation_tokens ?? 0);
15826
+ }
15827
+ function buildDurationMetrics(startTime) {
15828
+ const end = getCurrentUnixTimestamp();
15829
+ return {
15830
+ duration: end - startTime,
15831
+ end,
15832
+ start: startTime
15833
+ };
15834
+ }
15835
+ function extractToolName(toolCall) {
15836
+ if (!toolCall) {
15837
+ return "unknown";
15838
+ }
15839
+ if (typeof toolCall.name === "string") {
15840
+ return toolCall.name;
15841
+ }
15842
+ if (typeof toolCall.type === "string") {
15843
+ return toolCall.type;
15844
+ }
15845
+ return "unknown";
15846
+ }
15847
+ function extractToolArgs(toolCall) {
15848
+ return toolCall && "args" in toolCall ? toolCall.args : void 0;
15849
+ }
15850
+ function extractToolResult(toolCall) {
15851
+ return toolCall && "result" in toolCall ? toolCall.result : void 0;
15852
+ }
15853
+ function isSubAgentToolName(name) {
15854
+ return name === "Agent" || name === "Task" || name === "task";
15855
+ }
15856
+ function formatSubAgentSpanName2(toolCall, args) {
15857
+ const details = toolCall ?? args;
15858
+ const description = getString(details, "description") ?? getString(details, "subagent_type") ?? getString(details, "type") ?? getString(details, "name");
15859
+ return description ? `Agent: ${description}` : "Agent: sub-agent";
15860
+ }
15861
+ function getString(obj, key) {
15862
+ const value = obj?.[key];
15863
+ return typeof value === "string" ? value : void 0;
15864
+ }
15865
+ function stringifyUnknown(value) {
15866
+ if (value instanceof Error) {
15867
+ return value.message;
15868
+ }
15869
+ if (typeof value === "string") {
15870
+ return value;
15871
+ }
15872
+ try {
15873
+ return JSON.stringify(value);
15874
+ } catch {
15875
+ return String(value);
15876
+ }
15877
+ }
15878
+ function safeLog(span, event) {
15879
+ try {
15880
+ span.log(event);
15881
+ } catch (error) {
15882
+ logInstrumentationError("Cursor SDK span log", error);
15883
+ }
15884
+ }
15885
+ function logInstrumentationError(context, error) {
15886
+ debugLogger.error(`Error processing ${context}:`, error);
15887
+ }
15888
+ function cleanMetrics(metrics) {
15889
+ const cleaned = {};
15890
+ for (const [key, value] of Object.entries(metrics)) {
15891
+ if (value !== void 0 && Number.isFinite(value)) {
15892
+ cleaned[key] = value;
15893
+ }
15894
+ }
15895
+ return cleaned;
15896
+ }
15897
+
15898
+ // src/instrumentation/plugins/google-genai-channels.ts
15899
+ var googleGenAIChannels = defineChannels("@google/genai", {
15900
+ generateContent: channel({
15901
+ channelName: "models.generateContent",
15902
+ kind: "async"
15903
+ }),
15904
+ generateContentStream: channel({
15905
+ channelName: "models.generateContentStream",
15906
+ kind: "async"
15907
+ }),
15908
+ embedContent: channel({
15909
+ channelName: "models.embedContent",
15910
+ kind: "async"
15911
+ })
15912
+ });
15913
+
15914
+ // src/instrumentation/plugins/google-genai-plugin.ts
15915
+ var GOOGLE_GENAI_INTERNAL_CONTEXT = {
15916
+ caller_filename: "<node-internal>",
15917
+ caller_functionname: "<node-internal>",
15918
+ caller_lineno: 0
15919
+ };
15920
+ function createWrapperParityEvent(args) {
15921
+ return {
15922
+ context: GOOGLE_GENAI_INTERNAL_CONTEXT,
15923
+ input: args.input,
15924
+ metadata: args.metadata
15925
+ };
15926
+ }
15927
+ var GoogleGenAIPlugin = class extends BasePlugin {
15928
+ onEnable() {
15929
+ this.subscribeToGoogleGenAIChannels();
15930
+ }
15931
+ onDisable() {
15932
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
15933
+ }
15934
+ subscribeToGoogleGenAIChannels() {
15935
+ this.subscribeToGenerateContentChannel();
15936
+ this.subscribeToGenerateContentStreamChannel();
15937
+ this.subscribeToEmbedContentChannel();
15938
+ }
15939
+ subscribeToGenerateContentChannel() {
15940
+ const tracingChannel2 = googleGenAIChannels.generateContent.tracingChannel();
15941
+ const states = /* @__PURE__ */ new WeakMap();
15942
+ const unbindCurrentSpanStore = bindCurrentSpanStoreToStart2(
15943
+ tracingChannel2,
15944
+ states,
15945
+ (event) => {
15946
+ const params = event.arguments[0];
15947
+ const input = serializeGenerateContentInput(params);
15948
+ const metadata = extractGenerateContentMetadata(params);
15949
+ const span = startSpan({
15950
+ name: "generate_content",
15951
+ spanAttributes: {
15952
+ type: "llm" /* LLM */
15953
+ },
15954
+ event: createWrapperParityEvent({ input, metadata })
15955
+ });
15956
+ return {
14675
15957
  span,
14676
15958
  startTime: getCurrentUnixTimestamp()
14677
15959
  };
@@ -14705,7 +15987,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
14705
15987
  const responseMetadata = extractResponseMetadata(event.result);
14706
15988
  spanState.span.log({
14707
15989
  ...responseMetadata ? { metadata: responseMetadata } : {},
14708
- metrics: cleanMetrics(
15990
+ metrics: cleanMetrics2(
14709
15991
  extractGenerateContentMetrics(
14710
15992
  event.result,
14711
15993
  spanState.startTime
@@ -14806,7 +16088,7 @@ var GoogleGenAIPlugin = class extends BasePlugin {
14806
16088
  const output = summarizeEmbedContentOutput(event.result);
14807
16089
  spanState.span.log({
14808
16090
  ...output ? { output } : {},
14809
- metrics: cleanMetrics(
16091
+ metrics: cleanMetrics2(
14810
16092
  extractEmbedContentMetrics(event.result, spanState.startTime)
14811
16093
  )
14812
16094
  });
@@ -14903,7 +16185,7 @@ function patchGoogleGenAIStreamingResult(args) {
14903
16185
  );
14904
16186
  span.log({
14905
16187
  ...responseMetadata ? { metadata: responseMetadata } : {},
14906
- metrics: cleanMetrics(metricsWithoutEnd),
16188
+ metrics: cleanMetrics2(metricsWithoutEnd),
14907
16189
  output: options.result.aggregated
14908
16190
  });
14909
16191
  span.end(typeof end === "number" ? { endTime: end } : void 0);
@@ -15328,7 +16610,7 @@ function aggregateGenerateContentChunks(chunks, startTime, firstTokenTime) {
15328
16610
  }
15329
16611
  return { aggregated, metrics };
15330
16612
  }
15331
- function cleanMetrics(metrics) {
16613
+ function cleanMetrics2(metrics) {
15332
16614
  const cleaned = {};
15333
16615
  for (const [key, value] of Object.entries(metrics)) {
15334
16616
  if (value !== null && value !== void 0) {
@@ -15412,6 +16694,8 @@ var REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
15412
16694
  "stop",
15413
16695
  "stream",
15414
16696
  "temperature",
16697
+ "tool_choice",
16698
+ "tools",
15415
16699
  "top_p"
15416
16700
  ]);
15417
16701
  var RESPONSE_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
@@ -15674,7 +16958,10 @@ function aggregateChatCompletionChunks2(chunks) {
15674
16958
  for (const chunk of chunks) {
15675
16959
  for (const choice of chunk.choices ?? []) {
15676
16960
  const index = typeof choice.index === "number" ? choice.index : 0;
15677
- const existing = aggregatedChoices.get(index) ?? { content: "" };
16961
+ const existing = aggregatedChoices.get(index) ?? {
16962
+ content: "",
16963
+ toolCallsByIndex: /* @__PURE__ */ new Map()
16964
+ };
15678
16965
  const delta = isObject(choice.delta) ? choice.delta : void 0;
15679
16966
  const message = isObject(choice.message) ? choice.message : void 0;
15680
16967
  if (typeof delta?.content === "string") {
@@ -15690,6 +16977,10 @@ function aggregateChatCompletionChunks2(chunks) {
15690
16977
  if (choice.finish_reason !== void 0) {
15691
16978
  existing.finish_reason = choice.finish_reason;
15692
16979
  }
16980
+ const toolCallDeltas = getChatToolCallDeltas(delta) ?? getChatToolCallDeltas(message);
16981
+ if (toolCallDeltas) {
16982
+ mergeChatToolCallDeltas(existing.toolCallsByIndex, toolCallDeltas);
16983
+ }
15693
16984
  aggregatedChoices.set(index, existing);
15694
16985
  }
15695
16986
  }
@@ -15698,12 +16989,72 @@ function aggregateChatCompletionChunks2(chunks) {
15698
16989
  index,
15699
16990
  message: {
15700
16991
  content: choice.content,
15701
- role: choice.role ?? "assistant"
16992
+ role: choice.role ?? "assistant",
16993
+ ...choice.toolCallsByIndex.size > 0 ? {
16994
+ tool_calls: [...choice.toolCallsByIndex.entries()].sort(([leftIndex], [rightIndex]) => leftIndex - rightIndex).map(([, toolCall]) => toolCall)
16995
+ } : {}
15702
16996
  },
15703
16997
  ...choice.finish_reason !== void 0 ? { finish_reason: choice.finish_reason } : {}
15704
16998
  }))
15705
16999
  };
15706
17000
  }
17001
+ function getChatToolCallDeltas(value) {
17002
+ if (!Array.isArray(value?.tool_calls)) {
17003
+ return void 0;
17004
+ }
17005
+ const toolCalls = value.tool_calls.filter((toolCall) => isObject(toolCall));
17006
+ return toolCalls.length > 0 ? toolCalls : void 0;
17007
+ }
17008
+ function mergeChatToolCallDeltas(toolCallsByIndex, toolCallDeltas) {
17009
+ for (const toolDelta of toolCallDeltas) {
17010
+ const toolIndex = typeof toolDelta.index === "number" && toolDelta.index >= 0 ? toolDelta.index : 0;
17011
+ const existing = toolCallsByIndex.get(toolIndex);
17012
+ if (!existing) {
17013
+ toolCallsByIndex.set(toolIndex, createChatToolCall(toolDelta));
17014
+ continue;
17015
+ }
17016
+ mergeChatToolCall(existing, toolDelta);
17017
+ }
17018
+ }
17019
+ function createChatToolCall(toolDelta) {
17020
+ const toolFunction = isObject(toolDelta.function) ? toolDelta.function : {};
17021
+ const toolCallFunction = {
17022
+ arguments: typeof toolFunction.arguments === "string" ? toolFunction.arguments : ""
17023
+ };
17024
+ if (typeof toolFunction.name === "string") {
17025
+ toolCallFunction.name = toolFunction.name;
17026
+ }
17027
+ const toolCall = {
17028
+ function: toolCallFunction
17029
+ };
17030
+ if (typeof toolDelta.id === "string") {
17031
+ toolCall.id = toolDelta.id;
17032
+ }
17033
+ if (typeof toolDelta.type === "string") {
17034
+ toolCall.type = toolDelta.type;
17035
+ }
17036
+ return toolCall;
17037
+ }
17038
+ function mergeChatToolCall(existing, toolDelta) {
17039
+ const currentFunction = isObject(existing.function) ? existing.function : {};
17040
+ const deltaFunction = isObject(toolDelta.function) ? toolDelta.function : {};
17041
+ const currentArguments = typeof currentFunction.arguments === "string" ? currentFunction.arguments : "";
17042
+ const deltaArguments = typeof deltaFunction.arguments === "string" ? deltaFunction.arguments : "";
17043
+ if (typeof toolDelta.id === "string" && typeof existing.id !== "string") {
17044
+ existing.id = toolDelta.id;
17045
+ }
17046
+ if (typeof toolDelta.type === "string" && typeof existing.type !== "string") {
17047
+ existing.type = toolDelta.type;
17048
+ }
17049
+ const nextFunction = {
17050
+ ...currentFunction,
17051
+ arguments: `${currentArguments}${deltaArguments}`
17052
+ };
17053
+ if (typeof deltaFunction.name === "string" && typeof currentFunction.name !== "string") {
17054
+ nextFunction.name = deltaFunction.name;
17055
+ }
17056
+ existing.function = nextFunction;
17057
+ }
15707
17058
  function aggregateTextGenerationStreamChunks(chunks) {
15708
17059
  if (chunks.length === 0) {
15709
17060
  return void 0;
@@ -17748,6 +19099,8 @@ var MISTRAL_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
17748
19099
  "presence_penalty",
17749
19100
  "randomSeed",
17750
19101
  "random_seed",
19102
+ "reasoningEffort",
19103
+ "reasoning_effort",
17751
19104
  "responseFormat",
17752
19105
  "response_format",
17753
19106
  "safePrompt",
@@ -17888,6 +19241,98 @@ function extractDeltaText(content) {
17888
19241
  }).filter((part) => part.length > 0);
17889
19242
  return textParts.length > 0 ? textParts.join("") : void 0;
17890
19243
  }
19244
+ function normalizeMistralTextContentPart(part) {
19245
+ if (!isObject(part) || part.type !== "text" || typeof part.text !== "string") {
19246
+ return void 0;
19247
+ }
19248
+ return {
19249
+ type: "text",
19250
+ text: part.text
19251
+ };
19252
+ }
19253
+ function normalizeMistralThinkingContentPart(part) {
19254
+ if (!isObject(part) || part.type !== "thinking") {
19255
+ return void 0;
19256
+ }
19257
+ const thinking = Array.isArray(part.thinking) ? part.thinking.map((thinkingPart) => normalizeMistralTextContentPart(thinkingPart)).filter(
19258
+ (thinkingPart) => thinkingPart !== void 0 && typeof thinkingPart.text === "string"
19259
+ ) : [];
19260
+ return {
19261
+ type: "thinking",
19262
+ thinking
19263
+ };
19264
+ }
19265
+ function normalizeMistralContentParts(content) {
19266
+ if (!Array.isArray(content)) {
19267
+ return [];
19268
+ }
19269
+ return content.map((part) => {
19270
+ return normalizeMistralTextContentPart(part) || normalizeMistralThinkingContentPart(part);
19271
+ }).filter((part) => part !== void 0);
19272
+ }
19273
+ function mergeMistralTextSegments(left, right) {
19274
+ const merged = left.map((part) => ({ ...part }));
19275
+ for (const part of right) {
19276
+ const lastPart = merged[merged.length - 1];
19277
+ if (lastPart && lastPart.type === "text" && typeof lastPart.text === "string" && typeof part.text === "string") {
19278
+ lastPart.text += part.text;
19279
+ continue;
19280
+ }
19281
+ merged.push({ ...part });
19282
+ }
19283
+ return merged;
19284
+ }
19285
+ function mergeMistralContentParts(left, right) {
19286
+ const merged = [...(left || []).map((part) => structuredClone(part))];
19287
+ for (const part of right) {
19288
+ const lastPart = merged[merged.length - 1];
19289
+ if (part.type === "text" && lastPart?.type === "text" && typeof lastPart.text === "string" && typeof part.text === "string") {
19290
+ lastPart.text += part.text;
19291
+ continue;
19292
+ }
19293
+ if (part.type === "thinking" && lastPart?.type === "thinking" && Array.isArray(lastPart.thinking) && Array.isArray(part.thinking)) {
19294
+ lastPart.thinking = mergeMistralTextSegments(
19295
+ lastPart.thinking,
19296
+ part.thinking
19297
+ );
19298
+ continue;
19299
+ }
19300
+ merged.push(structuredClone(part));
19301
+ }
19302
+ return merged;
19303
+ }
19304
+ function appendMistralContent(accumulator, content) {
19305
+ if (typeof content === "string") {
19306
+ if (accumulator.contentParts) {
19307
+ accumulator.contentParts = mergeMistralContentParts(
19308
+ accumulator.contentParts,
19309
+ [{ type: "text", text: content }]
19310
+ );
19311
+ return;
19312
+ }
19313
+ accumulator.content = `${accumulator.content || ""}${content}`;
19314
+ return;
19315
+ }
19316
+ const normalizedContentParts = normalizeMistralContentParts(content);
19317
+ if (normalizedContentParts.length === 0) {
19318
+ return;
19319
+ }
19320
+ const hasStructuredContent = normalizedContentParts.some(
19321
+ (part) => part.type !== "text"
19322
+ );
19323
+ if (!accumulator.contentParts && !hasStructuredContent) {
19324
+ const text = extractDeltaText(content);
19325
+ if (text) {
19326
+ accumulator.content = `${accumulator.content || ""}${text}`;
19327
+ }
19328
+ return;
19329
+ }
19330
+ accumulator.contentParts = mergeMistralContentParts(
19331
+ accumulator.contentParts || (accumulator.content ? [{ type: "text", text: accumulator.content }] : []),
19332
+ normalizedContentParts
19333
+ );
19334
+ delete accumulator.content;
19335
+ }
17891
19336
  function getDeltaToolCalls(delta) {
17892
19337
  const toolCalls = Array.isArray(delta.toolCalls) && delta.toolCalls || Array.isArray(delta.tool_calls) && delta.tool_calls || [];
17893
19338
  return toolCalls.filter((toolCall) => isObject(toolCall));
@@ -18056,10 +19501,7 @@ function aggregateMistralStreamChunks(chunks) {
18056
19501
  if (!accumulator.role && typeof delta.role === "string") {
18057
19502
  accumulator.role = delta.role;
18058
19503
  }
18059
- const deltaText = extractDeltaText(delta.content);
18060
- if (deltaText) {
18061
- accumulator.content = `${accumulator.content || ""}${deltaText}`;
18062
- }
19504
+ appendMistralContent(accumulator, delta.content);
18063
19505
  accumulator.toolCalls = mergeToolCallDeltas(
18064
19506
  accumulator.toolCalls,
18065
19507
  getDeltaToolCalls(delta)
@@ -18077,7 +19519,7 @@ function aggregateMistralStreamChunks(chunks) {
18077
19519
  index: choice.index,
18078
19520
  message: {
18079
19521
  ...choice.role ? { role: choice.role } : {},
18080
- content: choice.content ?? null,
19522
+ content: choice.contentParts ?? choice.content ?? null,
18081
19523
  ...choice.toolCalls ? { toolCalls: choice.toolCalls } : {}
18082
19524
  },
18083
19525
  ...choice.finishReason !== void 0 ? { finishReason: choice.finishReason } : {}
@@ -18316,7 +19758,7 @@ var GoogleADKPlugin = class extends BasePlugin {
18316
19758
  start: (event) => {
18317
19759
  const req = event.arguments[0] ?? {};
18318
19760
  const tool = event.self;
18319
- const toolName = extractToolName(req, tool);
19761
+ const toolName = extractToolName2(req, tool);
18320
19762
  const parentSpan = findToolParentSpan(
18321
19763
  req,
18322
19764
  this.activeAgentSpans,
@@ -18355,7 +19797,7 @@ var GoogleADKPlugin = class extends BasePlugin {
18355
19797
  metrics.duration = end - state.startTime;
18356
19798
  state.span.log({
18357
19799
  output: event.result,
18358
- metrics: cleanMetrics2(metrics)
19800
+ metrics: cleanMetrics3(metrics)
18359
19801
  });
18360
19802
  } finally {
18361
19803
  state.span.end();
@@ -18574,7 +20016,7 @@ function extractToolCallId(req) {
18574
20016
  const toolContext = req.toolContext;
18575
20017
  return toolContext?.functionCallId;
18576
20018
  }
18577
- function extractToolName(req, tool) {
20019
+ function extractToolName2(req, tool) {
18578
20020
  if (typeof tool?.name === "string" && tool.name.length > 0) {
18579
20021
  return tool.name;
18580
20022
  }
@@ -18622,7 +20064,7 @@ function finalizeRunnerSpan(state, activeRunnerSpans) {
18622
20064
  }
18623
20065
  state.span.log({
18624
20066
  output: lastEvent ? extractEventOutput(lastEvent) : void 0,
18625
- metrics: cleanMetrics2(metrics)
20067
+ metrics: cleanMetrics3(metrics)
18626
20068
  });
18627
20069
  } finally {
18628
20070
  cleanupActiveRunnerSpan(state, activeRunnerSpans);
@@ -18639,7 +20081,7 @@ function finalizeAgentSpan(state, activeAgentSpans) {
18639
20081
  metrics.duration = end - state.startTime;
18640
20082
  state.span.log({
18641
20083
  output: lastEvent ? extractEventOutput(lastEvent) : void 0,
18642
- metrics: cleanMetrics2(metrics)
20084
+ metrics: cleanMetrics3(metrics)
18643
20085
  });
18644
20086
  } finally {
18645
20087
  cleanupActiveAgentSpan(state, activeAgentSpans);
@@ -18725,7 +20167,7 @@ function populateUsageMetrics2(metrics, usage) {
18725
20167
  metrics.completion_reasoning_tokens = usage.thoughtsTokenCount;
18726
20168
  }
18727
20169
  }
18728
- function cleanMetrics2(metrics) {
20170
+ function cleanMetrics3(metrics) {
18729
20171
  const cleaned = {};
18730
20172
  for (const [key, value] of Object.entries(metrics)) {
18731
20173
  if (value !== null && value !== void 0) {
@@ -18853,6 +20295,11 @@ var CHAT_REQUEST_METADATA_ALLOWLIST = /* @__PURE__ */ new Set([
18853
20295
  "strictTools",
18854
20296
  "strict_tools",
18855
20297
  "temperature",
20298
+ "thinking",
20299
+ "thinkingTokenBudget",
20300
+ "thinkingType",
20301
+ "thinking_token_budget",
20302
+ "thinking_type",
18856
20303
  "toolChoice",
18857
20304
  "tool_choice"
18858
20305
  ]);
@@ -19073,6 +20520,11 @@ function mergeUsageMetrics(metrics, usage) {
19073
20520
  "tokens",
19074
20521
  tokenContainer.totalTokens ?? tokenContainer.total_tokens
19075
20522
  );
20523
+ setMetricIfNumber(
20524
+ metrics,
20525
+ "reasoning_tokens",
20526
+ tokenContainer.reasoningTokens ?? tokenContainer.reasoning_tokens ?? tokenContainer.thinkingTokens ?? tokenContainer.thinking_tokens
20527
+ );
19076
20528
  }
19077
20529
  const billedUnits = (isObject(source.billedUnits) ? source.billedUnits : void 0) || (isObject(source.billed_units) ? source.billed_units : void 0);
19078
20530
  if (billedUnits) {
@@ -19153,13 +20605,87 @@ function extractV8DeltaText(chunk) {
19153
20605
  }
19154
20606
  return void 0;
19155
20607
  }
20608
+ function getV8ContentIndex(chunk) {
20609
+ return typeof chunk.index === "number" ? chunk.index : 0;
20610
+ }
20611
+ function toContentBlockType(value) {
20612
+ return value === "text" || value === "thinking" ? value : void 0;
20613
+ }
20614
+ function getOrCreateContentBlock(contentBlocksByIndex, contentBlockOrder, index) {
20615
+ if (!contentBlockOrder.includes(index)) {
20616
+ contentBlockOrder.push(index);
20617
+ }
20618
+ if (!(index in contentBlocksByIndex)) {
20619
+ contentBlocksByIndex[index] = {
20620
+ text: "",
20621
+ thinking: ""
20622
+ };
20623
+ }
20624
+ return contentBlocksByIndex[index];
20625
+ }
20626
+ function appendV8ContentBlock(contentBlocksByIndex, contentBlockOrder, index, content) {
20627
+ if (typeof content === "string") {
20628
+ const block2 = getOrCreateContentBlock(
20629
+ contentBlocksByIndex,
20630
+ contentBlockOrder,
20631
+ index
20632
+ );
20633
+ block2.type ??= "text";
20634
+ block2.text += content;
20635
+ return;
20636
+ }
20637
+ if (!isObject(content)) {
20638
+ return;
20639
+ }
20640
+ const block = getOrCreateContentBlock(
20641
+ contentBlocksByIndex,
20642
+ contentBlockOrder,
20643
+ index
20644
+ );
20645
+ const contentType = toContentBlockType(content.type);
20646
+ if (contentType) {
20647
+ block.type = contentType;
20648
+ }
20649
+ if (typeof content.text === "string") {
20650
+ block.type ??= "text";
20651
+ block.text += content.text;
20652
+ }
20653
+ if (typeof content.thinking === "string") {
20654
+ block.type ??= "thinking";
20655
+ block.thinking += content.thinking;
20656
+ }
20657
+ }
20658
+ function serializeAggregatedContentBlocks(contentBlocksByIndex, contentBlockOrder) {
20659
+ return contentBlockOrder.sort((left, right) => left - right).flatMap((index) => {
20660
+ const block = contentBlocksByIndex[index];
20661
+ if (!block) {
20662
+ return [];
20663
+ }
20664
+ if (block.type === "thinking" && block.thinking.length > 0) {
20665
+ return [{ type: "thinking", thinking: block.thinking }];
20666
+ }
20667
+ if (block.text.length > 0) {
20668
+ return [{ type: "text", text: block.text }];
20669
+ }
20670
+ if (block.thinking.length > 0) {
20671
+ return [{ type: "thinking", thinking: block.thinking }];
20672
+ }
20673
+ return [];
20674
+ });
20675
+ }
20676
+ function hasThinkingContent(contentBlocks) {
20677
+ return contentBlocks.some((block) => block.type === "thinking");
20678
+ }
19156
20679
  function aggregateCohereChatStreamChunks(chunks) {
19157
20680
  const textDeltas = [];
20681
+ const contentBlocksByIndex = {};
20682
+ const contentBlockOrder = [];
19158
20683
  const toolCallsByIndex = {};
19159
20684
  const toolCallOrder = [];
19160
20685
  let terminalResponse;
19161
20686
  let role;
19162
20687
  let finishReason;
20688
+ let toolPlan = "";
19163
20689
  let metadata = {};
19164
20690
  let metrics = {};
19165
20691
  for (const chunk of chunks) {
@@ -19217,12 +20743,36 @@ function aggregateCohereChatStreamChunks(chunks) {
19217
20743
  continue;
19218
20744
  }
19219
20745
  if (eventType === "content-delta") {
20746
+ appendV8ContentBlock(
20747
+ contentBlocksByIndex,
20748
+ contentBlockOrder,
20749
+ getV8ContentIndex(chunk),
20750
+ isObject(chunk.delta) && isObject(chunk.delta.message) ? chunk.delta.message.content : void 0
20751
+ );
19220
20752
  const text = extractV8DeltaText(chunk);
19221
20753
  if (text) {
19222
20754
  textDeltas.push(text);
19223
20755
  }
19224
20756
  continue;
19225
20757
  }
20758
+ if (eventType === "content-start") {
20759
+ appendV8ContentBlock(
20760
+ contentBlocksByIndex,
20761
+ contentBlockOrder,
20762
+ getV8ContentIndex(chunk),
20763
+ isObject(chunk.delta) && isObject(chunk.delta.message) ? chunk.delta.message.content : void 0
20764
+ );
20765
+ continue;
20766
+ }
20767
+ if (eventType === "tool-plan-delta") {
20768
+ if (isObject(chunk.delta) && isObject(chunk.delta.message)) {
20769
+ 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;
20770
+ if (deltaToolPlan) {
20771
+ toolPlan += deltaToolPlan;
20772
+ }
20773
+ }
20774
+ continue;
20775
+ }
19226
20776
  if (eventType === "tool-call-start") {
19227
20777
  const toolCalls = isObject(chunk.delta) && isObject(chunk.delta.message) ? toToolCallArray(
19228
20778
  Array.isArray(chunk.delta.message.toolCalls) ? chunk.delta.message.toolCalls : chunk.delta.message.toolCalls ?? chunk.delta.message.tool_calls
@@ -19276,13 +20826,26 @@ function aggregateCohereChatStreamChunks(chunks) {
19276
20826
  }
19277
20827
  }
19278
20828
  const mergedToolCalls = toolCallOrder.sort((left, right) => left - right).map((index) => toolCallsByIndex[index]).filter((toolCall) => isObject(toolCall));
20829
+ const aggregatedContentBlocks = serializeAggregatedContentBlocks(
20830
+ contentBlocksByIndex,
20831
+ contentBlockOrder
20832
+ );
19279
20833
  let output = extractCohereChatOutput(terminalResponse);
19280
20834
  if (output === void 0) {
19281
20835
  const mergedText = textDeltas.join("");
19282
- if (mergedToolCalls.length > 0 || role || mergedText.length > 0) {
20836
+ const shouldUseStructuredContent = hasThinkingContent(aggregatedContentBlocks) || toolPlan.length > 0;
20837
+ if (shouldUseStructuredContent) {
20838
+ output = {
20839
+ ...role ? { role } : {},
20840
+ ...aggregatedContentBlocks.length > 0 ? { content: aggregatedContentBlocks } : {},
20841
+ ...toolPlan.length > 0 ? { toolPlan } : {},
20842
+ ...mergedToolCalls.length > 0 ? { toolCalls: mergedToolCalls } : {}
20843
+ };
20844
+ } else if (mergedToolCalls.length > 0 || role || mergedText.length > 0 || aggregatedContentBlocks.length > 0) {
20845
+ const textContent = mergedText.length > 0 ? mergedText : aggregatedContentBlocks[0]?.type === "text" ? aggregatedContentBlocks[0].text : void 0;
19283
20846
  output = {
19284
20847
  ...role ? { role } : {},
19285
- ...mergedText.length > 0 ? { content: mergedText } : {},
20848
+ ...textContent ? { content: textContent } : {},
19286
20849
  ...mergedToolCalls.length > 0 ? { toolCalls: mergedToolCalls } : {}
19287
20850
  };
19288
20851
  }
@@ -19300,6 +20863,98 @@ function aggregateCohereChatStreamChunks(chunks) {
19300
20863
  };
19301
20864
  }
19302
20865
 
20866
+ // src/instrumentation/plugins/groq-channels.ts
20867
+ var groqChannels = defineChannels("groq-sdk", {
20868
+ chatCompletionsCreate: channel({
20869
+ channelName: "chat.completions.create",
20870
+ kind: "async"
20871
+ }),
20872
+ embeddingsCreate: channel(
20873
+ {
20874
+ channelName: "embeddings.create",
20875
+ kind: "async"
20876
+ }
20877
+ )
20878
+ });
20879
+
20880
+ // src/instrumentation/plugins/groq-plugin.ts
20881
+ var GroqPlugin = class extends BasePlugin {
20882
+ onEnable() {
20883
+ this.unsubscribers.push(
20884
+ traceStreamingChannel(groqChannels.chatCompletionsCreate, {
20885
+ name: "groq.chat.completions.create",
20886
+ type: "llm" /* LLM */,
20887
+ extractInput: ([params]) => {
20888
+ const { messages, ...metadata } = params;
20889
+ return {
20890
+ input: processInputAttachments(messages),
20891
+ metadata: { ...metadata, provider: "groq" }
20892
+ };
20893
+ },
20894
+ extractOutput: (result) => result?.choices,
20895
+ extractMetrics: (result, startTime) => {
20896
+ const metrics = parseGroqMetrics(result);
20897
+ if (startTime) {
20898
+ metrics.time_to_first_token = getCurrentUnixTimestamp() - startTime;
20899
+ }
20900
+ return metrics;
20901
+ },
20902
+ aggregateChunks: aggregateGroqChatCompletionChunks
20903
+ })
20904
+ );
20905
+ this.unsubscribers.push(
20906
+ traceAsyncChannel(groqChannels.embeddingsCreate, {
20907
+ name: "groq.embeddings.create",
20908
+ type: "llm" /* LLM */,
20909
+ extractInput: ([params]) => {
20910
+ const { input, ...metadata } = params;
20911
+ return {
20912
+ input,
20913
+ metadata: { ...metadata, provider: "groq" }
20914
+ };
20915
+ },
20916
+ extractOutput: (result) => {
20917
+ const embedding = result?.data?.[0]?.embedding;
20918
+ return Array.isArray(embedding) ? { embedding_length: embedding.length } : void 0;
20919
+ },
20920
+ extractMetrics: (result) => parseGroqMetrics(result)
20921
+ })
20922
+ );
20923
+ }
20924
+ onDisable() {
20925
+ this.unsubscribers = unsubscribeAll(this.unsubscribers);
20926
+ }
20927
+ };
20928
+ function parseGroqMetrics(result) {
20929
+ const metrics = parseMetricsFromUsage(result?.usage);
20930
+ const xGroq = result?.x_groq;
20931
+ if (!xGroq || typeof xGroq !== "object") {
20932
+ return metrics;
20933
+ }
20934
+ const extraUsage = "usage" in xGroq ? xGroq.usage : void 0;
20935
+ if (!extraUsage || typeof extraUsage !== "object") {
20936
+ return metrics;
20937
+ }
20938
+ const dramCachedTokens = extraUsage["dram_cached_tokens"];
20939
+ const sramCachedTokens = extraUsage["sram_cached_tokens"];
20940
+ return {
20941
+ ...metrics,
20942
+ ...typeof dramCachedTokens === "number" ? { dram_cached_tokens: dramCachedTokens } : {},
20943
+ ...typeof sramCachedTokens === "number" ? { sram_cached_tokens: sramCachedTokens } : {}
20944
+ };
20945
+ }
20946
+ function aggregateGroqChatCompletionChunks(chunks, streamResult, endEvent) {
20947
+ const aggregated = aggregateChatCompletionChunks(
20948
+ chunks,
20949
+ streamResult,
20950
+ endEvent
20951
+ );
20952
+ return {
20953
+ metrics: aggregated.metrics,
20954
+ output: aggregated.output
20955
+ };
20956
+ }
20957
+
19303
20958
  // src/instrumentation/braintrust-plugin.ts
19304
20959
  var BraintrustPlugin = class extends BasePlugin {
19305
20960
  config;
@@ -19307,6 +20962,7 @@ var BraintrustPlugin = class extends BasePlugin {
19307
20962
  anthropicPlugin = null;
19308
20963
  aiSDKPlugin = null;
19309
20964
  claudeAgentSDKPlugin = null;
20965
+ cursorSDKPlugin = null;
19310
20966
  googleGenAIPlugin = null;
19311
20967
  huggingFacePlugin = null;
19312
20968
  openRouterPlugin = null;
@@ -19314,6 +20970,7 @@ var BraintrustPlugin = class extends BasePlugin {
19314
20970
  mistralPlugin = null;
19315
20971
  googleADKPlugin = null;
19316
20972
  coherePlugin = null;
20973
+ groqPlugin = null;
19317
20974
  constructor(config = {}) {
19318
20975
  super();
19319
20976
  this.config = config;
@@ -19336,6 +20993,10 @@ var BraintrustPlugin = class extends BasePlugin {
19336
20993
  this.claudeAgentSDKPlugin = new ClaudeAgentSDKPlugin();
19337
20994
  this.claudeAgentSDKPlugin.enable();
19338
20995
  }
20996
+ if (integrations.cursorSDK !== false && integrations.cursor !== false) {
20997
+ this.cursorSDKPlugin = new CursorSDKPlugin();
20998
+ this.cursorSDKPlugin.enable();
20999
+ }
19339
21000
  if (integrations.googleGenAI !== false && integrations.google !== false) {
19340
21001
  this.googleGenAIPlugin = new GoogleGenAIPlugin();
19341
21002
  this.googleGenAIPlugin.enable();
@@ -19364,6 +21025,10 @@ var BraintrustPlugin = class extends BasePlugin {
19364
21025
  this.coherePlugin = new CoherePlugin();
19365
21026
  this.coherePlugin.enable();
19366
21027
  }
21028
+ if (integrations.groq !== false) {
21029
+ this.groqPlugin = new GroqPlugin();
21030
+ this.groqPlugin.enable();
21031
+ }
19367
21032
  }
19368
21033
  onDisable() {
19369
21034
  if (this.openaiPlugin) {
@@ -19382,6 +21047,10 @@ var BraintrustPlugin = class extends BasePlugin {
19382
21047
  this.claudeAgentSDKPlugin.disable();
19383
21048
  this.claudeAgentSDKPlugin = null;
19384
21049
  }
21050
+ if (this.cursorSDKPlugin) {
21051
+ this.cursorSDKPlugin.disable();
21052
+ this.cursorSDKPlugin = null;
21053
+ }
19385
21054
  if (this.googleGenAIPlugin) {
19386
21055
  this.googleGenAIPlugin.disable();
19387
21056
  this.googleGenAIPlugin = null;
@@ -19410,6 +21079,10 @@ var BraintrustPlugin = class extends BasePlugin {
19410
21079
  this.coherePlugin.disable();
19411
21080
  this.coherePlugin = null;
19412
21081
  }
21082
+ if (this.groqPlugin) {
21083
+ this.groqPlugin.disable();
21084
+ this.groqPlugin = null;
21085
+ }
19413
21086
  }
19414
21087
  };
19415
21088
 
@@ -19483,6 +21156,8 @@ var PluginRegistry = class {
19483
21156
  google: true,
19484
21157
  huggingface: true,
19485
21158
  claudeAgentSDK: true,
21159
+ cursor: true,
21160
+ cursorSDK: true,
19486
21161
  openrouter: true,
19487
21162
  openrouterAgent: true,
19488
21163
  mistral: true,
@@ -19499,7 +21174,11 @@ var PluginRegistry = class {
19499
21174
  if (disabledList) {
19500
21175
  const disabled = disabledList.split(",").map((s) => s.trim().toLowerCase()).filter((s) => s.length > 0);
19501
21176
  for (const sdk of disabled) {
19502
- integrations[sdk] = false;
21177
+ if (sdk === "cursor-sdk") {
21178
+ integrations.cursorSDK = false;
21179
+ } else {
21180
+ integrations[sdk] = false;
21181
+ }
19503
21182
  }
19504
21183
  }
19505
21184
  return { integrations };
@@ -23021,6 +24700,8 @@ async function getDataset(state, data) {
23021
24700
  state,
23022
24701
  project: data.project_name,
23023
24702
  dataset: data.dataset_name,
24703
+ version: data.dataset_version ?? void 0,
24704
+ environment: data.dataset_environment ?? void 0,
23024
24705
  _internal_btql: data._internal_btql ?? void 0
23025
24706
  });
23026
24707
  } else if ("dataset_id" in data) {
@@ -23032,6 +24713,8 @@ async function getDataset(state, data) {
23032
24713
  state,
23033
24714
  projectId: datasetInfo.projectId,
23034
24715
  dataset: datasetInfo.dataset,
24716
+ version: data.dataset_version ?? void 0,
24717
+ environment: data.dataset_environment ?? void 0,
23035
24718
  _internal_btql: data._internal_btql ?? void 0
23036
24719
  });
23037
24720
  } else {