braintrust 0.0.89 → 0.0.91
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/dist/browser.js +201 -21
- package/dist/cli.js +132 -13
- package/dist/index.js +211 -23
- package/dist/logger.d.ts +74 -6
- package/dist/oai.d.ts +5 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/util.d.ts +1 -0
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -7766,7 +7766,9 @@ async function getRepoStatus() {
|
|
|
7766
7766
|
async () => (await git.raw(["rev-parse", "--abbrev-ref", "HEAD"])).trim()
|
|
7767
7767
|
);
|
|
7768
7768
|
if (dirty) {
|
|
7769
|
-
git_diff = await attempt(
|
|
7769
|
+
git_diff = await attempt(
|
|
7770
|
+
async () => truncateToByteLimit(await git.raw(["diff", "HEAD"]))
|
|
7771
|
+
);
|
|
7770
7772
|
}
|
|
7771
7773
|
return {
|
|
7772
7774
|
commit,
|
|
@@ -7875,6 +7877,10 @@ var v4_default = v4;
|
|
|
7875
7877
|
// ../core/js/dist/index.mjs
|
|
7876
7878
|
var TRANSACTION_ID_FIELD = "_xact_id";
|
|
7877
7879
|
var IS_MERGE_FIELD = "_is_merge";
|
|
7880
|
+
var AUDIT_SOURCE_FIELD = "_audit_source";
|
|
7881
|
+
var AUDIT_METADATA_FIELD = "_audit_metadata";
|
|
7882
|
+
var VALID_SOURCES = ["app", "api", "external"];
|
|
7883
|
+
var PARENT_ID_FIELD = "_parent_id";
|
|
7878
7884
|
function mergeDicts(mergeInto, mergeFrom) {
|
|
7879
7885
|
for (const [k, mergeFromV] of Object.entries(mergeFrom)) {
|
|
7880
7886
|
const mergeIntoV = mergeInto[k];
|
|
@@ -7887,6 +7893,7 @@ function mergeDicts(mergeInto, mergeFrom) {
|
|
|
7887
7893
|
mergeInto[k] = mergeFromV;
|
|
7888
7894
|
}
|
|
7889
7895
|
}
|
|
7896
|
+
return mergeInto;
|
|
7890
7897
|
}
|
|
7891
7898
|
function generateMergedRowKey(row) {
|
|
7892
7899
|
return JSON.stringify(
|
|
@@ -7928,6 +7935,15 @@ function mergeRowBatch(rows) {
|
|
|
7928
7935
|
out.push(...Object.values(rowGroups));
|
|
7929
7936
|
return out;
|
|
7930
7937
|
}
|
|
7938
|
+
var SpanTypeAttribute = /* @__PURE__ */ ((SpanTypeAttribute2) => {
|
|
7939
|
+
SpanTypeAttribute2["LLM"] = "llm";
|
|
7940
|
+
SpanTypeAttribute2["SCORE"] = "score";
|
|
7941
|
+
SpanTypeAttribute2["FUNCTION"] = "function";
|
|
7942
|
+
SpanTypeAttribute2["EVAL"] = "eval";
|
|
7943
|
+
SpanTypeAttribute2["TASK"] = "task";
|
|
7944
|
+
SpanTypeAttribute2["TOOL"] = "tool";
|
|
7945
|
+
return SpanTypeAttribute2;
|
|
7946
|
+
})(SpanTypeAttribute || {});
|
|
7931
7947
|
|
|
7932
7948
|
// src/util.ts
|
|
7933
7949
|
var GLOBAL_PROJECT = "Global";
|
|
@@ -7950,6 +7966,9 @@ function runFinally(f, finallyF) {
|
|
|
7950
7966
|
function getCurrentUnixTimestamp() {
|
|
7951
7967
|
return (/* @__PURE__ */ new Date()).getTime() / 1e3;
|
|
7952
7968
|
}
|
|
7969
|
+
function isEmpty(a) {
|
|
7970
|
+
return a === void 0 || a === null;
|
|
7971
|
+
}
|
|
7953
7972
|
|
|
7954
7973
|
// src/logger.ts
|
|
7955
7974
|
var NoopSpan = class {
|
|
@@ -7961,6 +7980,8 @@ var NoopSpan = class {
|
|
|
7961
7980
|
}
|
|
7962
7981
|
log(_) {
|
|
7963
7982
|
}
|
|
7983
|
+
logFeedback(event) {
|
|
7984
|
+
}
|
|
7964
7985
|
traced(callback, _1) {
|
|
7965
7986
|
return callback(this);
|
|
7966
7987
|
}
|
|
@@ -8135,6 +8156,70 @@ var HTTPConnection = class _HTTPConnection {
|
|
|
8135
8156
|
return await resp.json();
|
|
8136
8157
|
}
|
|
8137
8158
|
};
|
|
8159
|
+
function logFeedbackImpl(bgLogger, parentIds, {
|
|
8160
|
+
id,
|
|
8161
|
+
expected,
|
|
8162
|
+
scores,
|
|
8163
|
+
metadata: inputMetadata,
|
|
8164
|
+
comment,
|
|
8165
|
+
source: inputSource
|
|
8166
|
+
}) {
|
|
8167
|
+
const source = inputSource ?? "external";
|
|
8168
|
+
if (!VALID_SOURCES.includes(source)) {
|
|
8169
|
+
throw new Error(`source must be one of ${VALID_SOURCES}`);
|
|
8170
|
+
}
|
|
8171
|
+
if (isEmpty(scores) && isEmpty(expected) && isEmpty(comment)) {
|
|
8172
|
+
throw new Error(
|
|
8173
|
+
"At least one of scores, expected, or comment must be specified"
|
|
8174
|
+
);
|
|
8175
|
+
}
|
|
8176
|
+
const validatedEvent = validateAndSanitizeExperimentLogPartialArgs({
|
|
8177
|
+
scores,
|
|
8178
|
+
metadata: inputMetadata,
|
|
8179
|
+
expected
|
|
8180
|
+
});
|
|
8181
|
+
let { metadata, ...updateEvent } = validatedEvent;
|
|
8182
|
+
updateEvent = Object.fromEntries(
|
|
8183
|
+
Object.entries(updateEvent).filter(([_, v]) => !isEmpty(v))
|
|
8184
|
+
);
|
|
8185
|
+
const trueParentIds = (async () => {
|
|
8186
|
+
const { kind, ...ids } = await parentIds;
|
|
8187
|
+
return ids;
|
|
8188
|
+
})();
|
|
8189
|
+
if (Object.keys(updateEvent).length > 0) {
|
|
8190
|
+
const record = (async () => {
|
|
8191
|
+
return {
|
|
8192
|
+
id,
|
|
8193
|
+
...updateEvent,
|
|
8194
|
+
...await trueParentIds,
|
|
8195
|
+
[AUDIT_SOURCE_FIELD]: source,
|
|
8196
|
+
[AUDIT_METADATA_FIELD]: metadata,
|
|
8197
|
+
[IS_MERGE_FIELD]: true
|
|
8198
|
+
};
|
|
8199
|
+
})();
|
|
8200
|
+
bgLogger.log([record]);
|
|
8201
|
+
}
|
|
8202
|
+
if (!isEmpty(comment)) {
|
|
8203
|
+
const record = (async () => {
|
|
8204
|
+
return {
|
|
8205
|
+
id: v4_default(),
|
|
8206
|
+
created: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8207
|
+
origin: {
|
|
8208
|
+
// NOTE: We do not know (or care?) what the transaction id of the row that
|
|
8209
|
+
// we're commenting on is here, so we omit it.
|
|
8210
|
+
id
|
|
8211
|
+
},
|
|
8212
|
+
comment: {
|
|
8213
|
+
text: comment
|
|
8214
|
+
},
|
|
8215
|
+
...await trueParentIds,
|
|
8216
|
+
[AUDIT_SOURCE_FIELD]: source,
|
|
8217
|
+
[AUDIT_METADATA_FIELD]: metadata
|
|
8218
|
+
};
|
|
8219
|
+
})();
|
|
8220
|
+
bgLogger.log([record]);
|
|
8221
|
+
}
|
|
8222
|
+
}
|
|
8138
8223
|
var Logger = class {
|
|
8139
8224
|
constructor(lazyMetadata, logOptions = {}) {
|
|
8140
8225
|
// For type identification.
|
|
@@ -8213,6 +8298,14 @@ var Logger = class {
|
|
|
8213
8298
|
})();
|
|
8214
8299
|
}
|
|
8215
8300
|
}
|
|
8301
|
+
async lazyParentIds() {
|
|
8302
|
+
return {
|
|
8303
|
+
kind: "project_log",
|
|
8304
|
+
org_id: await this.org_id,
|
|
8305
|
+
project_id: (await this.project).id,
|
|
8306
|
+
log_id: "g"
|
|
8307
|
+
};
|
|
8308
|
+
}
|
|
8216
8309
|
/**
|
|
8217
8310
|
* Lower-level alternative to `traced`, which does not automatically end the span or mark it as current.
|
|
8218
8311
|
*
|
|
@@ -8220,19 +8313,27 @@ var Logger = class {
|
|
|
8220
8313
|
*/
|
|
8221
8314
|
startSpan(args) {
|
|
8222
8315
|
const { name, ...argsRest } = args ?? {};
|
|
8223
|
-
const parentIds = (async () => ({
|
|
8224
|
-
kind: "project_log",
|
|
8225
|
-
org_id: await this.org_id,
|
|
8226
|
-
project_id: (await this.project).id,
|
|
8227
|
-
log_id: "g"
|
|
8228
|
-
}))();
|
|
8229
8316
|
return new SpanImpl({
|
|
8230
|
-
parentIds,
|
|
8317
|
+
parentIds: this.lazyParentIds(),
|
|
8231
8318
|
bgLogger: this.bgLogger,
|
|
8232
8319
|
name: name ?? "root",
|
|
8233
8320
|
...argsRest
|
|
8234
8321
|
});
|
|
8235
8322
|
}
|
|
8323
|
+
/**
|
|
8324
|
+
* Log feedback to an event. Feedback is used to save feedback scores, set an expected value, or add a comment.
|
|
8325
|
+
*
|
|
8326
|
+
* @param event
|
|
8327
|
+
* @param event.id The id of the event to log feedback for. This is the `id` returned by `log` or accessible as the `id` field of a span.
|
|
8328
|
+
* @param event.scores (Optional) a dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the existing scores for the event.
|
|
8329
|
+
* @param event.expected (Optional) the ground truth value (an arbitrary, JSON serializable object) that you'd compare to `output` to determine if your `output` value is correct or not.
|
|
8330
|
+
* @param event.comment (Optional) an optional comment string to log about the event.
|
|
8331
|
+
* @param event.metadata (Optional) a dictionary with additional data about the feedback. If you have a `user_id`, you can log it here and access it in the Braintrust UI.
|
|
8332
|
+
* @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
|
|
8333
|
+
*/
|
|
8334
|
+
logFeedback(event) {
|
|
8335
|
+
logFeedbackImpl(this.bgLogger, this.lazyParentIds(), event);
|
|
8336
|
+
}
|
|
8236
8337
|
/*
|
|
8237
8338
|
* Flush any pending logs to the server.
|
|
8238
8339
|
*/
|
|
@@ -8824,6 +8925,13 @@ var Experiment = class {
|
|
|
8824
8925
|
() => span.end()
|
|
8825
8926
|
);
|
|
8826
8927
|
}
|
|
8928
|
+
async lazyParentIds() {
|
|
8929
|
+
return {
|
|
8930
|
+
kind: "experiment",
|
|
8931
|
+
project_id: (await this.project).id,
|
|
8932
|
+
experiment_id: await this.id
|
|
8933
|
+
};
|
|
8934
|
+
}
|
|
8827
8935
|
/**
|
|
8828
8936
|
* Lower-level alternative to `traced`, which does not automatically end the span or mark it as current.
|
|
8829
8937
|
*
|
|
@@ -8831,13 +8939,8 @@ var Experiment = class {
|
|
|
8831
8939
|
*/
|
|
8832
8940
|
startSpan(args) {
|
|
8833
8941
|
const { name, ...argsRest } = args ?? {};
|
|
8834
|
-
const parentIds = (async () => ({
|
|
8835
|
-
kind: "experiment",
|
|
8836
|
-
project_id: (await this.project).id,
|
|
8837
|
-
experiment_id: await this.id
|
|
8838
|
-
}))();
|
|
8839
8942
|
return new SpanImpl({
|
|
8840
|
-
parentIds,
|
|
8943
|
+
parentIds: this.lazyParentIds(),
|
|
8841
8944
|
bgLogger: this.bgLogger,
|
|
8842
8945
|
name: name ?? "root",
|
|
8843
8946
|
...argsRest
|
|
@@ -8899,6 +9002,20 @@ var Experiment = class {
|
|
|
8899
9002
|
metrics
|
|
8900
9003
|
};
|
|
8901
9004
|
}
|
|
9005
|
+
/**
|
|
9006
|
+
* Log feedback to an event in the experiment. Feedback is used to save feedback scores, set an expected value, or add a comment.
|
|
9007
|
+
*
|
|
9008
|
+
* @param event
|
|
9009
|
+
* @param event.id The id of the event to log feedback for. This is the `id` returned by `log` or accessible as the `id` field of a span.
|
|
9010
|
+
* @param event.scores (Optional) a dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the existing scores for the event.
|
|
9011
|
+
* @param event.expected (Optional) the ground truth value (an arbitrary, JSON serializable object) that you'd compare to `output` to determine if your `output` value is correct or not.
|
|
9012
|
+
* @param event.comment (Optional) an optional comment string to log about the event.
|
|
9013
|
+
* @param event.metadata (Optional) a dictionary with additional data about the feedback. If you have a `user_id`, you can log it here and access it in the Braintrust UI.
|
|
9014
|
+
* @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
|
|
9015
|
+
*/
|
|
9016
|
+
logFeedback(event) {
|
|
9017
|
+
logFeedbackImpl(this.bgLogger, this.lazyParentIds(), event);
|
|
9018
|
+
}
|
|
8902
9019
|
/**
|
|
8903
9020
|
* Flush any pending rows to the server.
|
|
8904
9021
|
*/
|
|
@@ -8949,10 +9066,12 @@ var SpanImpl = class _SpanImpl {
|
|
|
8949
9066
|
this.rowIds = {
|
|
8950
9067
|
id,
|
|
8951
9068
|
span_id,
|
|
8952
|
-
root_span_id: args.parentSpanInfo?.root_span_id
|
|
9069
|
+
root_span_id: "parentSpanInfo" in args && args.parentSpanInfo?.root_span_id ? args.parentSpanInfo.root_span_id : span_id
|
|
8953
9070
|
};
|
|
8954
|
-
if (args.parentSpanInfo) {
|
|
9071
|
+
if ("parentSpanInfo" in args && args.parentSpanInfo?.span_id) {
|
|
8955
9072
|
this.internalData.span_parents = [args.parentSpanInfo.span_id];
|
|
9073
|
+
} else if ("parentId" in args && !isEmpty(args.parentId)) {
|
|
9074
|
+
this.rowIds[PARENT_ID_FIELD] = args.parentId;
|
|
8956
9075
|
}
|
|
8957
9076
|
this.isMerge = false;
|
|
8958
9077
|
const { id: _id, ...eventRest } = args.event ?? {};
|
|
@@ -8976,16 +9095,26 @@ var SpanImpl = class _SpanImpl {
|
|
|
8976
9095
|
if (sanitizedAndInternalData.metrics?.end) {
|
|
8977
9096
|
this.loggedEndTime = sanitizedAndInternalData.metrics?.end;
|
|
8978
9097
|
}
|
|
9098
|
+
const parentIds = (async () => {
|
|
9099
|
+
const { kind, ...ids } = await this.parentIds;
|
|
9100
|
+
return ids;
|
|
9101
|
+
})();
|
|
8979
9102
|
const record = (async () => {
|
|
8980
9103
|
return {
|
|
8981
9104
|
...sanitizedAndInternalData,
|
|
8982
9105
|
...this.rowIds,
|
|
8983
|
-
...await
|
|
9106
|
+
...await parentIds,
|
|
8984
9107
|
[IS_MERGE_FIELD]: this.isMerge
|
|
8985
9108
|
};
|
|
8986
9109
|
})();
|
|
8987
9110
|
this.bgLogger.log([record]);
|
|
8988
9111
|
}
|
|
9112
|
+
logFeedback(event) {
|
|
9113
|
+
logFeedbackImpl(this.bgLogger, this.parentIds, {
|
|
9114
|
+
...event,
|
|
9115
|
+
id: this.id
|
|
9116
|
+
});
|
|
9117
|
+
}
|
|
8989
9118
|
traced(callback, args) {
|
|
8990
9119
|
const { setCurrent, ...argsRest } = args ?? {};
|
|
8991
9120
|
const span = this.startSpan(argsRest);
|
|
@@ -9375,7 +9504,7 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
|
|
|
9375
9504
|
}
|
|
9376
9505
|
span.log({ input: datum.input, output });
|
|
9377
9506
|
},
|
|
9378
|
-
{ name: "task" }
|
|
9507
|
+
{ name: "task", spanAttributes: { type: SpanTypeAttribute.TASK } }
|
|
9379
9508
|
);
|
|
9380
9509
|
rootSpan.log({ output });
|
|
9381
9510
|
const scoringArgs = { ...datum, metadata, output };
|
|
@@ -9398,6 +9527,9 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
|
|
|
9398
9527
|
},
|
|
9399
9528
|
{
|
|
9400
9529
|
name: score.name || `scorer_${score_idx}`,
|
|
9530
|
+
spanAttributes: {
|
|
9531
|
+
type: SpanTypeAttribute.SCORE
|
|
9532
|
+
},
|
|
9401
9533
|
event: { input: scoringArgs }
|
|
9402
9534
|
}
|
|
9403
9535
|
);
|
|
@@ -9437,6 +9569,9 @@ async function runEvaluator(experiment, evaluator, progressReporter, filters) {
|
|
|
9437
9569
|
} else {
|
|
9438
9570
|
return await experiment.traced(callback, {
|
|
9439
9571
|
name: "eval",
|
|
9572
|
+
spanAttributes: {
|
|
9573
|
+
type: SpanTypeAttribute.EVAL
|
|
9574
|
+
},
|
|
9440
9575
|
event: {
|
|
9441
9576
|
input: datum.input,
|
|
9442
9577
|
expected: datum.expected
|
|
@@ -9532,6 +9667,7 @@ function wrapOpenAI(openai) {
|
|
|
9532
9667
|
return openai;
|
|
9533
9668
|
}
|
|
9534
9669
|
}
|
|
9670
|
+
globalThis.__inherited_braintrust_wrap_openai = wrapOpenAI;
|
|
9535
9671
|
function wrapOpenAIv4(openai) {
|
|
9536
9672
|
let completionProxy = new Proxy(openai.chat.completions, {
|
|
9537
9673
|
get(target, name, receiver) {
|
|
@@ -9550,6 +9686,15 @@ function wrapOpenAIv4(openai) {
|
|
|
9550
9686
|
return Reflect.get(target, name, receiver);
|
|
9551
9687
|
}
|
|
9552
9688
|
});
|
|
9689
|
+
let embeddingProxy = new Proxy(openai.embeddings, {
|
|
9690
|
+
get(target, name, receiver) {
|
|
9691
|
+
const baseVal = Reflect.get(target, name, receiver);
|
|
9692
|
+
if (name === "create") {
|
|
9693
|
+
return wrapEmbeddings(baseVal.bind(target));
|
|
9694
|
+
}
|
|
9695
|
+
return baseVal;
|
|
9696
|
+
}
|
|
9697
|
+
});
|
|
9553
9698
|
let betaProxy;
|
|
9554
9699
|
if (openai.beta?.chat?.completions?.stream) {
|
|
9555
9700
|
let betaChatCompletionProxy = new Proxy(openai?.beta?.chat.completions, {
|
|
@@ -9583,6 +9728,9 @@ function wrapOpenAIv4(openai) {
|
|
|
9583
9728
|
if (name === "chat") {
|
|
9584
9729
|
return chatProxy;
|
|
9585
9730
|
}
|
|
9731
|
+
if (name === "embeddings") {
|
|
9732
|
+
return embeddingProxy;
|
|
9733
|
+
}
|
|
9586
9734
|
if (name === "beta" && betaProxy) {
|
|
9587
9735
|
return betaProxy;
|
|
9588
9736
|
}
|
|
@@ -9592,10 +9740,13 @@ function wrapOpenAIv4(openai) {
|
|
|
9592
9740
|
return proxy;
|
|
9593
9741
|
}
|
|
9594
9742
|
function wrapBetaChatCompletion(completion) {
|
|
9595
|
-
return
|
|
9743
|
+
return (params) => {
|
|
9596
9744
|
const { messages, ...rest } = params;
|
|
9597
9745
|
const span = startSpan({
|
|
9598
9746
|
name: "OpenAI Chat Completion",
|
|
9747
|
+
spanAttributes: {
|
|
9748
|
+
type: SpanTypeAttribute.LLM
|
|
9749
|
+
},
|
|
9599
9750
|
event: {
|
|
9600
9751
|
input: messages,
|
|
9601
9752
|
metadata: {
|
|
@@ -9604,7 +9755,7 @@ function wrapBetaChatCompletion(completion) {
|
|
|
9604
9755
|
}
|
|
9605
9756
|
});
|
|
9606
9757
|
const startTime = getCurrentUnixTimestamp();
|
|
9607
|
-
const ret =
|
|
9758
|
+
const ret = completion(params);
|
|
9608
9759
|
let first2 = true;
|
|
9609
9760
|
ret.on("chunk", (_chunk) => {
|
|
9610
9761
|
if (first2) {
|
|
@@ -9629,10 +9780,13 @@ function wrapBetaChatCompletion(completion) {
|
|
|
9629
9780
|
};
|
|
9630
9781
|
}
|
|
9631
9782
|
function wrapChatCompletion(completion) {
|
|
9632
|
-
return async (params) => {
|
|
9783
|
+
return async (params, options) => {
|
|
9633
9784
|
const { messages, ...rest } = params;
|
|
9634
9785
|
const span = startSpan({
|
|
9635
9786
|
name: "OpenAI Chat Completion",
|
|
9787
|
+
spanAttributes: {
|
|
9788
|
+
type: SpanTypeAttribute.LLM
|
|
9789
|
+
},
|
|
9636
9790
|
event: {
|
|
9637
9791
|
input: messages,
|
|
9638
9792
|
metadata: {
|
|
@@ -9642,11 +9796,14 @@ function wrapChatCompletion(completion) {
|
|
|
9642
9796
|
});
|
|
9643
9797
|
if (params.stream) {
|
|
9644
9798
|
const startTime = getCurrentUnixTimestamp();
|
|
9645
|
-
const ret = await completion(params);
|
|
9799
|
+
const ret = await completion(params, options);
|
|
9646
9800
|
return new WrapperStream(span, startTime, ret);
|
|
9647
9801
|
} else {
|
|
9648
9802
|
try {
|
|
9649
|
-
const ret = await completion(
|
|
9803
|
+
const ret = await completion(
|
|
9804
|
+
params,
|
|
9805
|
+
options
|
|
9806
|
+
);
|
|
9650
9807
|
const { messages: messages2, ...rest2 } = params;
|
|
9651
9808
|
span.log({
|
|
9652
9809
|
input: messages2,
|
|
@@ -9667,6 +9824,37 @@ function wrapChatCompletion(completion) {
|
|
|
9667
9824
|
}
|
|
9668
9825
|
};
|
|
9669
9826
|
}
|
|
9827
|
+
function wrapEmbeddings(create) {
|
|
9828
|
+
return async (params, options) => {
|
|
9829
|
+
const { input, ...rest } = params;
|
|
9830
|
+
return traced(
|
|
9831
|
+
async (span) => {
|
|
9832
|
+
const result = await create(params, options);
|
|
9833
|
+
const output = result.data[0];
|
|
9834
|
+
span.log({
|
|
9835
|
+
output,
|
|
9836
|
+
metrics: {
|
|
9837
|
+
tokens: result.usage?.total_tokens,
|
|
9838
|
+
prompt_tokens: result.usage?.prompt_tokens
|
|
9839
|
+
}
|
|
9840
|
+
});
|
|
9841
|
+
return result;
|
|
9842
|
+
},
|
|
9843
|
+
{
|
|
9844
|
+
name: "OpenAI Embedding",
|
|
9845
|
+
spanAttributes: {
|
|
9846
|
+
type: SpanTypeAttribute.LLM
|
|
9847
|
+
},
|
|
9848
|
+
event: {
|
|
9849
|
+
input,
|
|
9850
|
+
metadata: {
|
|
9851
|
+
...rest
|
|
9852
|
+
}
|
|
9853
|
+
}
|
|
9854
|
+
}
|
|
9855
|
+
);
|
|
9856
|
+
};
|
|
9857
|
+
}
|
|
9670
9858
|
var WrapperStream = class {
|
|
9671
9859
|
constructor(span, startTime, iter) {
|
|
9672
9860
|
this.span = span;
|
package/dist/logger.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
|
-
import { IS_MERGE_FIELD } from "@braintrust/core";
|
|
2
|
+
import { IS_MERGE_FIELD, PARENT_ID_FIELD, Source, AUDIT_SOURCE_FIELD, AUDIT_METADATA_FIELD } from "@braintrust/core";
|
|
3
3
|
import { IsoAsyncLocalStorage } from "./isomorph";
|
|
4
4
|
export type Metadata = Record<string, unknown>;
|
|
5
5
|
export type SetCurrentArg = {
|
|
@@ -10,6 +10,7 @@ export type StartSpanArgs = {
|
|
|
10
10
|
name?: string;
|
|
11
11
|
spanAttributes?: Record<any, any>;
|
|
12
12
|
startTime?: number;
|
|
13
|
+
parentId?: string;
|
|
13
14
|
event?: StartSpanEventArgs;
|
|
14
15
|
};
|
|
15
16
|
export type EndSpanArgs = {
|
|
@@ -41,6 +42,12 @@ export interface Span {
|
|
|
41
42
|
* @param event: Data to be logged. See `Experiment.log` for full details.
|
|
42
43
|
*/
|
|
43
44
|
log(event: ExperimentLogPartialArgs): void;
|
|
45
|
+
/**
|
|
46
|
+
* Add feedback to the current span. Unlike `Experiment.logFeedback` and `Logger.logFeedback`, this method does not accept an id parameter, because it logs feedback to the current span.
|
|
47
|
+
*
|
|
48
|
+
* @param event: Data to be logged. See `Experiment.logFeedback` for full details.
|
|
49
|
+
*/
|
|
50
|
+
logFeedback(event: Omit<LogFeedbackFullArgs, "id">): void;
|
|
44
51
|
/**
|
|
45
52
|
* Create a new span and run the provided callback. This is useful if you want to log more detailed trace information beyond the scope of a single log event. Data logged over several calls to `Span.log` will be merged into one logical row.
|
|
46
53
|
*
|
|
@@ -51,6 +58,7 @@ export interface Span {
|
|
|
51
58
|
* @param args.span_attributes Optional additional attributes to attach to the span, such as a type name.
|
|
52
59
|
* @param args.start_time Optional start time of the span, as a timestamp in seconds.
|
|
53
60
|
* @param args.setCurrent If true (the default), the span will be marked as the currently-active span for the duration of the callback.
|
|
61
|
+
* @param args.parentId Optional id of the parent span. If not provided, the current span will be used (depending on context). This is useful for adding spans to an existing trace.
|
|
54
62
|
* @param args.event Data to be logged. See `Experiment.log` for full details.
|
|
55
63
|
* @Returns The result of running `callback`.
|
|
56
64
|
*/
|
|
@@ -88,6 +96,7 @@ export declare class NoopSpan implements Span {
|
|
|
88
96
|
kind: "span";
|
|
89
97
|
constructor();
|
|
90
98
|
log(_: ExperimentLogPartialArgs): void;
|
|
99
|
+
logFeedback(event: Omit<LogFeedbackFullArgs, "id">): void;
|
|
91
100
|
traced<R>(callback: (span: Span) => R, _1: StartSpanArgs & SetCurrentArg): R;
|
|
92
101
|
startSpan(_1?: StartSpanArgs): this;
|
|
93
102
|
end(args?: EndSpanArgs): number;
|
|
@@ -183,12 +192,25 @@ export declare class Logger<IsAsyncFlush extends boolean> {
|
|
|
183
192
|
* See `Span.traced` for full details.
|
|
184
193
|
*/
|
|
185
194
|
traced<R>(callback: (span: Span) => R, args?: StartSpanArgs & SetCurrentArg): PromiseUnless<IsAsyncFlush, R>;
|
|
195
|
+
private lazyParentIds;
|
|
186
196
|
/**
|
|
187
197
|
* Lower-level alternative to `traced`, which does not automatically end the span or mark it as current.
|
|
188
198
|
*
|
|
189
199
|
* See `traced` for full details.
|
|
190
200
|
*/
|
|
191
201
|
startSpan(args?: StartSpanArgs): Span;
|
|
202
|
+
/**
|
|
203
|
+
* Log feedback to an event. Feedback is used to save feedback scores, set an expected value, or add a comment.
|
|
204
|
+
*
|
|
205
|
+
* @param event
|
|
206
|
+
* @param event.id The id of the event to log feedback for. This is the `id` returned by `log` or accessible as the `id` field of a span.
|
|
207
|
+
* @param event.scores (Optional) a dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the existing scores for the event.
|
|
208
|
+
* @param event.expected (Optional) the ground truth value (an arbitrary, JSON serializable object) that you'd compare to `output` to determine if your `output` value is correct or not.
|
|
209
|
+
* @param event.comment (Optional) an optional comment string to log about the event.
|
|
210
|
+
* @param event.metadata (Optional) a dictionary with additional data about the feedback. If you have a `user_id`, you can log it here and access it in the Braintrust UI.
|
|
211
|
+
* @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
|
|
212
|
+
*/
|
|
213
|
+
logFeedback(event: LogFeedbackFullArgs): void;
|
|
192
214
|
flush(): Promise<void>;
|
|
193
215
|
get asyncFlush(): IsAsyncFlush | undefined;
|
|
194
216
|
}
|
|
@@ -211,10 +233,25 @@ export type OtherExperimentLogFields = {
|
|
|
211
233
|
};
|
|
212
234
|
export type ExperimentLogPartialArgs = Partial<OtherExperimentLogFields> & Partial<InputField | InputsField>;
|
|
213
235
|
export type ExperimentLogFullArgs = Partial<Omit<OtherExperimentLogFields, "scores">> & Required<Pick<OtherExperimentLogFields, "scores">> & Partial<InputField | InputsField> & Partial<IdField>;
|
|
236
|
+
export type LogFeedbackFullArgs = IdField & Partial<Omit<OtherExperimentLogFields, "output" | "metrics" | "datasetRecordId"> & {
|
|
237
|
+
comment: string;
|
|
238
|
+
source: Source;
|
|
239
|
+
}>;
|
|
240
|
+
export type LogCommentFullArgs = IdField & {
|
|
241
|
+
created: string;
|
|
242
|
+
origin: {
|
|
243
|
+
id: string;
|
|
244
|
+
};
|
|
245
|
+
comment: {
|
|
246
|
+
text: string;
|
|
247
|
+
};
|
|
248
|
+
[AUDIT_SOURCE_FIELD]: Source;
|
|
249
|
+
[AUDIT_METADATA_FIELD]?: Record<string, unknown>;
|
|
250
|
+
} & Omit<ParentExperimentIds | ParentProjectLogIds, "kind">;
|
|
214
251
|
type ExperimentEvent = Partial<InputField> & Partial<OtherExperimentLogFields> & {
|
|
215
252
|
id: string;
|
|
216
|
-
span_id
|
|
217
|
-
root_span_id
|
|
253
|
+
span_id?: string;
|
|
254
|
+
root_span_id?: string;
|
|
218
255
|
project_id: string;
|
|
219
256
|
experiment_id: string;
|
|
220
257
|
[IS_MERGE_FIELD]: boolean;
|
|
@@ -222,6 +259,9 @@ type ExperimentEvent = Partial<InputField> & Partial<OtherExperimentLogFields> &
|
|
|
222
259
|
created: string;
|
|
223
260
|
span_parents: string[];
|
|
224
261
|
span_attributes: Record<string, unknown>;
|
|
262
|
+
[PARENT_ID_FIELD]: string;
|
|
263
|
+
[AUDIT_SOURCE_FIELD]: Source;
|
|
264
|
+
[AUDIT_METADATA_FIELD]?: Record<string, unknown>;
|
|
225
265
|
}>;
|
|
226
266
|
interface DatasetEvent {
|
|
227
267
|
inputs?: unknown;
|
|
@@ -236,7 +276,18 @@ type LoggingEvent = Omit<ExperimentEvent, "experiment_id"> & {
|
|
|
236
276
|
org_id: string;
|
|
237
277
|
log_id: "g";
|
|
238
278
|
};
|
|
239
|
-
type
|
|
279
|
+
export type CommentEvent = IdField & {
|
|
280
|
+
created: string;
|
|
281
|
+
origin: {
|
|
282
|
+
id: string;
|
|
283
|
+
};
|
|
284
|
+
comment: {
|
|
285
|
+
text: string;
|
|
286
|
+
};
|
|
287
|
+
[AUDIT_SOURCE_FIELD]: Source;
|
|
288
|
+
[AUDIT_METADATA_FIELD]?: Record<string, unknown>;
|
|
289
|
+
} & Omit<ParentExperimentIds | ParentProjectLogIds, "kind">;
|
|
290
|
+
type BackgroundLogEvent = ExperimentEvent | DatasetEvent | LoggingEvent | CommentEvent;
|
|
240
291
|
export interface DatasetRecord {
|
|
241
292
|
id: string;
|
|
242
293
|
input: any;
|
|
@@ -467,6 +518,7 @@ export declare class Experiment {
|
|
|
467
518
|
* See `Span.traced` for full details.
|
|
468
519
|
*/
|
|
469
520
|
traced<R>(callback: (span: Span) => R, args?: StartSpanArgs & SetCurrentArg): R;
|
|
521
|
+
private lazyParentIds;
|
|
470
522
|
/**
|
|
471
523
|
* Lower-level alternative to `traced`, which does not automatically end the span or mark it as current.
|
|
472
524
|
*
|
|
@@ -485,6 +537,18 @@ export declare class Experiment {
|
|
|
485
537
|
readonly summarizeScores?: boolean;
|
|
486
538
|
readonly comparisonExperimentId?: string;
|
|
487
539
|
}): Promise<ExperimentSummary>;
|
|
540
|
+
/**
|
|
541
|
+
* Log feedback to an event in the experiment. Feedback is used to save feedback scores, set an expected value, or add a comment.
|
|
542
|
+
*
|
|
543
|
+
* @param event
|
|
544
|
+
* @param event.id The id of the event to log feedback for. This is the `id` returned by `log` or accessible as the `id` field of a span.
|
|
545
|
+
* @param event.scores (Optional) a dictionary of numeric values (between 0 and 1) to log. These scores will be merged into the existing scores for the event.
|
|
546
|
+
* @param event.expected (Optional) the ground truth value (an arbitrary, JSON serializable object) that you'd compare to `output` to determine if your `output` value is correct or not.
|
|
547
|
+
* @param event.comment (Optional) an optional comment string to log about the event.
|
|
548
|
+
* @param event.metadata (Optional) a dictionary with additional data about the feedback. If you have a `user_id`, you can log it here and access it in the Braintrust UI.
|
|
549
|
+
* @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
|
|
550
|
+
*/
|
|
551
|
+
logFeedback(event: LogFeedbackFullArgs): void;
|
|
488
552
|
/**
|
|
489
553
|
* Flush any pending rows to the server.
|
|
490
554
|
*/
|
|
@@ -521,17 +585,21 @@ export declare class SpanImpl implements Span {
|
|
|
521
585
|
constructor(args: {
|
|
522
586
|
parentIds: Promise<ParentExperimentIds | ParentProjectLogIds>;
|
|
523
587
|
bgLogger: BackgroundLogger;
|
|
588
|
+
} & Omit<StartSpanArgs, "parentId"> & ({
|
|
524
589
|
parentSpanInfo?: {
|
|
525
590
|
span_id: string;
|
|
526
591
|
root_span_id: string;
|
|
527
592
|
};
|
|
528
|
-
}
|
|
593
|
+
} | {
|
|
594
|
+
parentId?: string;
|
|
595
|
+
}));
|
|
529
596
|
get id(): string;
|
|
530
597
|
get span_id(): string;
|
|
531
598
|
get root_span_id(): string;
|
|
532
599
|
log(event: ExperimentLogPartialArgs): void;
|
|
600
|
+
logFeedback(event: Omit<LogFeedbackFullArgs, "id">): void;
|
|
533
601
|
traced<R>(callback: (span: Span) => R, args?: StartSpanArgs & SetCurrentArg): R;
|
|
534
|
-
startSpan(args?: StartSpanArgs): Span;
|
|
602
|
+
startSpan(args?: Omit<StartSpanArgs, "parent_id">): Span;
|
|
535
603
|
end(args?: EndSpanArgs): number;
|
|
536
604
|
close(args?: EndSpanArgs): number;
|
|
537
605
|
}
|
package/dist/oai.d.ts
CHANGED
|
@@ -4,14 +4,19 @@ interface BetaLike {
|
|
|
4
4
|
stream: any;
|
|
5
5
|
};
|
|
6
6
|
};
|
|
7
|
+
embeddings: any;
|
|
7
8
|
}
|
|
8
9
|
interface ChatLike {
|
|
9
10
|
completions: any;
|
|
10
11
|
}
|
|
11
12
|
interface OpenAILike {
|
|
12
13
|
chat: ChatLike;
|
|
14
|
+
embeddings: any;
|
|
13
15
|
beta?: BetaLike;
|
|
14
16
|
}
|
|
17
|
+
declare global {
|
|
18
|
+
var __inherited_braintrust_wrap_openai: ((openai: any) => any) | undefined;
|
|
19
|
+
}
|
|
15
20
|
/**
|
|
16
21
|
* Wrap an `OpenAI` object (created with `new OpenAI(...)`) to add tracing. If Braintrust is
|
|
17
22
|
* not configured, this is a no-op
|