braintrust 0.0.145 → 0.0.147

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.
Binary file
@@ -1,4 +1,4 @@
1
- import { GitMetadataSettings, LogFeedbackFullArgs, BackgroundLogEvent, ExperimentEvent, ExperimentLogFullArgs, ExperimentLogPartialArgs, IdField, SpanType, RepoInfo, DEFAULT_IS_LEGACY_DATASET, TRANSACTION_ID_FIELD, TransactionId, SpanObjectTypeV2, DatasetRecord } from '@braintrust/core';
1
+ import { GitMetadataSettings, LogFeedbackFullArgs, ExperimentEvent, BackgroundLogEvent, ExperimentLogFullArgs, ExperimentLogPartialArgs, IdField, SpanType, RepoInfo, DEFAULT_IS_LEGACY_DATASET, TRANSACTION_ID_FIELD, TransactionId, SpanObjectTypeV2, DatasetRecord } from '@braintrust/core';
2
2
  import { PromptData, OpenAIMessage, Tools, AnyModelParam, Prompt as Prompt$1, PromptSessionEvent } from '@braintrust/core/typespecs';
3
3
  import { z } from 'zod';
4
4
 
@@ -201,7 +201,7 @@ declare class BraintrustState {
201
201
  resetLoginInfo(): void;
202
202
  copyLoginInfo(other: BraintrustState): void;
203
203
  serialize(): SerializedBraintrustState;
204
- static deserialize(serialized: unknown, opts?: BackgroundLoggerOpts): BraintrustState;
204
+ static deserialize(serialized: unknown, opts?: LoginOptions): BraintrustState;
205
205
  setFetch(fetch: typeof globalThis.fetch): void;
206
206
  login(loginParams: LoginOptions & {
207
207
  forceLogin?: boolean;
@@ -253,6 +253,18 @@ interface LogOptions<IsAsyncFlush> {
253
253
  computeMetadataArgs?: Record<string, any>;
254
254
  }
255
255
  type PromiseUnless<B, R> = B extends true ? R : Promise<Awaited<R>>;
256
+ /**
257
+ * Update a span using the output of `span.export()`. It is important that you only resume updating
258
+ * to a span once the original span has been fully written and flushed, since otherwise updates to
259
+ * the span may conflict with the original span.
260
+ *
261
+ * @param exported The output of `span.export()`.
262
+ * @param event The event data to update the span with. See `Experiment.log` for a full list of valid fields.
263
+ * @param state (optional) Login state to use. If not provided, the global state will be used.
264
+ */
265
+ declare function updateSpan({ exported, state, ...event }: {
266
+ exported: string;
267
+ } & Omit<Partial<ExperimentEvent>, "id"> & OptionalStateArg): void;
256
268
  interface ParentSpanIds {
257
269
  spanId: string;
258
270
  rootSpanId: string;
@@ -316,6 +328,13 @@ declare class Logger<IsAsyncFlush extends boolean> implements Exportable {
316
328
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
317
329
  */
318
330
  logFeedback(event: LogFeedbackFullArgs): void;
331
+ /**
332
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
333
+ * since otherwise updates to the span may conflict with the original span.
334
+ *
335
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
336
+ */
337
+ updateSpan(event: Omit<Partial<ExperimentEvent>, "id"> & Required<Pick<ExperimentEvent, "id">>): void;
319
338
  /**
320
339
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
321
340
  */
@@ -780,6 +799,13 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
780
799
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
781
800
  */
782
801
  logFeedback(event: LogFeedbackFullArgs): void;
802
+ /**
803
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
804
+ * since otherwise updates to the span may conflict with the original span.
805
+ *
806
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
807
+ */
808
+ updateSpan(event: Omit<Partial<ExperimentEvent>, "id"> & Required<Pick<ExperimentEvent, "id">>): void;
783
809
  /**
784
810
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
785
811
  */
@@ -1079,6 +1105,13 @@ declare class BraintrustStream {
1079
1105
  * @returns The underlying ReadableStream<BraintrustStreamChunk>.
1080
1106
  */
1081
1107
  toReadableStream(): ReadableStream<BraintrustStreamChunk>;
1108
+ /**
1109
+ * Returns an async iterator for the BraintrustStream.
1110
+ * This allows for easy consumption of the stream using a for-await...of loop.
1111
+ *
1112
+ * @returns An async iterator that yields BraintrustStreamChunk objects.
1113
+ */
1114
+ [Symbol.asyncIterator](): AsyncIterator<BraintrustStreamChunk>;
1082
1115
  /**
1083
1116
  * Get the final value of the stream. The final value is the concatenation of all
1084
1117
  * the chunks in the stream, deserialized into a string or JSON object, depending on
@@ -1116,7 +1149,7 @@ interface InvokeFunctionArgs<Input, Output, Stream extends boolean = false> {
1116
1149
  /**
1117
1150
  * The name of the project containing the function to invoke.
1118
1151
  */
1119
- project_name?: string;
1152
+ projectName?: string;
1120
1153
  /**
1121
1154
  * The slug of the function to invoke.
1122
1155
  */
@@ -1124,15 +1157,15 @@ interface InvokeFunctionArgs<Input, Output, Stream extends boolean = false> {
1124
1157
  /**
1125
1158
  * The name of the global function to invoke.
1126
1159
  */
1127
- global_function?: string;
1160
+ globalFunction?: string;
1128
1161
  /**
1129
1162
  * The ID of the prompt session to invoke the function from.
1130
1163
  */
1131
- prompt_session_id?: string;
1164
+ promptSessionId?: string;
1132
1165
  /**
1133
1166
  * The ID of the function in the prompt session to invoke.
1134
1167
  */
1135
- prompt_session_function_id?: string;
1168
+ promptSessionFunctionId?: string;
1136
1169
  /**
1137
1170
  * The version of the function to invoke.
1138
1171
  */
@@ -1215,4 +1248,4 @@ declare const LEGACY_CACHED_HEADER = "x-cached";
1215
1248
  declare const X_CACHED_HEADER = "x-bt-cached";
1216
1249
  declare function parseCachedHeader(value: string | null | undefined): number | undefined;
1217
1250
 
1218
- export { type AnyDataset, type BackgroundLoggerOpts, type BaseMetadata, BraintrustState, BraintrustStream, type BraintrustStreamChunk, type ChatPrompt, type CompiledPrompt, type CompiledPromptParams, type CompletionPrompt, type DataSummary, Dataset, type DatasetSummary, type DefaultMetadataType, type DefaultPromptArgs, type EndSpanArgs, type EvalCase, Experiment, type ExperimentSummary, type Exportable, type FullInitOptions, type FullLoginOptions, type InitOptions, type InvokeFunctionArgs, type InvokeReturn, LEGACY_CACHED_HEADER, type LogOptions, Logger, type LoginOptions, type MetricSummary, NOOP_SPAN, NoopSpan, type ObjectMetadata, type PromiseUnless, Prompt, ReadonlyExperiment, type ScoreSummary, type SerializedBraintrustState, type SetCurrentArg, type Span, SpanImpl, type StartSpanArgs, type WithTransactionId, X_CACHED_HEADER, _internalGetGlobalState, _internalSetInitialState, braintrustStreamChunkSchema, createFinalValuePassThroughStream, currentExperiment, currentLogger, currentSpan, devNullWritableStream, flush, getSpanParentObject, init, initDataset, initExperiment, initLogger, invoke, loadPrompt, log, login, loginToState, newId, parseCachedHeader, setFetch, startSpan, summarize, traceable, traced, withDataset, withExperiment, withLogger, wrapOpenAI, wrapOpenAIv4, wrapTraced };
1251
+ export { type AnyDataset, type BackgroundLoggerOpts, type BaseMetadata, BraintrustState, BraintrustStream, type BraintrustStreamChunk, type ChatPrompt, type CompiledPrompt, type CompiledPromptParams, type CompletionPrompt, type DataSummary, Dataset, type DatasetSummary, type DefaultMetadataType, type DefaultPromptArgs, type EndSpanArgs, type EvalCase, Experiment, type ExperimentSummary, type Exportable, type FullInitOptions, type FullLoginOptions, type InitOptions, type InvokeFunctionArgs, type InvokeReturn, LEGACY_CACHED_HEADER, type LogOptions, Logger, type LoginOptions, type MetricSummary, NOOP_SPAN, NoopSpan, type ObjectMetadata, type PromiseUnless, Prompt, ReadonlyExperiment, type ScoreSummary, type SerializedBraintrustState, type SetCurrentArg, type Span, SpanImpl, type StartSpanArgs, type WithTransactionId, X_CACHED_HEADER, _internalGetGlobalState, _internalSetInitialState, braintrustStreamChunkSchema, createFinalValuePassThroughStream, currentExperiment, currentLogger, currentSpan, devNullWritableStream, flush, getSpanParentObject, init, initDataset, initExperiment, initLogger, invoke, loadPrompt, log, login, loginToState, newId, parseCachedHeader, setFetch, startSpan, summarize, traceable, traced, updateSpan, withDataset, withExperiment, withLogger, wrapOpenAI, wrapOpenAIv4, wrapTraced };
package/dist/browser.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { GitMetadataSettings, LogFeedbackFullArgs, BackgroundLogEvent, ExperimentEvent, ExperimentLogFullArgs, ExperimentLogPartialArgs, IdField, SpanType, RepoInfo, DEFAULT_IS_LEGACY_DATASET, TRANSACTION_ID_FIELD, TransactionId, SpanObjectTypeV2, DatasetRecord } from '@braintrust/core';
1
+ import { GitMetadataSettings, LogFeedbackFullArgs, ExperimentEvent, BackgroundLogEvent, ExperimentLogFullArgs, ExperimentLogPartialArgs, IdField, SpanType, RepoInfo, DEFAULT_IS_LEGACY_DATASET, TRANSACTION_ID_FIELD, TransactionId, SpanObjectTypeV2, DatasetRecord } from '@braintrust/core';
2
2
  import { PromptData, OpenAIMessage, Tools, AnyModelParam, Prompt as Prompt$1, PromptSessionEvent } from '@braintrust/core/typespecs';
3
3
  import { z } from 'zod';
4
4
 
@@ -201,7 +201,7 @@ declare class BraintrustState {
201
201
  resetLoginInfo(): void;
202
202
  copyLoginInfo(other: BraintrustState): void;
203
203
  serialize(): SerializedBraintrustState;
204
- static deserialize(serialized: unknown, opts?: BackgroundLoggerOpts): BraintrustState;
204
+ static deserialize(serialized: unknown, opts?: LoginOptions): BraintrustState;
205
205
  setFetch(fetch: typeof globalThis.fetch): void;
206
206
  login(loginParams: LoginOptions & {
207
207
  forceLogin?: boolean;
@@ -253,6 +253,18 @@ interface LogOptions<IsAsyncFlush> {
253
253
  computeMetadataArgs?: Record<string, any>;
254
254
  }
255
255
  type PromiseUnless<B, R> = B extends true ? R : Promise<Awaited<R>>;
256
+ /**
257
+ * Update a span using the output of `span.export()`. It is important that you only resume updating
258
+ * to a span once the original span has been fully written and flushed, since otherwise updates to
259
+ * the span may conflict with the original span.
260
+ *
261
+ * @param exported The output of `span.export()`.
262
+ * @param event The event data to update the span with. See `Experiment.log` for a full list of valid fields.
263
+ * @param state (optional) Login state to use. If not provided, the global state will be used.
264
+ */
265
+ declare function updateSpan({ exported, state, ...event }: {
266
+ exported: string;
267
+ } & Omit<Partial<ExperimentEvent>, "id"> & OptionalStateArg): void;
256
268
  interface ParentSpanIds {
257
269
  spanId: string;
258
270
  rootSpanId: string;
@@ -316,6 +328,13 @@ declare class Logger<IsAsyncFlush extends boolean> implements Exportable {
316
328
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
317
329
  */
318
330
  logFeedback(event: LogFeedbackFullArgs): void;
331
+ /**
332
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
333
+ * since otherwise updates to the span may conflict with the original span.
334
+ *
335
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
336
+ */
337
+ updateSpan(event: Omit<Partial<ExperimentEvent>, "id"> & Required<Pick<ExperimentEvent, "id">>): void;
319
338
  /**
320
339
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
321
340
  */
@@ -780,6 +799,13 @@ declare class Experiment extends ObjectFetcher<ExperimentEvent> implements Expor
780
799
  * @param event.source (Optional) the source of the feedback. Must be one of "external" (default), "app", or "api".
781
800
  */
782
801
  logFeedback(event: LogFeedbackFullArgs): void;
802
+ /**
803
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
804
+ * since otherwise updates to the span may conflict with the original span.
805
+ *
806
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
807
+ */
808
+ updateSpan(event: Omit<Partial<ExperimentEvent>, "id"> & Required<Pick<ExperimentEvent, "id">>): void;
783
809
  /**
784
810
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
785
811
  */
@@ -1079,6 +1105,13 @@ declare class BraintrustStream {
1079
1105
  * @returns The underlying ReadableStream<BraintrustStreamChunk>.
1080
1106
  */
1081
1107
  toReadableStream(): ReadableStream<BraintrustStreamChunk>;
1108
+ /**
1109
+ * Returns an async iterator for the BraintrustStream.
1110
+ * This allows for easy consumption of the stream using a for-await...of loop.
1111
+ *
1112
+ * @returns An async iterator that yields BraintrustStreamChunk objects.
1113
+ */
1114
+ [Symbol.asyncIterator](): AsyncIterator<BraintrustStreamChunk>;
1082
1115
  /**
1083
1116
  * Get the final value of the stream. The final value is the concatenation of all
1084
1117
  * the chunks in the stream, deserialized into a string or JSON object, depending on
@@ -1116,7 +1149,7 @@ interface InvokeFunctionArgs<Input, Output, Stream extends boolean = false> {
1116
1149
  /**
1117
1150
  * The name of the project containing the function to invoke.
1118
1151
  */
1119
- project_name?: string;
1152
+ projectName?: string;
1120
1153
  /**
1121
1154
  * The slug of the function to invoke.
1122
1155
  */
@@ -1124,15 +1157,15 @@ interface InvokeFunctionArgs<Input, Output, Stream extends boolean = false> {
1124
1157
  /**
1125
1158
  * The name of the global function to invoke.
1126
1159
  */
1127
- global_function?: string;
1160
+ globalFunction?: string;
1128
1161
  /**
1129
1162
  * The ID of the prompt session to invoke the function from.
1130
1163
  */
1131
- prompt_session_id?: string;
1164
+ promptSessionId?: string;
1132
1165
  /**
1133
1166
  * The ID of the function in the prompt session to invoke.
1134
1167
  */
1135
- prompt_session_function_id?: string;
1168
+ promptSessionFunctionId?: string;
1136
1169
  /**
1137
1170
  * The version of the function to invoke.
1138
1171
  */
@@ -1215,4 +1248,4 @@ declare const LEGACY_CACHED_HEADER = "x-cached";
1215
1248
  declare const X_CACHED_HEADER = "x-bt-cached";
1216
1249
  declare function parseCachedHeader(value: string | null | undefined): number | undefined;
1217
1250
 
1218
- export { type AnyDataset, type BackgroundLoggerOpts, type BaseMetadata, BraintrustState, BraintrustStream, type BraintrustStreamChunk, type ChatPrompt, type CompiledPrompt, type CompiledPromptParams, type CompletionPrompt, type DataSummary, Dataset, type DatasetSummary, type DefaultMetadataType, type DefaultPromptArgs, type EndSpanArgs, type EvalCase, Experiment, type ExperimentSummary, type Exportable, type FullInitOptions, type FullLoginOptions, type InitOptions, type InvokeFunctionArgs, type InvokeReturn, LEGACY_CACHED_HEADER, type LogOptions, Logger, type LoginOptions, type MetricSummary, NOOP_SPAN, NoopSpan, type ObjectMetadata, type PromiseUnless, Prompt, ReadonlyExperiment, type ScoreSummary, type SerializedBraintrustState, type SetCurrentArg, type Span, SpanImpl, type StartSpanArgs, type WithTransactionId, X_CACHED_HEADER, _internalGetGlobalState, _internalSetInitialState, braintrustStreamChunkSchema, createFinalValuePassThroughStream, currentExperiment, currentLogger, currentSpan, devNullWritableStream, flush, getSpanParentObject, init, initDataset, initExperiment, initLogger, invoke, loadPrompt, log, login, loginToState, newId, parseCachedHeader, setFetch, startSpan, summarize, traceable, traced, withDataset, withExperiment, withLogger, wrapOpenAI, wrapOpenAIv4, wrapTraced };
1251
+ export { type AnyDataset, type BackgroundLoggerOpts, type BaseMetadata, BraintrustState, BraintrustStream, type BraintrustStreamChunk, type ChatPrompt, type CompiledPrompt, type CompiledPromptParams, type CompletionPrompt, type DataSummary, Dataset, type DatasetSummary, type DefaultMetadataType, type DefaultPromptArgs, type EndSpanArgs, type EvalCase, Experiment, type ExperimentSummary, type Exportable, type FullInitOptions, type FullLoginOptions, type InitOptions, type InvokeFunctionArgs, type InvokeReturn, LEGACY_CACHED_HEADER, type LogOptions, Logger, type LoginOptions, type MetricSummary, NOOP_SPAN, NoopSpan, type ObjectMetadata, type PromiseUnless, Prompt, ReadonlyExperiment, type ScoreSummary, type SerializedBraintrustState, type SetCurrentArg, type Span, SpanImpl, type StartSpanArgs, type WithTransactionId, X_CACHED_HEADER, _internalGetGlobalState, _internalSetInitialState, braintrustStreamChunkSchema, createFinalValuePassThroughStream, currentExperiment, currentLogger, currentSpan, devNullWritableStream, flush, getSpanParentObject, init, initDataset, initExperiment, initLogger, invoke, loadPrompt, log, login, loginToState, newId, parseCachedHeader, setFetch, startSpan, summarize, traceable, traced, updateSpan, withDataset, withExperiment, withLogger, wrapOpenAI, wrapOpenAIv4, wrapTraced };
package/dist/browser.js CHANGED
@@ -68,6 +68,7 @@ __export(browser_exports, {
68
68
  summarize: () => summarize,
69
69
  traceable: () => traceable,
70
70
  traced: () => traced,
71
+ updateSpan: () => updateSpan,
71
72
  withDataset: () => withDataset,
72
73
  withExperiment: () => withExperiment,
73
74
  withLogger: () => withLogger,
@@ -194,6 +195,33 @@ var BraintrustStream = class _BraintrustStream {
194
195
  toReadableStream() {
195
196
  return this.stream;
196
197
  }
198
+ /**
199
+ * Returns an async iterator for the BraintrustStream.
200
+ * This allows for easy consumption of the stream using a for-await...of loop.
201
+ *
202
+ * @returns An async iterator that yields BraintrustStreamChunk objects.
203
+ */
204
+ [Symbol.asyncIterator]() {
205
+ const reader = this.stream.getReader();
206
+ return {
207
+ async next() {
208
+ const { done, value } = await reader.read();
209
+ if (done) {
210
+ reader.releaseLock();
211
+ return { done: true, value: void 0 };
212
+ }
213
+ return { done: false, value };
214
+ },
215
+ async return() {
216
+ reader.releaseLock();
217
+ return { done: true, value: void 0 };
218
+ },
219
+ async throw(error) {
220
+ reader.releaseLock();
221
+ throw error;
222
+ }
223
+ };
224
+ }
197
225
  /**
198
226
  * Get the final value of the stream. The final value is the concatenation of all
199
227
  * the chunks in the stream, deserialized into a string or JSON object, depending on
@@ -482,8 +510,10 @@ var BraintrustState = class _BraintrustState {
482
510
  state.apiConn().set_token(state.loginToken);
483
511
  state.apiConn().make_long_lived();
484
512
  state.appConn().set_token(state.loginToken);
485
- state.proxyConn().make_long_lived();
486
- state.proxyConn().set_token(state.loginToken);
513
+ if (state.proxyUrl) {
514
+ state.proxyConn().make_long_lived();
515
+ state.proxyConn().set_token(state.loginToken);
516
+ }
487
517
  state.loggedIn = true;
488
518
  state.loginReplaceApiConn(state.apiConn());
489
519
  return state;
@@ -523,6 +553,9 @@ var BraintrustState = class _BraintrustState {
523
553
  return this._apiConn;
524
554
  }
525
555
  proxyConn() {
556
+ if (!this.proxyUrl) {
557
+ return this.apiConn();
558
+ }
526
559
  if (!this._proxyConn) {
527
560
  if (!this.proxyUrl) {
528
561
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
@@ -740,6 +773,41 @@ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
740
773
  state.bgLogger().log([record]);
741
774
  }
742
775
  }
776
+ function updateSpanImpl(state, parentObjectType, parentObjectId, id, event) {
777
+ const updateEvent = validateAndSanitizeExperimentLogPartialArgs({
778
+ id,
779
+ ...event
780
+ });
781
+ const parentIds = async () => new import_core.SpanComponentsV2({
782
+ objectType: parentObjectType,
783
+ objectId: await parentObjectId.get()
784
+ }).objectIdFields();
785
+ const record = new LazyValue(async () => ({
786
+ id,
787
+ ...updateEvent,
788
+ ...await parentIds(),
789
+ [import_core.IS_MERGE_FIELD]: true
790
+ }));
791
+ state.bgLogger().log([record]);
792
+ }
793
+ function updateSpan({
794
+ exported,
795
+ state,
796
+ ...event
797
+ }) {
798
+ const resolvedState = state ?? _globalState;
799
+ const components = import_core.SpanComponentsV2.fromStr(exported);
800
+ if (!components.rowIds?.rowId) {
801
+ throw new Error("Exported span must have a row id");
802
+ }
803
+ updateSpanImpl(
804
+ resolvedState,
805
+ components.objectType,
806
+ new LazyValue(spanComponentsToObjectIdLambda(resolvedState, components)),
807
+ components.rowIds?.rowId,
808
+ event
809
+ );
810
+ }
743
811
  function spanComponentsToObjectIdLambda(state, components) {
744
812
  if (components.objectId) {
745
813
  const ret = components.objectId;
@@ -944,6 +1012,25 @@ var Logger = class {
944
1012
  logFeedback(event) {
945
1013
  logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
946
1014
  }
1015
+ /**
1016
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
1017
+ * since otherwise updates to the span may conflict with the original span.
1018
+ *
1019
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
1020
+ */
1021
+ updateSpan(event) {
1022
+ const { id, ...eventRest } = event;
1023
+ if (!id) {
1024
+ throw new Error("Span id is required to update a span");
1025
+ }
1026
+ updateSpanImpl(
1027
+ this.state,
1028
+ this.parentObjectType(),
1029
+ this.lazyId,
1030
+ id,
1031
+ eventRest
1032
+ );
1033
+ }
947
1034
  /**
948
1035
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
949
1036
  */
@@ -1663,7 +1750,7 @@ async function loadPrompt({
1663
1750
  throw new Error("Must specify slug");
1664
1751
  }
1665
1752
  const state = stateArg ?? _globalState;
1666
- state.login({
1753
+ await state.login({
1667
1754
  orgName,
1668
1755
  apiKey,
1669
1756
  appUrl,
@@ -1750,7 +1837,9 @@ async function loginToState(options = {}) {
1750
1837
  }
1751
1838
  conn.make_long_lived();
1752
1839
  state.appConn().set_token(apiKey);
1753
- state.proxyConn().set_token(apiKey);
1840
+ if (state.proxyUrl) {
1841
+ state.proxyConn().set_token(apiKey);
1842
+ }
1754
1843
  state.loginToken = conn.token;
1755
1844
  state.loggedIn = true;
1756
1845
  state.loginReplaceApiConn(conn);
@@ -2281,6 +2370,25 @@ var Experiment = class extends ObjectFetcher {
2281
2370
  logFeedback(event) {
2282
2371
  logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
2283
2372
  }
2373
+ /**
2374
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
2375
+ * since otherwise updates to the span may conflict with the original span.
2376
+ *
2377
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
2378
+ */
2379
+ updateSpan(event) {
2380
+ const { id, ...eventRest } = event;
2381
+ if (!id) {
2382
+ throw new Error("Span id is required to update a span");
2383
+ }
2384
+ updateSpanImpl(
2385
+ this.state,
2386
+ this.parentObjectType(),
2387
+ this.lazyId,
2388
+ id,
2389
+ eventRest
2390
+ );
2391
+ }
2284
2392
  /**
2285
2393
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
2286
2394
  */
@@ -2896,7 +3004,14 @@ async function invoke(args) {
2896
3004
  forceLogin
2897
3005
  });
2898
3006
  const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
2899
- const functionId = import_typespecs3.functionIdSchema.safeParse(functionIdArgs);
3007
+ const functionId = import_typespecs3.functionIdSchema.safeParse({
3008
+ project_name: functionIdArgs.projectName,
3009
+ slug: functionIdArgs.slug,
3010
+ global_function: functionIdArgs.globalFunction,
3011
+ prompt_session_id: functionIdArgs.promptSessionId,
3012
+ prompt_session_function_id: functionIdArgs.promptSessionFunctionId,
3013
+ version: functionIdArgs.version
3014
+ });
2900
3015
  if (!functionId.success) {
2901
3016
  throw new Error(
2902
3017
  `Invalid function ID arguments: ${functionId.error.message}`
@@ -2906,8 +3021,7 @@ async function invoke(args) {
2906
3021
  ...functionId.data,
2907
3022
  input,
2908
3023
  parent,
2909
- stream,
2910
- api_version: import_typespecs3.INVOKE_API_VERSION
3024
+ stream
2911
3025
  };
2912
3026
  const resp = await state.proxyConn().post(`function/invoke`, request, {
2913
3027
  headers: {
@@ -3319,6 +3433,7 @@ configureBrowser();
3319
3433
  summarize,
3320
3434
  traceable,
3321
3435
  traced,
3436
+ updateSpan,
3322
3437
  withDataset,
3323
3438
  withExperiment,
3324
3439
  withLogger,
package/dist/browser.mjs CHANGED
@@ -141,6 +141,33 @@ var BraintrustStream = class _BraintrustStream {
141
141
  toReadableStream() {
142
142
  return this.stream;
143
143
  }
144
+ /**
145
+ * Returns an async iterator for the BraintrustStream.
146
+ * This allows for easy consumption of the stream using a for-await...of loop.
147
+ *
148
+ * @returns An async iterator that yields BraintrustStreamChunk objects.
149
+ */
150
+ [Symbol.asyncIterator]() {
151
+ const reader = this.stream.getReader();
152
+ return {
153
+ async next() {
154
+ const { done, value } = await reader.read();
155
+ if (done) {
156
+ reader.releaseLock();
157
+ return { done: true, value: void 0 };
158
+ }
159
+ return { done: false, value };
160
+ },
161
+ async return() {
162
+ reader.releaseLock();
163
+ return { done: true, value: void 0 };
164
+ },
165
+ async throw(error) {
166
+ reader.releaseLock();
167
+ throw error;
168
+ }
169
+ };
170
+ }
144
171
  /**
145
172
  * Get the final value of the stream. The final value is the concatenation of all
146
173
  * the chunks in the stream, deserialized into a string or JSON object, depending on
@@ -429,8 +456,10 @@ var BraintrustState = class _BraintrustState {
429
456
  state.apiConn().set_token(state.loginToken);
430
457
  state.apiConn().make_long_lived();
431
458
  state.appConn().set_token(state.loginToken);
432
- state.proxyConn().make_long_lived();
433
- state.proxyConn().set_token(state.loginToken);
459
+ if (state.proxyUrl) {
460
+ state.proxyConn().make_long_lived();
461
+ state.proxyConn().set_token(state.loginToken);
462
+ }
434
463
  state.loggedIn = true;
435
464
  state.loginReplaceApiConn(state.apiConn());
436
465
  return state;
@@ -470,6 +499,9 @@ var BraintrustState = class _BraintrustState {
470
499
  return this._apiConn;
471
500
  }
472
501
  proxyConn() {
502
+ if (!this.proxyUrl) {
503
+ return this.apiConn();
504
+ }
473
505
  if (!this._proxyConn) {
474
506
  if (!this.proxyUrl) {
475
507
  throw new Error("Must initialize proxyUrl before requesting proxyConn");
@@ -687,6 +719,41 @@ function logFeedbackImpl(state, parentObjectType, parentObjectId, {
687
719
  state.bgLogger().log([record]);
688
720
  }
689
721
  }
722
+ function updateSpanImpl(state, parentObjectType, parentObjectId, id, event) {
723
+ const updateEvent = validateAndSanitizeExperimentLogPartialArgs({
724
+ id,
725
+ ...event
726
+ });
727
+ const parentIds = async () => new SpanComponentsV2({
728
+ objectType: parentObjectType,
729
+ objectId: await parentObjectId.get()
730
+ }).objectIdFields();
731
+ const record = new LazyValue(async () => ({
732
+ id,
733
+ ...updateEvent,
734
+ ...await parentIds(),
735
+ [IS_MERGE_FIELD]: true
736
+ }));
737
+ state.bgLogger().log([record]);
738
+ }
739
+ function updateSpan({
740
+ exported,
741
+ state,
742
+ ...event
743
+ }) {
744
+ const resolvedState = state ?? _globalState;
745
+ const components = SpanComponentsV2.fromStr(exported);
746
+ if (!components.rowIds?.rowId) {
747
+ throw new Error("Exported span must have a row id");
748
+ }
749
+ updateSpanImpl(
750
+ resolvedState,
751
+ components.objectType,
752
+ new LazyValue(spanComponentsToObjectIdLambda(resolvedState, components)),
753
+ components.rowIds?.rowId,
754
+ event
755
+ );
756
+ }
690
757
  function spanComponentsToObjectIdLambda(state, components) {
691
758
  if (components.objectId) {
692
759
  const ret = components.objectId;
@@ -891,6 +958,25 @@ var Logger = class {
891
958
  logFeedback(event) {
892
959
  logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
893
960
  }
961
+ /**
962
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
963
+ * since otherwise updates to the span may conflict with the original span.
964
+ *
965
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
966
+ */
967
+ updateSpan(event) {
968
+ const { id, ...eventRest } = event;
969
+ if (!id) {
970
+ throw new Error("Span id is required to update a span");
971
+ }
972
+ updateSpanImpl(
973
+ this.state,
974
+ this.parentObjectType(),
975
+ this.lazyId,
976
+ id,
977
+ eventRest
978
+ );
979
+ }
894
980
  /**
895
981
  * Return a serialized representation of the logger that can be used to start subspans in other places. See `Span.start_span` for more details.
896
982
  */
@@ -1610,7 +1696,7 @@ async function loadPrompt({
1610
1696
  throw new Error("Must specify slug");
1611
1697
  }
1612
1698
  const state = stateArg ?? _globalState;
1613
- state.login({
1699
+ await state.login({
1614
1700
  orgName,
1615
1701
  apiKey,
1616
1702
  appUrl,
@@ -1697,7 +1783,9 @@ async function loginToState(options = {}) {
1697
1783
  }
1698
1784
  conn.make_long_lived();
1699
1785
  state.appConn().set_token(apiKey);
1700
- state.proxyConn().set_token(apiKey);
1786
+ if (state.proxyUrl) {
1787
+ state.proxyConn().set_token(apiKey);
1788
+ }
1701
1789
  state.loginToken = conn.token;
1702
1790
  state.loggedIn = true;
1703
1791
  state.loginReplaceApiConn(conn);
@@ -2228,6 +2316,25 @@ var Experiment = class extends ObjectFetcher {
2228
2316
  logFeedback(event) {
2229
2317
  logFeedbackImpl(this.state, this.parentObjectType(), this.lazyId, event);
2230
2318
  }
2319
+ /**
2320
+ * Update a span in the experiment using its id. It is important that you only update a span once the original span has been fully written and flushed,
2321
+ * since otherwise updates to the span may conflict with the original span.
2322
+ *
2323
+ * @param event The event data to update the span with. Must include `id`. See `Experiment.log` for a full list of valid fields.
2324
+ */
2325
+ updateSpan(event) {
2326
+ const { id, ...eventRest } = event;
2327
+ if (!id) {
2328
+ throw new Error("Span id is required to update a span");
2329
+ }
2330
+ updateSpanImpl(
2331
+ this.state,
2332
+ this.parentObjectType(),
2333
+ this.lazyId,
2334
+ id,
2335
+ eventRest
2336
+ );
2337
+ }
2231
2338
  /**
2232
2339
  * Return a serialized representation of the experiment that can be used to start subspans in other places. See `Span.start_span` for more details.
2233
2340
  */
@@ -2821,7 +2928,6 @@ function configureBrowser() {
2821
2928
 
2822
2929
  // src/functions/invoke.ts
2823
2930
  import {
2824
- INVOKE_API_VERSION,
2825
2931
  functionIdSchema
2826
2932
  } from "@braintrust/core/typespecs";
2827
2933
  async function invoke(args) {
@@ -2846,7 +2952,14 @@ async function invoke(args) {
2846
2952
  forceLogin
2847
2953
  });
2848
2954
  const parent = parentArg ? typeof parentArg === "string" ? parentArg : await parentArg.export() : await getSpanParentObject().export();
2849
- const functionId = functionIdSchema.safeParse(functionIdArgs);
2955
+ const functionId = functionIdSchema.safeParse({
2956
+ project_name: functionIdArgs.projectName,
2957
+ slug: functionIdArgs.slug,
2958
+ global_function: functionIdArgs.globalFunction,
2959
+ prompt_session_id: functionIdArgs.promptSessionId,
2960
+ prompt_session_function_id: functionIdArgs.promptSessionFunctionId,
2961
+ version: functionIdArgs.version
2962
+ });
2850
2963
  if (!functionId.success) {
2851
2964
  throw new Error(
2852
2965
  `Invalid function ID arguments: ${functionId.error.message}`
@@ -2856,8 +2969,7 @@ async function invoke(args) {
2856
2969
  ...functionId.data,
2857
2970
  input,
2858
2971
  parent,
2859
- stream,
2860
- api_version: INVOKE_API_VERSION
2972
+ stream
2861
2973
  };
2862
2974
  const resp = await state.proxyConn().post(`function/invoke`, request, {
2863
2975
  headers: {
@@ -3268,6 +3380,7 @@ export {
3268
3380
  summarize,
3269
3381
  traceable,
3270
3382
  traced,
3383
+ updateSpan,
3271
3384
  withDataset,
3272
3385
  withExperiment,
3273
3386
  withLogger,