braintrust 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7454,6 +7454,12 @@ interface Span extends Exportable {
7454
7454
  */
7455
7455
  startSpanWithParents(spanId: string, spanParents: string[], args?: StartSpanArgs): Span;
7456
7456
  state(): BraintrustState;
7457
+ /**
7458
+ * Internal method to get the OTEL parent string for this span.
7459
+ * This is used by OtelContextManager to set the braintrust.parent attribute.
7460
+ * @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
7461
+ */
7462
+ _getOtelParent(): string | undefined;
7457
7463
  kind: "span";
7458
7464
  }
7459
7465
  declare abstract class ContextManager {
@@ -7484,6 +7490,7 @@ declare class NoopSpan implements Span {
7484
7490
  setAttributes(_args: Omit<StartSpanArgs, "event">): void;
7485
7491
  startSpanWithParents(_spanId: string, _spanParents: string[], _args?: StartSpanArgs): Span;
7486
7492
  state(): BraintrustState;
7493
+ _getOtelParent(): string | undefined;
7487
7494
  toString(): string;
7488
7495
  }
7489
7496
  declare const NOOP_SPAN: NoopSpan;
@@ -7645,6 +7652,7 @@ declare class Logger<IsAsyncFlush extends boolean> implements Exportable {
7645
7652
  get org_id(): Promise<string>;
7646
7653
  get project(): Promise<ObjectMetadata>;
7647
7654
  get id(): Promise<string>;
7655
+ get loggingState(): BraintrustState;
7648
7656
  private parentObjectType;
7649
7657
  /**
7650
7658
  * Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
@@ -7861,6 +7869,13 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
7861
7869
  kind: "experiment";
7862
7870
  constructor(state: BraintrustState, lazyMetadata: LazyValue<ProjectExperimentMetadata>, dataset?: AnyDataset);
7863
7871
  get id(): Promise<string>;
7872
+ get loggingState(): BraintrustState;
7873
+ /**
7874
+ * Wait for the experiment ID to be resolved. This is useful for ensuring the ID
7875
+ * is available synchronously in child spans (for OTEL parent attributes).
7876
+ * @internal
7877
+ */
7878
+ _waitForId(): Promise<void>;
7864
7879
  get name(): Promise<string>;
7865
7880
  get project(): Promise<ObjectMetadata>;
7866
7881
  private parentObjectType;
@@ -7966,6 +7981,7 @@ declare class Dataset<IsLegacyDataset extends boolean = typeof DEFAULT_IS_LEGACY
7966
7981
  get id(): Promise<string>;
7967
7982
  get name(): Promise<string>;
7968
7983
  get project(): Promise<ObjectMetadata>;
7984
+ get loggingState(): BraintrustState;
7969
7985
  protected getState(): Promise<BraintrustState>;
7970
7986
  private validateEvent;
7971
7987
  private createArgs;
@@ -7454,6 +7454,12 @@ interface Span extends Exportable {
7454
7454
  */
7455
7455
  startSpanWithParents(spanId: string, spanParents: string[], args?: StartSpanArgs): Span;
7456
7456
  state(): BraintrustState;
7457
+ /**
7458
+ * Internal method to get the OTEL parent string for this span.
7459
+ * This is used by OtelContextManager to set the braintrust.parent attribute.
7460
+ * @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
7461
+ */
7462
+ _getOtelParent(): string | undefined;
7457
7463
  kind: "span";
7458
7464
  }
7459
7465
  declare abstract class ContextManager {
@@ -7484,6 +7490,7 @@ declare class NoopSpan implements Span {
7484
7490
  setAttributes(_args: Omit<StartSpanArgs, "event">): void;
7485
7491
  startSpanWithParents(_spanId: string, _spanParents: string[], _args?: StartSpanArgs): Span;
7486
7492
  state(): BraintrustState;
7493
+ _getOtelParent(): string | undefined;
7487
7494
  toString(): string;
7488
7495
  }
7489
7496
  declare const NOOP_SPAN: NoopSpan;
@@ -7645,6 +7652,7 @@ declare class Logger<IsAsyncFlush extends boolean> implements Exportable {
7645
7652
  get org_id(): Promise<string>;
7646
7653
  get project(): Promise<ObjectMetadata>;
7647
7654
  get id(): Promise<string>;
7655
+ get loggingState(): BraintrustState;
7648
7656
  private parentObjectType;
7649
7657
  /**
7650
7658
  * Log a single event. The event will be batched and uploaded behind the scenes if `logOptions.asyncFlush` is true.
@@ -7861,6 +7869,13 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
7861
7869
  kind: "experiment";
7862
7870
  constructor(state: BraintrustState, lazyMetadata: LazyValue<ProjectExperimentMetadata>, dataset?: AnyDataset);
7863
7871
  get id(): Promise<string>;
7872
+ get loggingState(): BraintrustState;
7873
+ /**
7874
+ * Wait for the experiment ID to be resolved. This is useful for ensuring the ID
7875
+ * is available synchronously in child spans (for OTEL parent attributes).
7876
+ * @internal
7877
+ */
7878
+ _waitForId(): Promise<void>;
7864
7879
  get name(): Promise<string>;
7865
7880
  get project(): Promise<ObjectMetadata>;
7866
7881
  private parentObjectType;
@@ -7966,6 +7981,7 @@ declare class Dataset<IsLegacyDataset extends boolean = typeof DEFAULT_IS_LEGACY
7966
7981
  get id(): Promise<string>;
7967
7982
  get name(): Promise<string>;
7968
7983
  get project(): Promise<ObjectMetadata>;
7984
+ get loggingState(): BraintrustState;
7969
7985
  protected getState(): Promise<BraintrustState>;
7970
7986
  private validateEvent;
7971
7987
  private createArgs;
package/dev/dist/index.js CHANGED
@@ -5141,7 +5141,6 @@ var init_context3 = __esm({
5141
5141
  "src/otel/context.ts"() {
5142
5142
  "use strict";
5143
5143
  init_logger();
5144
- init_util();
5145
5144
  OTEL_NOT_INSTALLED_MESSAGE = "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base";
5146
5145
  otelTrace = null;
5147
5146
  otelContext = null;
@@ -5204,6 +5203,10 @@ var init_context3 = __esm({
5204
5203
  const currentContext = otelContext.active();
5205
5204
  let newContext = otelTrace.setSpan(currentContext, wrappedContext);
5206
5205
  newContext = newContext.setValue("braintrust_span", span);
5206
+ const parentValue = span._getOtelParent();
5207
+ if (parentValue) {
5208
+ newContext = newContext.setValue("braintrust.parent", parentValue);
5209
+ }
5207
5210
  return otelContext.with(newContext, callback);
5208
5211
  }
5209
5212
  } catch (error2) {
@@ -5219,34 +5222,6 @@ var init_context3 = __esm({
5219
5222
  }
5220
5223
  return void 0;
5221
5224
  }
5222
- _getOtelParent(span) {
5223
- if (!span.parentObjectType || !span.parentObjectId) {
5224
- return void 0;
5225
- }
5226
- try {
5227
- const parentType = span.parentObjectType;
5228
- const parentId = span.parentObjectId;
5229
- if (parentType === 2 /* PROJECT_LOGS */) {
5230
- const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
5231
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
5232
- parentId.get()
5233
- ) : parentId;
5234
- if (typeof id === "string") {
5235
- return `project_id:${id}`;
5236
- }
5237
- } else if (parentType === 1 /* EXPERIMENT */) {
5238
- const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
5239
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
5240
- parentId.get()
5241
- ) : parentId;
5242
- if (typeof id === "string") {
5243
- return `experiment_id:${id}`;
5244
- }
5245
- }
5246
- } catch (e9) {
5247
- }
5248
- return void 0;
5249
- }
5250
5225
  };
5251
5226
  }
5252
5227
  });
@@ -5282,7 +5257,7 @@ function getContextManager() {
5282
5257
  try {
5283
5258
  const { OtelContextManager: OtelContextManager2 } = (init_context3(), __toCommonJS(context_exports));
5284
5259
  return new OtelContextManager2();
5285
- } catch (e10) {
5260
+ } catch (e9) {
5286
5261
  console.warn(
5287
5262
  "OTEL not available, falling back to Braintrust-only context manager"
5288
5263
  );
@@ -6521,6 +6496,9 @@ var init_logger = __esm({
6521
6496
  state() {
6522
6497
  return _internalGetGlobalState();
6523
6498
  }
6499
+ _getOtelParent() {
6500
+ return void 0;
6501
+ }
6524
6502
  // Custom inspect for Node.js console.log
6525
6503
  [Symbol.for("nodejs.util.inspect.custom")]() {
6526
6504
  return `NoopSpan {
@@ -7248,6 +7226,9 @@ with a Blob/ArrayBuffer, or run the program on Node.js.`
7248
7226
  get id() {
7249
7227
  return (async () => (await this.project).id)();
7250
7228
  }
7229
+ get loggingState() {
7230
+ return this.state;
7231
+ }
7251
7232
  parentObjectType() {
7252
7233
  return 2 /* PROJECT_LOGS */;
7253
7234
  }
@@ -7908,6 +7889,18 @@ Error: ${errorText}`;
7908
7889
  return (await this.lazyMetadata.get()).experiment.id;
7909
7890
  })();
7910
7891
  }
7892
+ get loggingState() {
7893
+ return this.state;
7894
+ }
7895
+ /**
7896
+ * Wait for the experiment ID to be resolved. This is useful for ensuring the ID
7897
+ * is available synchronously in child spans (for OTEL parent attributes).
7898
+ * @internal
7899
+ */
7900
+ async _waitForId() {
7901
+ await this.lazyId.get().catch(() => {
7902
+ });
7903
+ }
7911
7904
  get name() {
7912
7905
  return (async () => {
7913
7906
  return (await this.lazyMetadata.get()).experiment.name;
@@ -8164,6 +8157,9 @@ View complete results in Braintrust or run experiment.summarize() again.`
8164
8157
  return (await this.lazyMetadata.get()).experiment.name;
8165
8158
  })();
8166
8159
  }
8160
+ get loggingState() {
8161
+ return this.state;
8162
+ }
8167
8163
  async getState() {
8168
8164
  await this.lazyMetadata.get();
8169
8165
  return this.state;
@@ -8460,6 +8456,42 @@ View complete results in Braintrust or run experiment.summarize() again.`
8460
8456
  state() {
8461
8457
  return this._state;
8462
8458
  }
8459
+ /**
8460
+ * Internal method to get the OTEL parent string for this span.
8461
+ * This is used by OtelContextManager to set the braintrust.parent attribute.
8462
+ * @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
8463
+ */
8464
+ _getOtelParent() {
8465
+ if (!this.parentObjectType) {
8466
+ return void 0;
8467
+ }
8468
+ try {
8469
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
8470
+ const syncResult = this.parentObjectId.getSync();
8471
+ const id = syncResult.value;
8472
+ const args = this.parentComputeObjectMetadataArgs;
8473
+ if (id) {
8474
+ return `project_id:${id}`;
8475
+ }
8476
+ const projectName = _optionalChain([args, 'optionalAccess', _94 => _94.project_name]);
8477
+ if (projectName) {
8478
+ return `project_name:${projectName}`;
8479
+ }
8480
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
8481
+ const syncResult = this.parentObjectId.getSync();
8482
+ const id = syncResult.value;
8483
+ if (!syncResult.resolved) {
8484
+ this.parentObjectId.get().catch(() => {
8485
+ });
8486
+ }
8487
+ if (id) {
8488
+ return `experiment_id:${id}`;
8489
+ }
8490
+ }
8491
+ } catch (e) {
8492
+ }
8493
+ return void 0;
8494
+ }
8463
8495
  // Custom inspect for Node.js console.log
8464
8496
  [Symbol.for("nodejs.util.inspect.custom")]() {
8465
8497
  return `SpanImpl {
@@ -8516,6 +8548,9 @@ View complete results in Braintrust or run experiment.summarize() again.`
8516
8548
  return (await this.lazyMetadata.get()).project;
8517
8549
  })();
8518
8550
  }
8551
+ get loggingState() {
8552
+ return this.state;
8553
+ }
8519
8554
  async getState() {
8520
8555
  await this.lazyMetadata.get();
8521
8556
  return this.state;
@@ -8738,13 +8773,13 @@ View complete results in Braintrust or run experiment.summarize() again.`
8738
8773
  return "slug" in this.metadata ? this.metadata.slug : this.metadata.id;
8739
8774
  }
8740
8775
  get prompt() {
8741
- return _optionalChain([this, 'access', _94 => _94.getParsedPromptData, 'call', _95 => _95(), 'optionalAccess', _96 => _96.prompt]);
8776
+ return _optionalChain([this, 'access', _95 => _95.getParsedPromptData, 'call', _96 => _96(), 'optionalAccess', _97 => _97.prompt]);
8742
8777
  }
8743
8778
  get version() {
8744
8779
  return this.metadata[TRANSACTION_ID_FIELD];
8745
8780
  }
8746
8781
  get options() {
8747
- return _optionalChain([this, 'access', _97 => _97.getParsedPromptData, 'call', _98 => _98(), 'optionalAccess', _99 => _99.options]) || {};
8782
+ return _optionalChain([this, 'access', _98 => _98.getParsedPromptData, 'call', _99 => _99(), 'optionalAccess', _100 => _100.options]) || {};
8748
8783
  }
8749
8784
  get promptData() {
8750
8785
  return this.getParsedPromptData();
@@ -8895,7 +8930,7 @@ View complete results in Braintrust or run experiment.summarize() again.`
8895
8930
  return {
8896
8931
  type: "chat",
8897
8932
  messages,
8898
- ..._optionalChain([prompt, 'access', _100 => _100.tools, 'optionalAccess', _101 => _101.trim, 'call', _102 => _102()]) ? {
8933
+ ..._optionalChain([prompt, 'access', _101 => _101.tools, 'optionalAccess', _102 => _102.trim, 'call', _103 => _103()]) ? {
8899
8934
  tools: render(prompt.tools)
8900
8935
  } : void 0
8901
8936
  };
@@ -8976,7 +9011,7 @@ async function getBaseBranch(remote = void 0) {
8976
9011
  if (git === null) {
8977
9012
  throw new Error("Not in a git repo");
8978
9013
  }
8979
- const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _103 => _103[0], 'optionalAccess', async _104 => _104.name])));
9014
+ const remoteName = await _asyncNullishCoalesce(remote, async () => ( await _asyncOptionalChain([(await git.getRemotes()), 'access', async _104 => _104[0], 'optionalAccess', async _105 => _105.name])));
8980
9015
  if (!remoteName) {
8981
9016
  throw new Error("No remote found");
8982
9017
  }
@@ -8998,7 +9033,7 @@ async function getBaseBranch(remote = void 0) {
8998
9033
  throw new Error(`Could not find HEAD branch in remote ${remoteName}`);
8999
9034
  }
9000
9035
  branch = match[1];
9001
- } catch (e11) {
9036
+ } catch (e10) {
9002
9037
  branch = "main";
9003
9038
  }
9004
9039
  }
@@ -9069,7 +9104,7 @@ async function getRepoInfo(settings) {
9069
9104
  return repo;
9070
9105
  }
9071
9106
  let sanitized = {};
9072
- _optionalChain([settings, 'access', _105 => _105.fields, 'optionalAccess', _106 => _106.forEach, 'call', _107 => _107((field) => {
9107
+ _optionalChain([settings, 'access', _106 => _106.fields, 'optionalAccess', _107 => _107.forEach, 'call', _108 => _108((field) => {
9073
9108
  sanitized = { ...sanitized, [field]: repo[field] };
9074
9109
  })]);
9075
9110
  return sanitized;
@@ -9156,9 +9191,9 @@ function getCallerLocation() {
9156
9191
  const entries = getStackTrace();
9157
9192
  for (const frame of entries) {
9158
9193
  if (thisDir === void 0) {
9159
- thisDir = _optionalChain([isomorph_default, 'access', _108 => _108.pathDirname, 'optionalCall', _109 => _109(frame.fileName)]);
9194
+ thisDir = _optionalChain([isomorph_default, 'access', _109 => _109.pathDirname, 'optionalCall', _110 => _110(frame.fileName)]);
9160
9195
  }
9161
- if (_optionalChain([isomorph_default, 'access', _110 => _110.pathDirname, 'optionalCall', _111 => _111(frame.fileName)]) !== thisDir) {
9196
+ if (_optionalChain([isomorph_default, 'access', _111 => _111.pathDirname, 'optionalCall', _112 => _112(frame.fileName)]) !== thisDir) {
9162
9197
  return {
9163
9198
  caller_functionname: frame.functionName,
9164
9199
  caller_filename: frame.fileName,
@@ -10791,6 +10826,9 @@ async function Eval(name, evaluator, reporterOrOpts) {
10791
10826
  repoInfo: evaluator.repoInfo,
10792
10827
  dataset: Dataset2.isDataset(data) ? data : void 0
10793
10828
  });
10829
+ if (experiment && typeof process !== "undefined" && _optionalChain([process, 'access', _113 => _113.env, 'optionalAccess', _114 => _114.BRAINTRUST_OTEL_COMPAT, 'optionalAccess', _115 => _115.toLowerCase, 'call', _116 => _116()]) === "true") {
10830
+ await experiment._waitForId();
10831
+ }
10794
10832
  if (experiment && options.onStart) {
10795
10833
  const summary = await experiment.summarize({ summarizeScores: false });
10796
10834
  options.onStart(summary);
@@ -10973,10 +11011,10 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
10973
11011
  span,
10974
11012
  parameters: _nullishCoalesce(parameters, () => ( {})),
10975
11013
  reportProgress: (event) => {
10976
- _optionalChain([stream, 'optionalCall', _112 => _112({
11014
+ _optionalChain([stream, 'optionalCall', _117 => _117({
10977
11015
  ...event,
10978
11016
  id: rootSpan.id,
10979
- origin: _optionalChain([baseEvent, 'access', _113 => _113.event, 'optionalAccess', _114 => _114.origin]),
11017
+ origin: _optionalChain([baseEvent, 'access', _118 => _118.event, 'optionalAccess', _119 => _119.origin]),
10980
11018
  name: evaluator.evalName,
10981
11019
  object_type: "task"
10982
11020
  })]);
@@ -11126,7 +11164,7 @@ async function runEvaluatorInternal(experiment, evaluator, progressReporter, fil
11126
11164
  ...scores
11127
11165
  },
11128
11166
  error: error2,
11129
- origin: _optionalChain([baseEvent, 'access', _115 => _115.event, 'optionalAccess', _116 => _116.origin])
11167
+ origin: _optionalChain([baseEvent, 'access', _120 => _120.event, 'optionalAccess', _121 => _121.origin])
11130
11168
  });
11131
11169
  };
11132
11170
  if (!experiment) {
@@ -11351,12 +11389,12 @@ async function cachedLogin(options) {
11351
11389
  }
11352
11390
  function makeCheckAuthorized(allowedOrgName) {
11353
11391
  return async (req, _res, next) => {
11354
- if (!_optionalChain([req, 'access', _117 => _117.ctx, 'optionalAccess', _118 => _118.token])) {
11392
+ if (!_optionalChain([req, 'access', _122 => _122.ctx, 'optionalAccess', _123 => _123.token])) {
11355
11393
  return next(_httperrors2.default.call(void 0, 401, "Unauthorized"));
11356
11394
  }
11357
11395
  try {
11358
11396
  const state = await cachedLogin({
11359
- apiKey: _optionalChain([req, 'access', _119 => _119.ctx, 'optionalAccess', _120 => _120.token]),
11397
+ apiKey: _optionalChain([req, 'access', _124 => _124.ctx, 'optionalAccess', _125 => _125.token]),
11360
11398
  orgName: allowedOrgName
11361
11399
  });
11362
11400
  req.ctx.state = state;
@@ -11567,7 +11605,7 @@ function runDevServer(evaluators, opts) {
11567
11605
  scores,
11568
11606
  stream
11569
11607
  } = evalBodySchema.parse(req.body);
11570
- if (!_optionalChain([req, 'access', _121 => _121.ctx, 'optionalAccess', _122 => _122.state])) {
11608
+ if (!_optionalChain([req, 'access', _126 => _126.ctx, 'optionalAccess', _127 => _127.state])) {
11571
11609
  res.status(500).json({ error: "Braintrust state not initialized in request" });
11572
11610
  return;
11573
11611
  }
@@ -11624,7 +11662,7 @@ function runDevServer(evaluators, opts) {
11624
11662
  ...evaluator,
11625
11663
  data: evalData.data,
11626
11664
  scores: evaluator.scores.concat(
11627
- _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _123 => _123.map, 'call', _124 => _124(
11665
+ _nullishCoalesce(_optionalChain([scores, 'optionalAccess', _128 => _128.map, 'call', _129 => _129(
11628
11666
  (score) => makeScorer(state, score.name, score.function_id)
11629
11667
  )]), () => ( []))
11630
11668
  ),
@@ -5141,7 +5141,6 @@ var init_context3 = __esm({
5141
5141
  "src/otel/context.ts"() {
5142
5142
  "use strict";
5143
5143
  init_logger();
5144
- init_util();
5145
5144
  OTEL_NOT_INSTALLED_MESSAGE = "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base";
5146
5145
  otelTrace = null;
5147
5146
  otelContext = null;
@@ -5204,6 +5203,10 @@ var init_context3 = __esm({
5204
5203
  const currentContext = otelContext.active();
5205
5204
  let newContext = otelTrace.setSpan(currentContext, wrappedContext);
5206
5205
  newContext = newContext.setValue("braintrust_span", span);
5206
+ const parentValue = span._getOtelParent();
5207
+ if (parentValue) {
5208
+ newContext = newContext.setValue("braintrust.parent", parentValue);
5209
+ }
5207
5210
  return otelContext.with(newContext, callback);
5208
5211
  }
5209
5212
  } catch (error2) {
@@ -5219,34 +5222,6 @@ var init_context3 = __esm({
5219
5222
  }
5220
5223
  return void 0;
5221
5224
  }
5222
- _getOtelParent(span) {
5223
- if (!span.parentObjectType || !span.parentObjectId) {
5224
- return void 0;
5225
- }
5226
- try {
5227
- const parentType = span.parentObjectType;
5228
- const parentId = span.parentObjectId;
5229
- if (parentType === 2 /* PROJECT_LOGS */) {
5230
- const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
5231
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
5232
- parentId.get()
5233
- ) : parentId;
5234
- if (typeof id === "string") {
5235
- return `project_id:${id}`;
5236
- }
5237
- } else if (parentType === 1 /* EXPERIMENT */) {
5238
- const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
5239
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
5240
- parentId.get()
5241
- ) : parentId;
5242
- if (typeof id === "string") {
5243
- return `experiment_id:${id}`;
5244
- }
5245
- }
5246
- } catch {
5247
- }
5248
- return void 0;
5249
- }
5250
5225
  };
5251
5226
  }
5252
5227
  });
@@ -6521,6 +6496,9 @@ var init_logger = __esm({
6521
6496
  state() {
6522
6497
  return _internalGetGlobalState();
6523
6498
  }
6499
+ _getOtelParent() {
6500
+ return void 0;
6501
+ }
6524
6502
  // Custom inspect for Node.js console.log
6525
6503
  [Symbol.for("nodejs.util.inspect.custom")]() {
6526
6504
  return `NoopSpan {
@@ -7248,6 +7226,9 @@ with a Blob/ArrayBuffer, or run the program on Node.js.`
7248
7226
  get id() {
7249
7227
  return (async () => (await this.project).id)();
7250
7228
  }
7229
+ get loggingState() {
7230
+ return this.state;
7231
+ }
7251
7232
  parentObjectType() {
7252
7233
  return 2 /* PROJECT_LOGS */;
7253
7234
  }
@@ -7908,6 +7889,18 @@ Error: ${errorText}`;
7908
7889
  return (await this.lazyMetadata.get()).experiment.id;
7909
7890
  })();
7910
7891
  }
7892
+ get loggingState() {
7893
+ return this.state;
7894
+ }
7895
+ /**
7896
+ * Wait for the experiment ID to be resolved. This is useful for ensuring the ID
7897
+ * is available synchronously in child spans (for OTEL parent attributes).
7898
+ * @internal
7899
+ */
7900
+ async _waitForId() {
7901
+ await this.lazyId.get().catch(() => {
7902
+ });
7903
+ }
7911
7904
  get name() {
7912
7905
  return (async () => {
7913
7906
  return (await this.lazyMetadata.get()).experiment.name;
@@ -8164,6 +8157,9 @@ View complete results in Braintrust or run experiment.summarize() again.`
8164
8157
  return (await this.lazyMetadata.get()).experiment.name;
8165
8158
  })();
8166
8159
  }
8160
+ get loggingState() {
8161
+ return this.state;
8162
+ }
8167
8163
  async getState() {
8168
8164
  await this.lazyMetadata.get();
8169
8165
  return this.state;
@@ -8460,6 +8456,42 @@ View complete results in Braintrust or run experiment.summarize() again.`
8460
8456
  state() {
8461
8457
  return this._state;
8462
8458
  }
8459
+ /**
8460
+ * Internal method to get the OTEL parent string for this span.
8461
+ * This is used by OtelContextManager to set the braintrust.parent attribute.
8462
+ * @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
8463
+ */
8464
+ _getOtelParent() {
8465
+ if (!this.parentObjectType) {
8466
+ return void 0;
8467
+ }
8468
+ try {
8469
+ if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
8470
+ const syncResult = this.parentObjectId.getSync();
8471
+ const id = syncResult.value;
8472
+ const args = this.parentComputeObjectMetadataArgs;
8473
+ if (id) {
8474
+ return `project_id:${id}`;
8475
+ }
8476
+ const projectName = args?.project_name;
8477
+ if (projectName) {
8478
+ return `project_name:${projectName}`;
8479
+ }
8480
+ } else if (this.parentObjectType === 1 /* EXPERIMENT */) {
8481
+ const syncResult = this.parentObjectId.getSync();
8482
+ const id = syncResult.value;
8483
+ if (!syncResult.resolved) {
8484
+ this.parentObjectId.get().catch(() => {
8485
+ });
8486
+ }
8487
+ if (id) {
8488
+ return `experiment_id:${id}`;
8489
+ }
8490
+ }
8491
+ } catch (e) {
8492
+ }
8493
+ return void 0;
8494
+ }
8463
8495
  // Custom inspect for Node.js console.log
8464
8496
  [Symbol.for("nodejs.util.inspect.custom")]() {
8465
8497
  return `SpanImpl {
@@ -8516,6 +8548,9 @@ View complete results in Braintrust or run experiment.summarize() again.`
8516
8548
  return (await this.lazyMetadata.get()).project;
8517
8549
  })();
8518
8550
  }
8551
+ get loggingState() {
8552
+ return this.state;
8553
+ }
8519
8554
  async getState() {
8520
8555
  await this.lazyMetadata.get();
8521
8556
  return this.state;
@@ -10791,6 +10826,9 @@ async function Eval(name, evaluator, reporterOrOpts) {
10791
10826
  repoInfo: evaluator.repoInfo,
10792
10827
  dataset: Dataset2.isDataset(data) ? data : void 0
10793
10828
  });
10829
+ if (experiment && typeof process !== "undefined" && process.env?.BRAINTRUST_OTEL_COMPAT?.toLowerCase() === "true") {
10830
+ await experiment._waitForId();
10831
+ }
10794
10832
  if (experiment && options.onStart) {
10795
10833
  const summary = await experiment.summarize({ summarizeScores: false });
10796
10834
  options.onStart(summary);