braintrust 0.4.1 → 0.4.2
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.
- package/dev/dist/index.d.mts +13 -0
- package/dev/dist/index.d.ts +13 -0
- package/dev/dist/index.js +71 -45
- package/dev/dist/index.mjs +55 -29
- package/dist/browser.d.mts +19 -0
- package/dist/browser.d.ts +19 -0
- package/dist/browser.js +71 -48
- package/dist/browser.mjs +52 -29
- package/dist/cli.js +63 -37
- package/dist/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +272 -179
- package/dist/index.mjs +162 -69
- package/package.json +1 -1
package/dist/browser.js
CHANGED
|
@@ -5124,7 +5124,6 @@ var init_context3 = __esm({
|
|
|
5124
5124
|
"src/otel/context.ts"() {
|
|
5125
5125
|
"use strict";
|
|
5126
5126
|
init_logger();
|
|
5127
|
-
init_util();
|
|
5128
5127
|
OTEL_NOT_INSTALLED_MESSAGE = "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base";
|
|
5129
5128
|
otelTrace = null;
|
|
5130
5129
|
otelContext = null;
|
|
@@ -5187,6 +5186,10 @@ var init_context3 = __esm({
|
|
|
5187
5186
|
const currentContext = otelContext.active();
|
|
5188
5187
|
let newContext = otelTrace.setSpan(currentContext, wrappedContext);
|
|
5189
5188
|
newContext = newContext.setValue("braintrust_span", span);
|
|
5189
|
+
const parentValue = span._getOtelParent();
|
|
5190
|
+
if (parentValue) {
|
|
5191
|
+
newContext = newContext.setValue("braintrust.parent", parentValue);
|
|
5192
|
+
}
|
|
5190
5193
|
return otelContext.with(newContext, callback);
|
|
5191
5194
|
}
|
|
5192
5195
|
} catch (error) {
|
|
@@ -5202,34 +5205,6 @@ var init_context3 = __esm({
|
|
|
5202
5205
|
}
|
|
5203
5206
|
return void 0;
|
|
5204
5207
|
}
|
|
5205
|
-
_getOtelParent(span) {
|
|
5206
|
-
if (!span.parentObjectType || !span.parentObjectId) {
|
|
5207
|
-
return void 0;
|
|
5208
|
-
}
|
|
5209
|
-
try {
|
|
5210
|
-
const parentType = span.parentObjectType;
|
|
5211
|
-
const parentId = span.parentObjectId;
|
|
5212
|
-
if (parentType === 2 /* PROJECT_LOGS */) {
|
|
5213
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
5214
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
5215
|
-
parentId.get()
|
|
5216
|
-
) : parentId;
|
|
5217
|
-
if (typeof id === "string") {
|
|
5218
|
-
return `project_id:${id}`;
|
|
5219
|
-
}
|
|
5220
|
-
} else if (parentType === 1 /* EXPERIMENT */) {
|
|
5221
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
5222
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
5223
|
-
parentId.get()
|
|
5224
|
-
) : parentId;
|
|
5225
|
-
if (typeof id === "string") {
|
|
5226
|
-
return `experiment_id:${id}`;
|
|
5227
|
-
}
|
|
5228
|
-
}
|
|
5229
|
-
} catch (e9) {
|
|
5230
|
-
}
|
|
5231
|
-
return void 0;
|
|
5232
|
-
}
|
|
5233
5208
|
};
|
|
5234
5209
|
}
|
|
5235
5210
|
});
|
|
@@ -5265,7 +5240,7 @@ function getContextManager() {
|
|
|
5265
5240
|
try {
|
|
5266
5241
|
const { OtelContextManager: OtelContextManager2 } = (init_context3(), __toCommonJS(context_exports));
|
|
5267
5242
|
return new OtelContextManager2();
|
|
5268
|
-
} catch (
|
|
5243
|
+
} catch (e9) {
|
|
5269
5244
|
console.warn(
|
|
5270
5245
|
"OTEL not available, falling back to Braintrust-only context manager"
|
|
5271
5246
|
);
|
|
@@ -7040,6 +7015,9 @@ var init_logger = __esm({
|
|
|
7040
7015
|
state() {
|
|
7041
7016
|
return _internalGetGlobalState();
|
|
7042
7017
|
}
|
|
7018
|
+
_getOtelParent() {
|
|
7019
|
+
return void 0;
|
|
7020
|
+
}
|
|
7043
7021
|
// Custom inspect for Node.js console.log
|
|
7044
7022
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
7045
7023
|
return `NoopSpan {
|
|
@@ -8547,6 +8525,15 @@ Error: ${errorText}`;
|
|
|
8547
8525
|
return (await this.lazyMetadata.get()).experiment.id;
|
|
8548
8526
|
})();
|
|
8549
8527
|
}
|
|
8528
|
+
/**
|
|
8529
|
+
* Wait for the experiment ID to be resolved. This is useful for ensuring the ID
|
|
8530
|
+
* is available synchronously in child spans (for OTEL parent attributes).
|
|
8531
|
+
* @internal
|
|
8532
|
+
*/
|
|
8533
|
+
async _waitForId() {
|
|
8534
|
+
await this.lazyId.get().catch(() => {
|
|
8535
|
+
});
|
|
8536
|
+
}
|
|
8550
8537
|
get name() {
|
|
8551
8538
|
return (async () => {
|
|
8552
8539
|
return (await this.lazyMetadata.get()).experiment.name;
|
|
@@ -9099,6 +9086,42 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
9099
9086
|
state() {
|
|
9100
9087
|
return this._state;
|
|
9101
9088
|
}
|
|
9089
|
+
/**
|
|
9090
|
+
* Internal method to get the OTEL parent string for this span.
|
|
9091
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
9092
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
9093
|
+
*/
|
|
9094
|
+
_getOtelParent() {
|
|
9095
|
+
if (!this.parentObjectType) {
|
|
9096
|
+
return void 0;
|
|
9097
|
+
}
|
|
9098
|
+
try {
|
|
9099
|
+
if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
|
|
9100
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9101
|
+
const id = syncResult.value;
|
|
9102
|
+
const args = this.parentComputeObjectMetadataArgs;
|
|
9103
|
+
if (id) {
|
|
9104
|
+
return `project_id:${id}`;
|
|
9105
|
+
}
|
|
9106
|
+
const projectName = _optionalChain([args, 'optionalAccess', _106 => _106.project_name]);
|
|
9107
|
+
if (projectName) {
|
|
9108
|
+
return `project_name:${projectName}`;
|
|
9109
|
+
}
|
|
9110
|
+
} else if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
9111
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9112
|
+
const id = syncResult.value;
|
|
9113
|
+
if (!syncResult.resolved) {
|
|
9114
|
+
this.parentObjectId.get().catch(() => {
|
|
9115
|
+
});
|
|
9116
|
+
}
|
|
9117
|
+
if (id) {
|
|
9118
|
+
return `experiment_id:${id}`;
|
|
9119
|
+
}
|
|
9120
|
+
}
|
|
9121
|
+
} catch (e) {
|
|
9122
|
+
}
|
|
9123
|
+
return void 0;
|
|
9124
|
+
}
|
|
9102
9125
|
// Custom inspect for Node.js console.log
|
|
9103
9126
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
9104
9127
|
return `SpanImpl {
|
|
@@ -9377,13 +9400,13 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
9377
9400
|
return "slug" in this.metadata ? this.metadata.slug : this.metadata.id;
|
|
9378
9401
|
}
|
|
9379
9402
|
get prompt() {
|
|
9380
|
-
return _optionalChain([this, 'access',
|
|
9403
|
+
return _optionalChain([this, 'access', _107 => _107.getParsedPromptData, 'call', _108 => _108(), 'optionalAccess', _109 => _109.prompt]);
|
|
9381
9404
|
}
|
|
9382
9405
|
get version() {
|
|
9383
9406
|
return this.metadata[TRANSACTION_ID_FIELD];
|
|
9384
9407
|
}
|
|
9385
9408
|
get options() {
|
|
9386
|
-
return _optionalChain([this, 'access',
|
|
9409
|
+
return _optionalChain([this, 'access', _110 => _110.getParsedPromptData, 'call', _111 => _111(), 'optionalAccess', _112 => _112.options]) || {};
|
|
9387
9410
|
}
|
|
9388
9411
|
get promptData() {
|
|
9389
9412
|
return this.getParsedPromptData();
|
|
@@ -9534,7 +9557,7 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
9534
9557
|
return {
|
|
9535
9558
|
type: "chat",
|
|
9536
9559
|
messages,
|
|
9537
|
-
..._optionalChain([prompt, 'access',
|
|
9560
|
+
..._optionalChain([prompt, 'access', _113 => _113.tools, 'optionalAccess', _114 => _114.trim, 'call', _115 => _115()]) ? {
|
|
9538
9561
|
tools: render(prompt.tools)
|
|
9539
9562
|
} : void 0
|
|
9540
9563
|
};
|
|
@@ -9609,7 +9632,7 @@ function configureBrowser() {
|
|
|
9609
9632
|
if (typeof AsyncLocalStorage !== "undefined") {
|
|
9610
9633
|
isomorph_default.newAsyncLocalStorage = () => new AsyncLocalStorage();
|
|
9611
9634
|
}
|
|
9612
|
-
} catch (
|
|
9635
|
+
} catch (e10) {
|
|
9613
9636
|
}
|
|
9614
9637
|
isomorph_default.getEnv = (name) => {
|
|
9615
9638
|
if (typeof process === "undefined" || typeof process.env === "undefined") {
|
|
@@ -9862,7 +9885,7 @@ function parseSpanFromResponseCreateParams(params) {
|
|
|
9862
9885
|
}
|
|
9863
9886
|
function parseEventFromResponseCreateResult(result) {
|
|
9864
9887
|
const data = {};
|
|
9865
|
-
if (_optionalChain([result, 'optionalAccess',
|
|
9888
|
+
if (_optionalChain([result, 'optionalAccess', _116 => _116.output]) !== void 0) {
|
|
9866
9889
|
data.output = processImagesInOutput(result.output);
|
|
9867
9890
|
}
|
|
9868
9891
|
if (result) {
|
|
@@ -9871,7 +9894,7 @@ function parseEventFromResponseCreateResult(result) {
|
|
|
9871
9894
|
data.metadata = metadata;
|
|
9872
9895
|
}
|
|
9873
9896
|
}
|
|
9874
|
-
data.metrics = parseMetricsFromUsage(_optionalChain([result, 'optionalAccess',
|
|
9897
|
+
data.metrics = parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _117 => _117.usage]));
|
|
9875
9898
|
return data;
|
|
9876
9899
|
}
|
|
9877
9900
|
function processImagesInOutput(output) {
|
|
@@ -9925,7 +9948,7 @@ function parseSpanFromResponseParseParams(params) {
|
|
|
9925
9948
|
}
|
|
9926
9949
|
function parseEventFromResponseParseResult(result) {
|
|
9927
9950
|
const data = {};
|
|
9928
|
-
if (_optionalChain([result, 'optionalAccess',
|
|
9951
|
+
if (_optionalChain([result, 'optionalAccess', _118 => _118.output]) !== void 0) {
|
|
9929
9952
|
data.output = processImagesInOutput(result.output);
|
|
9930
9953
|
}
|
|
9931
9954
|
if (result) {
|
|
@@ -9934,7 +9957,7 @@ function parseEventFromResponseParseResult(result) {
|
|
|
9934
9957
|
data.metadata = metadata;
|
|
9935
9958
|
}
|
|
9936
9959
|
}
|
|
9937
|
-
data.metrics = parseMetricsFromUsage(_optionalChain([result, 'optionalAccess',
|
|
9960
|
+
data.metrics = parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _119 => _119.usage]));
|
|
9938
9961
|
return data;
|
|
9939
9962
|
}
|
|
9940
9963
|
function traceResponseCreateStream(stream, timedSpan) {
|
|
@@ -9951,7 +9974,7 @@ function traceResponseCreateStream(stream, timedSpan) {
|
|
|
9951
9974
|
return result;
|
|
9952
9975
|
}
|
|
9953
9976
|
const item = result.value;
|
|
9954
|
-
if (!item || !_optionalChain([item, 'optionalAccess',
|
|
9977
|
+
if (!item || !_optionalChain([item, 'optionalAccess', _120 => _120.type]) || !_optionalChain([item, 'optionalAccess', _121 => _121.response])) {
|
|
9955
9978
|
return result;
|
|
9956
9979
|
}
|
|
9957
9980
|
const event = parseLogFromItem(item);
|
|
@@ -9962,14 +9985,14 @@ function traceResponseCreateStream(stream, timedSpan) {
|
|
|
9962
9985
|
};
|
|
9963
9986
|
}
|
|
9964
9987
|
function parseLogFromItem(item) {
|
|
9965
|
-
if (!item || !_optionalChain([item, 'optionalAccess',
|
|
9988
|
+
if (!item || !_optionalChain([item, 'optionalAccess', _122 => _122.type]) || !_optionalChain([item, 'optionalAccess', _123 => _123.response])) {
|
|
9966
9989
|
return {};
|
|
9967
9990
|
}
|
|
9968
9991
|
const response = item.response;
|
|
9969
9992
|
switch (item.type) {
|
|
9970
9993
|
case "response.completed":
|
|
9971
9994
|
const data = {};
|
|
9972
|
-
if (_optionalChain([response, 'optionalAccess',
|
|
9995
|
+
if (_optionalChain([response, 'optionalAccess', _124 => _124.output]) !== void 0) {
|
|
9973
9996
|
data.output = processImagesInOutput(response.output);
|
|
9974
9997
|
}
|
|
9975
9998
|
if (response) {
|
|
@@ -9978,7 +10001,7 @@ function parseLogFromItem(item) {
|
|
|
9978
10001
|
data.metadata = metadata;
|
|
9979
10002
|
}
|
|
9980
10003
|
}
|
|
9981
|
-
data.metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess',
|
|
10004
|
+
data.metrics = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _125 => _125.usage]));
|
|
9982
10005
|
return data;
|
|
9983
10006
|
default:
|
|
9984
10007
|
return {};
|
|
@@ -10162,8 +10185,8 @@ function wrapOpenAIv4(openai) {
|
|
|
10162
10185
|
const embeddingProxy = createEndpointProxy(openai.embeddings, wrapEmbeddings);
|
|
10163
10186
|
const moderationProxy = createEndpointProxy(openai.moderations, wrapModerations);
|
|
10164
10187
|
let betaProxy;
|
|
10165
|
-
if (_optionalChain([openai, 'access',
|
|
10166
|
-
const betaChatCompletionProxy = new Proxy(_optionalChain([openai, 'optionalAccess',
|
|
10188
|
+
if (_optionalChain([openai, 'access', _126 => _126.beta, 'optionalAccess', _127 => _127.chat, 'optionalAccess', _128 => _128.completions, 'optionalAccess', _129 => _129.stream])) {
|
|
10189
|
+
const betaChatCompletionProxy = new Proxy(_optionalChain([openai, 'optionalAccess', _130 => _130.beta, 'optionalAccess', _131 => _131.chat, 'access', _132 => _132.completions]), {
|
|
10167
10190
|
get(target, name, receiver) {
|
|
10168
10191
|
const baseVal = Reflect.get(target, name, receiver);
|
|
10169
10192
|
if (name === "parse") {
|
|
@@ -10211,7 +10234,7 @@ function wrapOpenAIv4(openai) {
|
|
|
10211
10234
|
});
|
|
10212
10235
|
}
|
|
10213
10236
|
function logCompletionResponse(startTime, response, span) {
|
|
10214
|
-
const metrics2 = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess',
|
|
10237
|
+
const metrics2 = parseMetricsFromUsage(_optionalChain([response, 'optionalAccess', _133 => _133.usage]));
|
|
10215
10238
|
metrics2.time_to_first_token = getCurrentUnixTimestamp() - startTime;
|
|
10216
10239
|
span.log({
|
|
10217
10240
|
output: response.choices,
|
|
@@ -10441,7 +10464,7 @@ function parseChatCompletionParams(params) {
|
|
|
10441
10464
|
function processEmbeddingResponse(result, span) {
|
|
10442
10465
|
span.log({
|
|
10443
10466
|
output: { embedding_length: result.data[0].embedding.length },
|
|
10444
|
-
metrics: parseMetricsFromUsage(_optionalChain([result, 'optionalAccess',
|
|
10467
|
+
metrics: parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _134 => _134.usage]))
|
|
10445
10468
|
});
|
|
10446
10469
|
}
|
|
10447
10470
|
function processModerationResponse(result, span) {
|
|
@@ -10471,10 +10494,10 @@ function postprocessStreamingResults(allResults) {
|
|
|
10471
10494
|
if (result.usage) {
|
|
10472
10495
|
metrics2 = {
|
|
10473
10496
|
...metrics2,
|
|
10474
|
-
...parseMetricsFromUsage(_optionalChain([result, 'optionalAccess',
|
|
10497
|
+
...parseMetricsFromUsage(_optionalChain([result, 'optionalAccess', _135 => _135.usage]))
|
|
10475
10498
|
};
|
|
10476
10499
|
}
|
|
10477
|
-
const delta = _optionalChain([result, 'access',
|
|
10500
|
+
const delta = _optionalChain([result, 'access', _136 => _136.choices, 'optionalAccess', _137 => _137[0], 'optionalAccess', _138 => _138.delta]);
|
|
10478
10501
|
if (!delta) {
|
|
10479
10502
|
continue;
|
|
10480
10503
|
}
|
package/dist/browser.mjs
CHANGED
|
@@ -5124,7 +5124,6 @@ var init_context3 = __esm({
|
|
|
5124
5124
|
"src/otel/context.ts"() {
|
|
5125
5125
|
"use strict";
|
|
5126
5126
|
init_logger();
|
|
5127
|
-
init_util();
|
|
5128
5127
|
OTEL_NOT_INSTALLED_MESSAGE = "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base";
|
|
5129
5128
|
otelTrace = null;
|
|
5130
5129
|
otelContext = null;
|
|
@@ -5187,6 +5186,10 @@ var init_context3 = __esm({
|
|
|
5187
5186
|
const currentContext = otelContext.active();
|
|
5188
5187
|
let newContext = otelTrace.setSpan(currentContext, wrappedContext);
|
|
5189
5188
|
newContext = newContext.setValue("braintrust_span", span);
|
|
5189
|
+
const parentValue = span._getOtelParent();
|
|
5190
|
+
if (parentValue) {
|
|
5191
|
+
newContext = newContext.setValue("braintrust.parent", parentValue);
|
|
5192
|
+
}
|
|
5190
5193
|
return otelContext.with(newContext, callback);
|
|
5191
5194
|
}
|
|
5192
5195
|
} catch (error) {
|
|
@@ -5202,34 +5205,6 @@ var init_context3 = __esm({
|
|
|
5202
5205
|
}
|
|
5203
5206
|
return void 0;
|
|
5204
5207
|
}
|
|
5205
|
-
_getOtelParent(span) {
|
|
5206
|
-
if (!span.parentObjectType || !span.parentObjectId) {
|
|
5207
|
-
return void 0;
|
|
5208
|
-
}
|
|
5209
|
-
try {
|
|
5210
|
-
const parentType = span.parentObjectType;
|
|
5211
|
-
const parentId = span.parentObjectId;
|
|
5212
|
-
if (parentType === 2 /* PROJECT_LOGS */) {
|
|
5213
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
5214
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
5215
|
-
parentId.get()
|
|
5216
|
-
) : parentId;
|
|
5217
|
-
if (typeof id === "string") {
|
|
5218
|
-
return `project_id:${id}`;
|
|
5219
|
-
}
|
|
5220
|
-
} else if (parentType === 1 /* EXPERIMENT */) {
|
|
5221
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
5222
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
5223
|
-
parentId.get()
|
|
5224
|
-
) : parentId;
|
|
5225
|
-
if (typeof id === "string") {
|
|
5226
|
-
return `experiment_id:${id}`;
|
|
5227
|
-
}
|
|
5228
|
-
}
|
|
5229
|
-
} catch {
|
|
5230
|
-
}
|
|
5231
|
-
return void 0;
|
|
5232
|
-
}
|
|
5233
5208
|
};
|
|
5234
5209
|
}
|
|
5235
5210
|
});
|
|
@@ -7040,6 +7015,9 @@ var init_logger = __esm({
|
|
|
7040
7015
|
state() {
|
|
7041
7016
|
return _internalGetGlobalState();
|
|
7042
7017
|
}
|
|
7018
|
+
_getOtelParent() {
|
|
7019
|
+
return void 0;
|
|
7020
|
+
}
|
|
7043
7021
|
// Custom inspect for Node.js console.log
|
|
7044
7022
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
7045
7023
|
return `NoopSpan {
|
|
@@ -8547,6 +8525,15 @@ Error: ${errorText}`;
|
|
|
8547
8525
|
return (await this.lazyMetadata.get()).experiment.id;
|
|
8548
8526
|
})();
|
|
8549
8527
|
}
|
|
8528
|
+
/**
|
|
8529
|
+
* Wait for the experiment ID to be resolved. This is useful for ensuring the ID
|
|
8530
|
+
* is available synchronously in child spans (for OTEL parent attributes).
|
|
8531
|
+
* @internal
|
|
8532
|
+
*/
|
|
8533
|
+
async _waitForId() {
|
|
8534
|
+
await this.lazyId.get().catch(() => {
|
|
8535
|
+
});
|
|
8536
|
+
}
|
|
8550
8537
|
get name() {
|
|
8551
8538
|
return (async () => {
|
|
8552
8539
|
return (await this.lazyMetadata.get()).experiment.name;
|
|
@@ -9099,6 +9086,42 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
9099
9086
|
state() {
|
|
9100
9087
|
return this._state;
|
|
9101
9088
|
}
|
|
9089
|
+
/**
|
|
9090
|
+
* Internal method to get the OTEL parent string for this span.
|
|
9091
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
9092
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
9093
|
+
*/
|
|
9094
|
+
_getOtelParent() {
|
|
9095
|
+
if (!this.parentObjectType) {
|
|
9096
|
+
return void 0;
|
|
9097
|
+
}
|
|
9098
|
+
try {
|
|
9099
|
+
if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
|
|
9100
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9101
|
+
const id = syncResult.value;
|
|
9102
|
+
const args = this.parentComputeObjectMetadataArgs;
|
|
9103
|
+
if (id) {
|
|
9104
|
+
return `project_id:${id}`;
|
|
9105
|
+
}
|
|
9106
|
+
const projectName = args?.project_name;
|
|
9107
|
+
if (projectName) {
|
|
9108
|
+
return `project_name:${projectName}`;
|
|
9109
|
+
}
|
|
9110
|
+
} else if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
9111
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9112
|
+
const id = syncResult.value;
|
|
9113
|
+
if (!syncResult.resolved) {
|
|
9114
|
+
this.parentObjectId.get().catch(() => {
|
|
9115
|
+
});
|
|
9116
|
+
}
|
|
9117
|
+
if (id) {
|
|
9118
|
+
return `experiment_id:${id}`;
|
|
9119
|
+
}
|
|
9120
|
+
}
|
|
9121
|
+
} catch (e) {
|
|
9122
|
+
}
|
|
9123
|
+
return void 0;
|
|
9124
|
+
}
|
|
9102
9125
|
// Custom inspect for Node.js console.log
|
|
9103
9126
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
9104
9127
|
return `SpanImpl {
|
package/dist/cli.js
CHANGED
|
@@ -6364,7 +6364,6 @@ var init_context3 = __esm({
|
|
|
6364
6364
|
"src/otel/context.ts"() {
|
|
6365
6365
|
"use strict";
|
|
6366
6366
|
init_logger();
|
|
6367
|
-
init_util();
|
|
6368
6367
|
OTEL_NOT_INSTALLED_MESSAGE = "OpenTelemetry packages are not installed. Install them with: npm install @opentelemetry/api @opentelemetry/sdk-trace-base";
|
|
6369
6368
|
otelTrace = null;
|
|
6370
6369
|
otelContext = null;
|
|
@@ -6427,6 +6426,10 @@ var init_context3 = __esm({
|
|
|
6427
6426
|
const currentContext = otelContext.active();
|
|
6428
6427
|
let newContext = otelTrace.setSpan(currentContext, wrappedContext);
|
|
6429
6428
|
newContext = newContext.setValue("braintrust_span", span);
|
|
6429
|
+
const parentValue = span._getOtelParent();
|
|
6430
|
+
if (parentValue) {
|
|
6431
|
+
newContext = newContext.setValue("braintrust.parent", parentValue);
|
|
6432
|
+
}
|
|
6430
6433
|
return otelContext.with(newContext, callback);
|
|
6431
6434
|
}
|
|
6432
6435
|
} catch (error2) {
|
|
@@ -6442,34 +6445,6 @@ var init_context3 = __esm({
|
|
|
6442
6445
|
}
|
|
6443
6446
|
return void 0;
|
|
6444
6447
|
}
|
|
6445
|
-
_getOtelParent(span) {
|
|
6446
|
-
if (!span.parentObjectType || !span.parentObjectId) {
|
|
6447
|
-
return void 0;
|
|
6448
|
-
}
|
|
6449
|
-
try {
|
|
6450
|
-
const parentType = span.parentObjectType;
|
|
6451
|
-
const parentId = span.parentObjectId;
|
|
6452
|
-
if (parentType === 2 /* PROJECT_LOGS */) {
|
|
6453
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
6454
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
6455
|
-
parentId.get()
|
|
6456
|
-
) : parentId;
|
|
6457
|
-
if (typeof id === "string") {
|
|
6458
|
-
return `project_id:${id}`;
|
|
6459
|
-
}
|
|
6460
|
-
} else if (parentType === 1 /* EXPERIMENT */) {
|
|
6461
|
-
const id = typeof parentId === "object" && parentId !== null && "get" in parentId ? (
|
|
6462
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Type guard ensures object has get method
|
|
6463
|
-
parentId.get()
|
|
6464
|
-
) : parentId;
|
|
6465
|
-
if (typeof id === "string") {
|
|
6466
|
-
return `experiment_id:${id}`;
|
|
6467
|
-
}
|
|
6468
|
-
}
|
|
6469
|
-
} catch {
|
|
6470
|
-
}
|
|
6471
|
-
return void 0;
|
|
6472
|
-
}
|
|
6473
6448
|
};
|
|
6474
6449
|
}
|
|
6475
6450
|
});
|
|
@@ -7744,6 +7719,9 @@ var init_logger = __esm({
|
|
|
7744
7719
|
state() {
|
|
7745
7720
|
return _internalGetGlobalState();
|
|
7746
7721
|
}
|
|
7722
|
+
_getOtelParent() {
|
|
7723
|
+
return void 0;
|
|
7724
|
+
}
|
|
7747
7725
|
// Custom inspect for Node.js console.log
|
|
7748
7726
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
7749
7727
|
return `NoopSpan {
|
|
@@ -9131,6 +9109,15 @@ Error: ${errorText}`;
|
|
|
9131
9109
|
return (await this.lazyMetadata.get()).experiment.id;
|
|
9132
9110
|
})();
|
|
9133
9111
|
}
|
|
9112
|
+
/**
|
|
9113
|
+
* Wait for the experiment ID to be resolved. This is useful for ensuring the ID
|
|
9114
|
+
* is available synchronously in child spans (for OTEL parent attributes).
|
|
9115
|
+
* @internal
|
|
9116
|
+
*/
|
|
9117
|
+
async _waitForId() {
|
|
9118
|
+
await this.lazyId.get().catch(() => {
|
|
9119
|
+
});
|
|
9120
|
+
}
|
|
9134
9121
|
get name() {
|
|
9135
9122
|
return (async () => {
|
|
9136
9123
|
return (await this.lazyMetadata.get()).experiment.name;
|
|
@@ -9683,6 +9670,42 @@ View complete results in Braintrust or run experiment.summarize() again.`
|
|
|
9683
9670
|
state() {
|
|
9684
9671
|
return this._state;
|
|
9685
9672
|
}
|
|
9673
|
+
/**
|
|
9674
|
+
* Internal method to get the OTEL parent string for this span.
|
|
9675
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
9676
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
9677
|
+
*/
|
|
9678
|
+
_getOtelParent() {
|
|
9679
|
+
if (!this.parentObjectType) {
|
|
9680
|
+
return void 0;
|
|
9681
|
+
}
|
|
9682
|
+
try {
|
|
9683
|
+
if (this.parentObjectType === 2 /* PROJECT_LOGS */) {
|
|
9684
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9685
|
+
const id = syncResult.value;
|
|
9686
|
+
const args = this.parentComputeObjectMetadataArgs;
|
|
9687
|
+
if (id) {
|
|
9688
|
+
return `project_id:${id}`;
|
|
9689
|
+
}
|
|
9690
|
+
const projectName = args?.project_name;
|
|
9691
|
+
if (projectName) {
|
|
9692
|
+
return `project_name:${projectName}`;
|
|
9693
|
+
}
|
|
9694
|
+
} else if (this.parentObjectType === 1 /* EXPERIMENT */) {
|
|
9695
|
+
const syncResult = this.parentObjectId.getSync();
|
|
9696
|
+
const id = syncResult.value;
|
|
9697
|
+
if (!syncResult.resolved) {
|
|
9698
|
+
this.parentObjectId.get().catch(() => {
|
|
9699
|
+
});
|
|
9700
|
+
}
|
|
9701
|
+
if (id) {
|
|
9702
|
+
return `experiment_id:${id}`;
|
|
9703
|
+
}
|
|
9704
|
+
}
|
|
9705
|
+
} catch (e) {
|
|
9706
|
+
}
|
|
9707
|
+
return void 0;
|
|
9708
|
+
}
|
|
9686
9709
|
// Custom inspect for Node.js console.log
|
|
9687
9710
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
9688
9711
|
return `SpanImpl {
|
|
@@ -10173,7 +10196,7 @@ var require_package = __commonJS({
|
|
|
10173
10196
|
"package.json"(exports2, module2) {
|
|
10174
10197
|
module2.exports = {
|
|
10175
10198
|
name: "braintrust",
|
|
10176
|
-
version: "0.4.
|
|
10199
|
+
version: "0.4.2",
|
|
10177
10200
|
description: "SDK for integrating Braintrust",
|
|
10178
10201
|
repository: {
|
|
10179
10202
|
type: "git",
|
|
@@ -10319,7 +10342,7 @@ var dotenv2 = __toESM(require("dotenv"));
|
|
|
10319
10342
|
var import_fs2 = __toESM(require("fs"));
|
|
10320
10343
|
var import_os = __toESM(require("os"));
|
|
10321
10344
|
var import_path6 = __toESM(require("path"));
|
|
10322
|
-
var
|
|
10345
|
+
var import_util14 = __toESM(require("util"));
|
|
10323
10346
|
var fsWalk = __toESM(require_out3());
|
|
10324
10347
|
var import_minimatch = require("minimatch");
|
|
10325
10348
|
var import_argparse = require("argparse");
|
|
@@ -11922,6 +11945,9 @@ async function Eval(name, evaluator, reporterOrOpts) {
|
|
|
11922
11945
|
repoInfo: evaluator.repoInfo,
|
|
11923
11946
|
dataset: Dataset2.isDataset(data) ? data : void 0
|
|
11924
11947
|
});
|
|
11948
|
+
if (experiment && typeof process !== "undefined" && process.env?.BRAINTRUST_OTEL_COMPAT?.toLowerCase() === "true") {
|
|
11949
|
+
await experiment._waitForId();
|
|
11950
|
+
}
|
|
11925
11951
|
if (experiment && options.onStart) {
|
|
11926
11952
|
const summary = await experiment.summarize({ summarizeScores: false });
|
|
11927
11953
|
options.onStart(summary);
|
|
@@ -12664,7 +12690,7 @@ function getCallerLocation() {
|
|
|
12664
12690
|
|
|
12665
12691
|
// src/node.ts
|
|
12666
12692
|
init_logger();
|
|
12667
|
-
var
|
|
12693
|
+
var import_util8 = require("util");
|
|
12668
12694
|
var zlib = __toESM(require("zlib"));
|
|
12669
12695
|
function configureNode() {
|
|
12670
12696
|
isomorph_default.getRepoInfo = getRepoInfo;
|
|
@@ -12686,8 +12712,8 @@ function configureNode() {
|
|
|
12686
12712
|
isomorph_default.utimes = fs.utimes;
|
|
12687
12713
|
isomorph_default.unlink = fs.unlink;
|
|
12688
12714
|
isomorph_default.homedir = os.homedir;
|
|
12689
|
-
isomorph_default.gzip = (0,
|
|
12690
|
-
isomorph_default.gunzip = (0,
|
|
12715
|
+
isomorph_default.gzip = (0, import_util8.promisify)(zlib.gzip);
|
|
12716
|
+
isomorph_default.gunzip = (0, import_util8.promisify)(zlib.gunzip);
|
|
12691
12717
|
isomorph_default.hash = (data) => crypto.createHash("sha256").update(data).digest("hex");
|
|
12692
12718
|
_internalSetInitialState();
|
|
12693
12719
|
}
|
|
@@ -13311,7 +13337,7 @@ init_generated_types();
|
|
|
13311
13337
|
init_logger();
|
|
13312
13338
|
var import_v311 = require("zod/v3");
|
|
13313
13339
|
var import_promises = __toESM(require("fs/promises"));
|
|
13314
|
-
var
|
|
13340
|
+
var import_util11 = __toESM(require("util"));
|
|
13315
13341
|
var import_slugify3 = __toESM(require("slugify"));
|
|
13316
13342
|
var import_path5 = __toESM(require("path"));
|
|
13317
13343
|
init_util();
|
|
@@ -13584,7 +13610,7 @@ function safeStringify(obj) {
|
|
|
13584
13610
|
return JSON.stringify(obj, null, 2);
|
|
13585
13611
|
} catch (error2) {
|
|
13586
13612
|
try {
|
|
13587
|
-
return
|
|
13613
|
+
return import_util11.default.inspect(obj, {
|
|
13588
13614
|
depth: 5,
|
|
13589
13615
|
maxStringLength: 1e3,
|
|
13590
13616
|
breakLength: 80,
|
|
@@ -14586,7 +14612,7 @@ async function collectFiles(inputPath, mode) {
|
|
|
14586
14612
|
}
|
|
14587
14613
|
files.push(inputPath);
|
|
14588
14614
|
} else {
|
|
14589
|
-
const walked = await
|
|
14615
|
+
const walked = await import_util14.default.promisify(fsWalk.walk)(inputPath, {
|
|
14590
14616
|
deepFilter: (entry) => {
|
|
14591
14617
|
return checkMatch(entry.path, null, EXCLUDE);
|
|
14592
14618
|
},
|
package/dist/index.d.mts
CHANGED
|
@@ -14477,6 +14477,12 @@ interface Span$1 extends Exportable {
|
|
|
14477
14477
|
*/
|
|
14478
14478
|
startSpanWithParents(spanId: string, spanParents: string[], args?: StartSpanArgs): Span$1;
|
|
14479
14479
|
state(): BraintrustState;
|
|
14480
|
+
/**
|
|
14481
|
+
* Internal method to get the OTEL parent string for this span.
|
|
14482
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
14483
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
14484
|
+
*/
|
|
14485
|
+
_getOtelParent(): string | undefined;
|
|
14480
14486
|
kind: "span";
|
|
14481
14487
|
}
|
|
14482
14488
|
declare abstract class ContextManager {
|
|
@@ -14508,6 +14514,7 @@ declare class NoopSpan implements Span$1 {
|
|
|
14508
14514
|
setAttributes(_args: Omit<StartSpanArgs, "event">): void;
|
|
14509
14515
|
startSpanWithParents(_spanId: string, _spanParents: string[], _args?: StartSpanArgs): Span$1;
|
|
14510
14516
|
state(): BraintrustState;
|
|
14517
|
+
_getOtelParent(): string | undefined;
|
|
14511
14518
|
toString(): string;
|
|
14512
14519
|
}
|
|
14513
14520
|
declare const NOOP_SPAN: NoopSpan;
|
|
@@ -15479,6 +15486,12 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
|
|
|
15479
15486
|
kind: "experiment";
|
|
15480
15487
|
constructor(state: BraintrustState, lazyMetadata: LazyValue<ProjectExperimentMetadata>, dataset?: AnyDataset);
|
|
15481
15488
|
get id(): Promise<string>;
|
|
15489
|
+
/**
|
|
15490
|
+
* Wait for the experiment ID to be resolved. This is useful for ensuring the ID
|
|
15491
|
+
* is available synchronously in child spans (for OTEL parent attributes).
|
|
15492
|
+
* @internal
|
|
15493
|
+
*/
|
|
15494
|
+
_waitForId(): Promise<void>;
|
|
15482
15495
|
get name(): Promise<string>;
|
|
15483
15496
|
get project(): Promise<ObjectMetadata>;
|
|
15484
15497
|
private parentObjectType;
|
|
@@ -15628,6 +15641,12 @@ declare class SpanImpl implements Span$1 {
|
|
|
15628
15641
|
flush(): Promise<void>;
|
|
15629
15642
|
close(args?: EndSpanArgs): number;
|
|
15630
15643
|
state(): BraintrustState;
|
|
15644
|
+
/**
|
|
15645
|
+
* Internal method to get the OTEL parent string for this span.
|
|
15646
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
15647
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
15648
|
+
*/
|
|
15649
|
+
_getOtelParent(): string | undefined;
|
|
15631
15650
|
toString(): string;
|
|
15632
15651
|
}
|
|
15633
15652
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -14477,6 +14477,12 @@ interface Span$1 extends Exportable {
|
|
|
14477
14477
|
*/
|
|
14478
14478
|
startSpanWithParents(spanId: string, spanParents: string[], args?: StartSpanArgs): Span$1;
|
|
14479
14479
|
state(): BraintrustState;
|
|
14480
|
+
/**
|
|
14481
|
+
* Internal method to get the OTEL parent string for this span.
|
|
14482
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
14483
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
14484
|
+
*/
|
|
14485
|
+
_getOtelParent(): string | undefined;
|
|
14480
14486
|
kind: "span";
|
|
14481
14487
|
}
|
|
14482
14488
|
declare abstract class ContextManager {
|
|
@@ -14508,6 +14514,7 @@ declare class NoopSpan implements Span$1 {
|
|
|
14508
14514
|
setAttributes(_args: Omit<StartSpanArgs, "event">): void;
|
|
14509
14515
|
startSpanWithParents(_spanId: string, _spanParents: string[], _args?: StartSpanArgs): Span$1;
|
|
14510
14516
|
state(): BraintrustState;
|
|
14517
|
+
_getOtelParent(): string | undefined;
|
|
14511
14518
|
toString(): string;
|
|
14512
14519
|
}
|
|
14513
14520
|
declare const NOOP_SPAN: NoopSpan;
|
|
@@ -15479,6 +15486,12 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
|
|
|
15479
15486
|
kind: "experiment";
|
|
15480
15487
|
constructor(state: BraintrustState, lazyMetadata: LazyValue<ProjectExperimentMetadata>, dataset?: AnyDataset);
|
|
15481
15488
|
get id(): Promise<string>;
|
|
15489
|
+
/**
|
|
15490
|
+
* Wait for the experiment ID to be resolved. This is useful for ensuring the ID
|
|
15491
|
+
* is available synchronously in child spans (for OTEL parent attributes).
|
|
15492
|
+
* @internal
|
|
15493
|
+
*/
|
|
15494
|
+
_waitForId(): Promise<void>;
|
|
15482
15495
|
get name(): Promise<string>;
|
|
15483
15496
|
get project(): Promise<ObjectMetadata>;
|
|
15484
15497
|
private parentObjectType;
|
|
@@ -15628,6 +15641,12 @@ declare class SpanImpl implements Span$1 {
|
|
|
15628
15641
|
flush(): Promise<void>;
|
|
15629
15642
|
close(args?: EndSpanArgs): number;
|
|
15630
15643
|
state(): BraintrustState;
|
|
15644
|
+
/**
|
|
15645
|
+
* Internal method to get the OTEL parent string for this span.
|
|
15646
|
+
* This is used by OtelContextManager to set the braintrust.parent attribute.
|
|
15647
|
+
* @returns A string like "project_id:X" or "experiment_id:X", or undefined if no parent
|
|
15648
|
+
*/
|
|
15649
|
+
_getOtelParent(): string | undefined;
|
|
15631
15650
|
toString(): string;
|
|
15632
15651
|
}
|
|
15633
15652
|
/**
|