braintrust 0.0.180 → 0.0.182
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.d.mts +32 -1
- package/dist/browser.d.ts +32 -1
- package/dist/browser.js +81 -66
- package/dist/browser.mjs +81 -66
- package/dist/cli.js +23 -19
- package/dist/index.d.mts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +81 -66
- package/dist/index.mjs +81 -66
- package/package.json +2 -2
package/dist/browser.d.mts
CHANGED
|
@@ -521,6 +521,32 @@ declare class Attachment {
|
|
|
521
521
|
private initUploader;
|
|
522
522
|
private initData;
|
|
523
523
|
}
|
|
524
|
+
declare const attachmentMetadataSchema: z.ZodObject<{
|
|
525
|
+
downloadUrl: z.ZodString;
|
|
526
|
+
status: z.ZodObject<{
|
|
527
|
+
upload_status: z.ZodEnum<["uploading", "done", "error"]>;
|
|
528
|
+
error_message: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
529
|
+
}, "strip", z.ZodTypeAny, {
|
|
530
|
+
upload_status: "error" | "done" | "uploading";
|
|
531
|
+
error_message?: string | undefined;
|
|
532
|
+
}, {
|
|
533
|
+
upload_status: "error" | "done" | "uploading";
|
|
534
|
+
error_message?: string | null | undefined;
|
|
535
|
+
}>;
|
|
536
|
+
}, "strip", z.ZodTypeAny, {
|
|
537
|
+
status: {
|
|
538
|
+
upload_status: "error" | "done" | "uploading";
|
|
539
|
+
error_message?: string | undefined;
|
|
540
|
+
};
|
|
541
|
+
downloadUrl: string;
|
|
542
|
+
}, {
|
|
543
|
+
status: {
|
|
544
|
+
upload_status: "error" | "done" | "uploading";
|
|
545
|
+
error_message?: string | null | undefined;
|
|
546
|
+
};
|
|
547
|
+
downloadUrl: string;
|
|
548
|
+
}>;
|
|
549
|
+
type AttachmentMetadata = z.infer<typeof attachmentMetadataSchema>;
|
|
524
550
|
/**
|
|
525
551
|
* A readonly alternative to `Attachment`, which can be used for fetching
|
|
526
552
|
* already-uploaded Attachments.
|
|
@@ -546,13 +572,17 @@ declare class ReadonlyAttachment {
|
|
|
546
572
|
* contents from the object store on first access.
|
|
547
573
|
*/
|
|
548
574
|
data(): Promise<Blob>;
|
|
575
|
+
/**
|
|
576
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
577
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
578
|
+
*/
|
|
579
|
+
metadata(): Promise<AttachmentMetadata>;
|
|
549
580
|
/**
|
|
550
581
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
551
582
|
* in case it changes over time.
|
|
552
583
|
*/
|
|
553
584
|
status(): Promise<AttachmentStatus>;
|
|
554
585
|
private initDownloader;
|
|
555
|
-
private fetchMetadata;
|
|
556
586
|
}
|
|
557
587
|
/**
|
|
558
588
|
* Update a span using the output of `span.export()`. It is important that you only resume updating
|
|
@@ -1815,6 +1845,7 @@ interface ChatLike {
|
|
|
1815
1845
|
interface OpenAILike {
|
|
1816
1846
|
chat: ChatLike;
|
|
1817
1847
|
embeddings: any;
|
|
1848
|
+
moderations: any;
|
|
1818
1849
|
beta?: BetaLike;
|
|
1819
1850
|
}
|
|
1820
1851
|
declare global {
|
package/dist/browser.d.ts
CHANGED
|
@@ -521,6 +521,32 @@ declare class Attachment {
|
|
|
521
521
|
private initUploader;
|
|
522
522
|
private initData;
|
|
523
523
|
}
|
|
524
|
+
declare const attachmentMetadataSchema: z.ZodObject<{
|
|
525
|
+
downloadUrl: z.ZodString;
|
|
526
|
+
status: z.ZodObject<{
|
|
527
|
+
upload_status: z.ZodEnum<["uploading", "done", "error"]>;
|
|
528
|
+
error_message: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
529
|
+
}, "strip", z.ZodTypeAny, {
|
|
530
|
+
upload_status: "error" | "done" | "uploading";
|
|
531
|
+
error_message?: string | undefined;
|
|
532
|
+
}, {
|
|
533
|
+
upload_status: "error" | "done" | "uploading";
|
|
534
|
+
error_message?: string | null | undefined;
|
|
535
|
+
}>;
|
|
536
|
+
}, "strip", z.ZodTypeAny, {
|
|
537
|
+
status: {
|
|
538
|
+
upload_status: "error" | "done" | "uploading";
|
|
539
|
+
error_message?: string | undefined;
|
|
540
|
+
};
|
|
541
|
+
downloadUrl: string;
|
|
542
|
+
}, {
|
|
543
|
+
status: {
|
|
544
|
+
upload_status: "error" | "done" | "uploading";
|
|
545
|
+
error_message?: string | null | undefined;
|
|
546
|
+
};
|
|
547
|
+
downloadUrl: string;
|
|
548
|
+
}>;
|
|
549
|
+
type AttachmentMetadata = z.infer<typeof attachmentMetadataSchema>;
|
|
524
550
|
/**
|
|
525
551
|
* A readonly alternative to `Attachment`, which can be used for fetching
|
|
526
552
|
* already-uploaded Attachments.
|
|
@@ -546,13 +572,17 @@ declare class ReadonlyAttachment {
|
|
|
546
572
|
* contents from the object store on first access.
|
|
547
573
|
*/
|
|
548
574
|
data(): Promise<Blob>;
|
|
575
|
+
/**
|
|
576
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
577
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
578
|
+
*/
|
|
579
|
+
metadata(): Promise<AttachmentMetadata>;
|
|
549
580
|
/**
|
|
550
581
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
551
582
|
* in case it changes over time.
|
|
552
583
|
*/
|
|
553
584
|
status(): Promise<AttachmentStatus>;
|
|
554
585
|
private initDownloader;
|
|
555
|
-
private fetchMetadata;
|
|
556
586
|
}
|
|
557
587
|
/**
|
|
558
588
|
* Update a span using the output of `span.export()`. It is important that you only resume updating
|
|
@@ -1815,6 +1845,7 @@ interface ChatLike {
|
|
|
1815
1845
|
interface OpenAILike {
|
|
1816
1846
|
chat: ChatLike;
|
|
1817
1847
|
embeddings: any;
|
|
1848
|
+
moderations: any;
|
|
1818
1849
|
beta?: BetaLike;
|
|
1819
1850
|
}
|
|
1820
1851
|
declare global {
|
package/dist/browser.js
CHANGED
|
@@ -1189,16 +1189,35 @@ var ReadonlyAttachment = class {
|
|
|
1189
1189
|
async data() {
|
|
1190
1190
|
return this._data.get();
|
|
1191
1191
|
}
|
|
1192
|
+
/**
|
|
1193
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
1194
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
1195
|
+
*/
|
|
1196
|
+
async metadata() {
|
|
1197
|
+
const state = this.state ?? _globalState;
|
|
1198
|
+
await state.login({});
|
|
1199
|
+
const resp = await state.apiConn().get("/attachment", {
|
|
1200
|
+
key: this.reference.key,
|
|
1201
|
+
filename: this.reference.filename,
|
|
1202
|
+
content_type: this.reference.content_type,
|
|
1203
|
+
org_id: state.orgId || ""
|
|
1204
|
+
});
|
|
1205
|
+
if (!resp.ok) {
|
|
1206
|
+
const errorStr = JSON.stringify(resp);
|
|
1207
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1208
|
+
}
|
|
1209
|
+
return attachmentMetadataSchema.parse(await resp.json());
|
|
1210
|
+
}
|
|
1192
1211
|
/**
|
|
1193
1212
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
1194
1213
|
* in case it changes over time.
|
|
1195
1214
|
*/
|
|
1196
1215
|
async status() {
|
|
1197
|
-
return (await this.
|
|
1216
|
+
return (await this.metadata()).status;
|
|
1198
1217
|
}
|
|
1199
1218
|
initDownloader() {
|
|
1200
1219
|
const download = async () => {
|
|
1201
|
-
const { downloadUrl, status } = await this.
|
|
1220
|
+
const { downloadUrl, status } = await this.metadata();
|
|
1202
1221
|
if (status.upload_status !== "done") {
|
|
1203
1222
|
throw new Error(
|
|
1204
1223
|
`Expected attachment status "done", got "${status.upload_status}"`
|
|
@@ -1213,21 +1232,6 @@ var ReadonlyAttachment = class {
|
|
|
1213
1232
|
};
|
|
1214
1233
|
return new LazyValue(download);
|
|
1215
1234
|
}
|
|
1216
|
-
async fetchMetadata() {
|
|
1217
|
-
const state = this.state ?? _globalState;
|
|
1218
|
-
await state.login({});
|
|
1219
|
-
const resp = await state.apiConn().get("/attachment", {
|
|
1220
|
-
key: this.reference.key,
|
|
1221
|
-
filename: this.reference.filename,
|
|
1222
|
-
content_type: this.reference.content_type,
|
|
1223
|
-
org_id: state.orgId || ""
|
|
1224
|
-
});
|
|
1225
|
-
if (!resp.ok) {
|
|
1226
|
-
const errorStr = JSON.stringify(resp);
|
|
1227
|
-
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1228
|
-
}
|
|
1229
|
-
return attachmentMetadataSchema.parse(await resp.json());
|
|
1230
|
-
}
|
|
1231
1235
|
};
|
|
1232
1236
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
1233
1237
|
id,
|
|
@@ -3986,16 +3990,11 @@ function wrapOpenAI(openai) {
|
|
|
3986
3990
|
}
|
|
3987
3991
|
globalThis.__inherited_braintrust_wrap_openai = wrapOpenAI;
|
|
3988
3992
|
function wrapOpenAIv4(openai) {
|
|
3989
|
-
|
|
3990
|
-
|
|
3991
|
-
|
|
3992
|
-
|
|
3993
|
-
|
|
3994
|
-
}
|
|
3995
|
-
return baseVal;
|
|
3996
|
-
}
|
|
3997
|
-
});
|
|
3998
|
-
let chatProxy = new Proxy(openai.chat, {
|
|
3993
|
+
const completionProxy = createEndpointProxy(
|
|
3994
|
+
openai.chat.completions,
|
|
3995
|
+
wrapChatCompletion
|
|
3996
|
+
);
|
|
3997
|
+
const chatProxy = new Proxy(openai.chat, {
|
|
3999
3998
|
get(target, name, receiver) {
|
|
4000
3999
|
if (name === "completions") {
|
|
4001
4000
|
return completionProxy;
|
|
@@ -4003,18 +4002,11 @@ function wrapOpenAIv4(openai) {
|
|
|
4003
4002
|
return Reflect.get(target, name, receiver);
|
|
4004
4003
|
}
|
|
4005
4004
|
});
|
|
4006
|
-
|
|
4007
|
-
|
|
4008
|
-
const baseVal = Reflect.get(target, name, receiver);
|
|
4009
|
-
if (name === "create") {
|
|
4010
|
-
return wrapEmbeddings(baseVal.bind(target));
|
|
4011
|
-
}
|
|
4012
|
-
return baseVal;
|
|
4013
|
-
}
|
|
4014
|
-
});
|
|
4005
|
+
const embeddingProxy = createEndpointProxy(openai.embeddings, wrapEmbeddings);
|
|
4006
|
+
const moderationProxy = createEndpointProxy(openai.moderations, wrapModerations);
|
|
4015
4007
|
let betaProxy;
|
|
4016
4008
|
if (openai.beta?.chat?.completions?.stream) {
|
|
4017
|
-
|
|
4009
|
+
const betaChatCompletionProxy = new Proxy(openai?.beta?.chat.completions, {
|
|
4018
4010
|
get(target, name, receiver) {
|
|
4019
4011
|
const baseVal = Reflect.get(target, name, receiver);
|
|
4020
4012
|
if (name === "parse") {
|
|
@@ -4025,7 +4017,7 @@ function wrapOpenAIv4(openai) {
|
|
|
4025
4017
|
return baseVal;
|
|
4026
4018
|
}
|
|
4027
4019
|
});
|
|
4028
|
-
|
|
4020
|
+
const betaChatProxy = new Proxy(openai.beta.chat, {
|
|
4029
4021
|
get(target, name, receiver) {
|
|
4030
4022
|
if (name === "completions") {
|
|
4031
4023
|
return betaChatCompletionProxy;
|
|
@@ -4042,7 +4034,7 @@ function wrapOpenAIv4(openai) {
|
|
|
4042
4034
|
}
|
|
4043
4035
|
});
|
|
4044
4036
|
}
|
|
4045
|
-
|
|
4037
|
+
return new Proxy(openai, {
|
|
4046
4038
|
get(target, name, receiver) {
|
|
4047
4039
|
if (name === "chat") {
|
|
4048
4040
|
return chatProxy;
|
|
@@ -4050,13 +4042,15 @@ function wrapOpenAIv4(openai) {
|
|
|
4050
4042
|
if (name === "embeddings") {
|
|
4051
4043
|
return embeddingProxy;
|
|
4052
4044
|
}
|
|
4045
|
+
if (name === "moderations") {
|
|
4046
|
+
return moderationProxy;
|
|
4047
|
+
}
|
|
4053
4048
|
if (name === "beta" && betaProxy) {
|
|
4054
4049
|
return betaProxy;
|
|
4055
4050
|
}
|
|
4056
4051
|
return Reflect.get(target, name, receiver);
|
|
4057
4052
|
}
|
|
4058
4053
|
});
|
|
4059
|
-
return proxy;
|
|
4060
4054
|
}
|
|
4061
4055
|
function logCompletionResponse(startTime, response, span) {
|
|
4062
4056
|
span.log({
|
|
@@ -4205,7 +4199,7 @@ function wrapChatCompletion(completion) {
|
|
|
4205
4199
|
}
|
|
4206
4200
|
};
|
|
4207
4201
|
}
|
|
4208
|
-
function
|
|
4202
|
+
function parseBaseParams(allParams, inputField) {
|
|
4209
4203
|
const { span_info, ...params } = allParams;
|
|
4210
4204
|
const { metadata: spanInfoMetadata, ...spanInfoRest } = span_info ?? {};
|
|
4211
4205
|
let ret = {
|
|
@@ -4214,10 +4208,12 @@ function parseChatCompletionParams(allParams) {
|
|
|
4214
4208
|
metadata: spanInfoMetadata
|
|
4215
4209
|
}
|
|
4216
4210
|
};
|
|
4217
|
-
const
|
|
4218
|
-
|
|
4211
|
+
const input = params[inputField];
|
|
4212
|
+
const paramsRest = { ...params };
|
|
4213
|
+
delete paramsRest[inputField];
|
|
4214
|
+
return (0, import_core3.mergeDicts)(ret, { event: { input, metadata: paramsRest } });
|
|
4219
4215
|
}
|
|
4220
|
-
function
|
|
4216
|
+
function createApiWrapper(name, create, processResponse, parseParams) {
|
|
4221
4217
|
return async (allParams, options) => {
|
|
4222
4218
|
const { span_info: _, ...params } = allParams;
|
|
4223
4219
|
return traced(
|
|
@@ -4227,42 +4223,61 @@ function wrapEmbeddings(create) {
|
|
|
4227
4223
|
options
|
|
4228
4224
|
).withResponse();
|
|
4229
4225
|
logHeaders(response, span);
|
|
4230
|
-
|
|
4231
|
-
span.log({
|
|
4232
|
-
// TODO: Add a flag to control whether to log the full embedding vector,
|
|
4233
|
-
// possibly w/ JSON compression.
|
|
4234
|
-
output: { embedding_length },
|
|
4235
|
-
metrics: {
|
|
4236
|
-
tokens: result.usage?.total_tokens,
|
|
4237
|
-
prompt_tokens: result.usage?.prompt_tokens
|
|
4238
|
-
}
|
|
4239
|
-
});
|
|
4226
|
+
processResponse(result, span);
|
|
4240
4227
|
return result;
|
|
4241
4228
|
},
|
|
4242
4229
|
(0, import_core3.mergeDicts)(
|
|
4243
4230
|
{
|
|
4244
|
-
name
|
|
4231
|
+
name,
|
|
4245
4232
|
spanAttributes: {
|
|
4246
4233
|
type: import_core2.SpanTypeAttribute.LLM
|
|
4247
4234
|
}
|
|
4248
4235
|
},
|
|
4249
|
-
|
|
4236
|
+
parseParams(allParams)
|
|
4250
4237
|
)
|
|
4251
4238
|
);
|
|
4252
4239
|
};
|
|
4253
4240
|
}
|
|
4254
|
-
function
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4241
|
+
function createEndpointProxy(target, wrapperFn) {
|
|
4242
|
+
return new Proxy(target, {
|
|
4243
|
+
get(target2, name, receiver) {
|
|
4244
|
+
const baseVal = Reflect.get(target2, name, receiver);
|
|
4245
|
+
if (name === "create") {
|
|
4246
|
+
return wrapperFn(baseVal.bind(target2));
|
|
4247
|
+
}
|
|
4248
|
+
return baseVal;
|
|
4261
4249
|
}
|
|
4262
|
-
};
|
|
4263
|
-
|
|
4264
|
-
|
|
4250
|
+
});
|
|
4251
|
+
}
|
|
4252
|
+
function parseChatCompletionParams(params) {
|
|
4253
|
+
return parseBaseParams(params, "messages");
|
|
4254
|
+
}
|
|
4255
|
+
function processEmbeddingResponse(result, span) {
|
|
4256
|
+
span.log({
|
|
4257
|
+
output: { embedding_length: result.data[0].embedding.length },
|
|
4258
|
+
metrics: {
|
|
4259
|
+
tokens: result.usage?.total_tokens,
|
|
4260
|
+
prompt_tokens: result.usage?.prompt_tokens
|
|
4261
|
+
}
|
|
4262
|
+
});
|
|
4263
|
+
}
|
|
4264
|
+
function processModerationResponse(result, span) {
|
|
4265
|
+
span.log({
|
|
4266
|
+
output: result.results
|
|
4267
|
+
});
|
|
4265
4268
|
}
|
|
4269
|
+
var wrapEmbeddings = (create) => createApiWrapper(
|
|
4270
|
+
"Embedding",
|
|
4271
|
+
create,
|
|
4272
|
+
processEmbeddingResponse,
|
|
4273
|
+
(params) => parseBaseParams(params, "input")
|
|
4274
|
+
);
|
|
4275
|
+
var wrapModerations = (create) => createApiWrapper(
|
|
4276
|
+
"Moderation",
|
|
4277
|
+
create,
|
|
4278
|
+
processModerationResponse,
|
|
4279
|
+
(params) => parseBaseParams(params, "input")
|
|
4280
|
+
);
|
|
4266
4281
|
function postprocessStreamingResults(allResults) {
|
|
4267
4282
|
let role = void 0;
|
|
4268
4283
|
let content = void 0;
|
package/dist/browser.mjs
CHANGED
|
@@ -1137,16 +1137,35 @@ var ReadonlyAttachment = class {
|
|
|
1137
1137
|
async data() {
|
|
1138
1138
|
return this._data.get();
|
|
1139
1139
|
}
|
|
1140
|
+
/**
|
|
1141
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
1142
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
1143
|
+
*/
|
|
1144
|
+
async metadata() {
|
|
1145
|
+
const state = this.state ?? _globalState;
|
|
1146
|
+
await state.login({});
|
|
1147
|
+
const resp = await state.apiConn().get("/attachment", {
|
|
1148
|
+
key: this.reference.key,
|
|
1149
|
+
filename: this.reference.filename,
|
|
1150
|
+
content_type: this.reference.content_type,
|
|
1151
|
+
org_id: state.orgId || ""
|
|
1152
|
+
});
|
|
1153
|
+
if (!resp.ok) {
|
|
1154
|
+
const errorStr = JSON.stringify(resp);
|
|
1155
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1156
|
+
}
|
|
1157
|
+
return attachmentMetadataSchema.parse(await resp.json());
|
|
1158
|
+
}
|
|
1140
1159
|
/**
|
|
1141
1160
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
1142
1161
|
* in case it changes over time.
|
|
1143
1162
|
*/
|
|
1144
1163
|
async status() {
|
|
1145
|
-
return (await this.
|
|
1164
|
+
return (await this.metadata()).status;
|
|
1146
1165
|
}
|
|
1147
1166
|
initDownloader() {
|
|
1148
1167
|
const download = async () => {
|
|
1149
|
-
const { downloadUrl, status } = await this.
|
|
1168
|
+
const { downloadUrl, status } = await this.metadata();
|
|
1150
1169
|
if (status.upload_status !== "done") {
|
|
1151
1170
|
throw new Error(
|
|
1152
1171
|
`Expected attachment status "done", got "${status.upload_status}"`
|
|
@@ -1161,21 +1180,6 @@ var ReadonlyAttachment = class {
|
|
|
1161
1180
|
};
|
|
1162
1181
|
return new LazyValue(download);
|
|
1163
1182
|
}
|
|
1164
|
-
async fetchMetadata() {
|
|
1165
|
-
const state = this.state ?? _globalState;
|
|
1166
|
-
await state.login({});
|
|
1167
|
-
const resp = await state.apiConn().get("/attachment", {
|
|
1168
|
-
key: this.reference.key,
|
|
1169
|
-
filename: this.reference.filename,
|
|
1170
|
-
content_type: this.reference.content_type,
|
|
1171
|
-
org_id: state.orgId || ""
|
|
1172
|
-
});
|
|
1173
|
-
if (!resp.ok) {
|
|
1174
|
-
const errorStr = JSON.stringify(resp);
|
|
1175
|
-
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1176
|
-
}
|
|
1177
|
-
return attachmentMetadataSchema.parse(await resp.json());
|
|
1178
|
-
}
|
|
1179
1183
|
};
|
|
1180
1184
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
1181
1185
|
id,
|
|
@@ -3936,16 +3940,11 @@ function wrapOpenAI(openai) {
|
|
|
3936
3940
|
}
|
|
3937
3941
|
globalThis.__inherited_braintrust_wrap_openai = wrapOpenAI;
|
|
3938
3942
|
function wrapOpenAIv4(openai) {
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
|
|
3944
|
-
}
|
|
3945
|
-
return baseVal;
|
|
3946
|
-
}
|
|
3947
|
-
});
|
|
3948
|
-
let chatProxy = new Proxy(openai.chat, {
|
|
3943
|
+
const completionProxy = createEndpointProxy(
|
|
3944
|
+
openai.chat.completions,
|
|
3945
|
+
wrapChatCompletion
|
|
3946
|
+
);
|
|
3947
|
+
const chatProxy = new Proxy(openai.chat, {
|
|
3949
3948
|
get(target, name, receiver) {
|
|
3950
3949
|
if (name === "completions") {
|
|
3951
3950
|
return completionProxy;
|
|
@@ -3953,18 +3952,11 @@ function wrapOpenAIv4(openai) {
|
|
|
3953
3952
|
return Reflect.get(target, name, receiver);
|
|
3954
3953
|
}
|
|
3955
3954
|
});
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
const baseVal = Reflect.get(target, name, receiver);
|
|
3959
|
-
if (name === "create") {
|
|
3960
|
-
return wrapEmbeddings(baseVal.bind(target));
|
|
3961
|
-
}
|
|
3962
|
-
return baseVal;
|
|
3963
|
-
}
|
|
3964
|
-
});
|
|
3955
|
+
const embeddingProxy = createEndpointProxy(openai.embeddings, wrapEmbeddings);
|
|
3956
|
+
const moderationProxy = createEndpointProxy(openai.moderations, wrapModerations);
|
|
3965
3957
|
let betaProxy;
|
|
3966
3958
|
if (openai.beta?.chat?.completions?.stream) {
|
|
3967
|
-
|
|
3959
|
+
const betaChatCompletionProxy = new Proxy(openai?.beta?.chat.completions, {
|
|
3968
3960
|
get(target, name, receiver) {
|
|
3969
3961
|
const baseVal = Reflect.get(target, name, receiver);
|
|
3970
3962
|
if (name === "parse") {
|
|
@@ -3975,7 +3967,7 @@ function wrapOpenAIv4(openai) {
|
|
|
3975
3967
|
return baseVal;
|
|
3976
3968
|
}
|
|
3977
3969
|
});
|
|
3978
|
-
|
|
3970
|
+
const betaChatProxy = new Proxy(openai.beta.chat, {
|
|
3979
3971
|
get(target, name, receiver) {
|
|
3980
3972
|
if (name === "completions") {
|
|
3981
3973
|
return betaChatCompletionProxy;
|
|
@@ -3992,7 +3984,7 @@ function wrapOpenAIv4(openai) {
|
|
|
3992
3984
|
}
|
|
3993
3985
|
});
|
|
3994
3986
|
}
|
|
3995
|
-
|
|
3987
|
+
return new Proxy(openai, {
|
|
3996
3988
|
get(target, name, receiver) {
|
|
3997
3989
|
if (name === "chat") {
|
|
3998
3990
|
return chatProxy;
|
|
@@ -4000,13 +3992,15 @@ function wrapOpenAIv4(openai) {
|
|
|
4000
3992
|
if (name === "embeddings") {
|
|
4001
3993
|
return embeddingProxy;
|
|
4002
3994
|
}
|
|
3995
|
+
if (name === "moderations") {
|
|
3996
|
+
return moderationProxy;
|
|
3997
|
+
}
|
|
4003
3998
|
if (name === "beta" && betaProxy) {
|
|
4004
3999
|
return betaProxy;
|
|
4005
4000
|
}
|
|
4006
4001
|
return Reflect.get(target, name, receiver);
|
|
4007
4002
|
}
|
|
4008
4003
|
});
|
|
4009
|
-
return proxy;
|
|
4010
4004
|
}
|
|
4011
4005
|
function logCompletionResponse(startTime, response, span) {
|
|
4012
4006
|
span.log({
|
|
@@ -4155,7 +4149,7 @@ function wrapChatCompletion(completion) {
|
|
|
4155
4149
|
}
|
|
4156
4150
|
};
|
|
4157
4151
|
}
|
|
4158
|
-
function
|
|
4152
|
+
function parseBaseParams(allParams, inputField) {
|
|
4159
4153
|
const { span_info, ...params } = allParams;
|
|
4160
4154
|
const { metadata: spanInfoMetadata, ...spanInfoRest } = span_info ?? {};
|
|
4161
4155
|
let ret = {
|
|
@@ -4164,10 +4158,12 @@ function parseChatCompletionParams(allParams) {
|
|
|
4164
4158
|
metadata: spanInfoMetadata
|
|
4165
4159
|
}
|
|
4166
4160
|
};
|
|
4167
|
-
const
|
|
4168
|
-
|
|
4161
|
+
const input = params[inputField];
|
|
4162
|
+
const paramsRest = { ...params };
|
|
4163
|
+
delete paramsRest[inputField];
|
|
4164
|
+
return mergeDicts2(ret, { event: { input, metadata: paramsRest } });
|
|
4169
4165
|
}
|
|
4170
|
-
function
|
|
4166
|
+
function createApiWrapper(name, create, processResponse, parseParams) {
|
|
4171
4167
|
return async (allParams, options) => {
|
|
4172
4168
|
const { span_info: _, ...params } = allParams;
|
|
4173
4169
|
return traced(
|
|
@@ -4177,42 +4173,61 @@ function wrapEmbeddings(create) {
|
|
|
4177
4173
|
options
|
|
4178
4174
|
).withResponse();
|
|
4179
4175
|
logHeaders(response, span);
|
|
4180
|
-
|
|
4181
|
-
span.log({
|
|
4182
|
-
// TODO: Add a flag to control whether to log the full embedding vector,
|
|
4183
|
-
// possibly w/ JSON compression.
|
|
4184
|
-
output: { embedding_length },
|
|
4185
|
-
metrics: {
|
|
4186
|
-
tokens: result.usage?.total_tokens,
|
|
4187
|
-
prompt_tokens: result.usage?.prompt_tokens
|
|
4188
|
-
}
|
|
4189
|
-
});
|
|
4176
|
+
processResponse(result, span);
|
|
4190
4177
|
return result;
|
|
4191
4178
|
},
|
|
4192
4179
|
mergeDicts2(
|
|
4193
4180
|
{
|
|
4194
|
-
name
|
|
4181
|
+
name,
|
|
4195
4182
|
spanAttributes: {
|
|
4196
4183
|
type: SpanTypeAttribute2.LLM
|
|
4197
4184
|
}
|
|
4198
4185
|
},
|
|
4199
|
-
|
|
4186
|
+
parseParams(allParams)
|
|
4200
4187
|
)
|
|
4201
4188
|
);
|
|
4202
4189
|
};
|
|
4203
4190
|
}
|
|
4204
|
-
function
|
|
4205
|
-
|
|
4206
|
-
|
|
4207
|
-
|
|
4208
|
-
|
|
4209
|
-
|
|
4210
|
-
|
|
4191
|
+
function createEndpointProxy(target, wrapperFn) {
|
|
4192
|
+
return new Proxy(target, {
|
|
4193
|
+
get(target2, name, receiver) {
|
|
4194
|
+
const baseVal = Reflect.get(target2, name, receiver);
|
|
4195
|
+
if (name === "create") {
|
|
4196
|
+
return wrapperFn(baseVal.bind(target2));
|
|
4197
|
+
}
|
|
4198
|
+
return baseVal;
|
|
4211
4199
|
}
|
|
4212
|
-
};
|
|
4213
|
-
|
|
4214
|
-
|
|
4200
|
+
});
|
|
4201
|
+
}
|
|
4202
|
+
function parseChatCompletionParams(params) {
|
|
4203
|
+
return parseBaseParams(params, "messages");
|
|
4204
|
+
}
|
|
4205
|
+
function processEmbeddingResponse(result, span) {
|
|
4206
|
+
span.log({
|
|
4207
|
+
output: { embedding_length: result.data[0].embedding.length },
|
|
4208
|
+
metrics: {
|
|
4209
|
+
tokens: result.usage?.total_tokens,
|
|
4210
|
+
prompt_tokens: result.usage?.prompt_tokens
|
|
4211
|
+
}
|
|
4212
|
+
});
|
|
4213
|
+
}
|
|
4214
|
+
function processModerationResponse(result, span) {
|
|
4215
|
+
span.log({
|
|
4216
|
+
output: result.results
|
|
4217
|
+
});
|
|
4215
4218
|
}
|
|
4219
|
+
var wrapEmbeddings = (create) => createApiWrapper(
|
|
4220
|
+
"Embedding",
|
|
4221
|
+
create,
|
|
4222
|
+
processEmbeddingResponse,
|
|
4223
|
+
(params) => parseBaseParams(params, "input")
|
|
4224
|
+
);
|
|
4225
|
+
var wrapModerations = (create) => createApiWrapper(
|
|
4226
|
+
"Moderation",
|
|
4227
|
+
create,
|
|
4228
|
+
processModerationResponse,
|
|
4229
|
+
(params) => parseBaseParams(params, "input")
|
|
4230
|
+
);
|
|
4216
4231
|
function postprocessStreamingResults(allResults) {
|
|
4217
4232
|
let role = void 0;
|
|
4218
4233
|
let content = void 0;
|
package/dist/cli.js
CHANGED
|
@@ -1236,7 +1236,7 @@ var require_package = __commonJS({
|
|
|
1236
1236
|
"package.json"(exports2, module2) {
|
|
1237
1237
|
module2.exports = {
|
|
1238
1238
|
name: "braintrust",
|
|
1239
|
-
version: "0.0.
|
|
1239
|
+
version: "0.0.182",
|
|
1240
1240
|
description: "SDK for integrating Braintrust",
|
|
1241
1241
|
repository: {
|
|
1242
1242
|
type: "git",
|
|
@@ -1311,7 +1311,7 @@ var require_package = __commonJS({
|
|
|
1311
1311
|
},
|
|
1312
1312
|
dependencies: {
|
|
1313
1313
|
"@ai-sdk/provider": "^1.0.1",
|
|
1314
|
-
"@braintrust/core": "0.0.
|
|
1314
|
+
"@braintrust/core": "0.0.76",
|
|
1315
1315
|
"@next/env": "^14.2.3",
|
|
1316
1316
|
"@vercel/functions": "^1.0.2",
|
|
1317
1317
|
ai: "^3.2.16",
|
|
@@ -2457,16 +2457,35 @@ var ReadonlyAttachment = class {
|
|
|
2457
2457
|
async data() {
|
|
2458
2458
|
return this._data.get();
|
|
2459
2459
|
}
|
|
2460
|
+
/**
|
|
2461
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
2462
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
2463
|
+
*/
|
|
2464
|
+
async metadata() {
|
|
2465
|
+
const state = this.state ?? _globalState;
|
|
2466
|
+
await state.login({});
|
|
2467
|
+
const resp = await state.apiConn().get("/attachment", {
|
|
2468
|
+
key: this.reference.key,
|
|
2469
|
+
filename: this.reference.filename,
|
|
2470
|
+
content_type: this.reference.content_type,
|
|
2471
|
+
org_id: state.orgId || ""
|
|
2472
|
+
});
|
|
2473
|
+
if (!resp.ok) {
|
|
2474
|
+
const errorStr = JSON.stringify(resp);
|
|
2475
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
2476
|
+
}
|
|
2477
|
+
return attachmentMetadataSchema.parse(await resp.json());
|
|
2478
|
+
}
|
|
2460
2479
|
/**
|
|
2461
2480
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
2462
2481
|
* in case it changes over time.
|
|
2463
2482
|
*/
|
|
2464
2483
|
async status() {
|
|
2465
|
-
return (await this.
|
|
2484
|
+
return (await this.metadata()).status;
|
|
2466
2485
|
}
|
|
2467
2486
|
initDownloader() {
|
|
2468
2487
|
const download = async () => {
|
|
2469
|
-
const { downloadUrl, status } = await this.
|
|
2488
|
+
const { downloadUrl, status } = await this.metadata();
|
|
2470
2489
|
if (status.upload_status !== "done") {
|
|
2471
2490
|
throw new Error(
|
|
2472
2491
|
`Expected attachment status "done", got "${status.upload_status}"`
|
|
@@ -2481,21 +2500,6 @@ var ReadonlyAttachment = class {
|
|
|
2481
2500
|
};
|
|
2482
2501
|
return new LazyValue(download);
|
|
2483
2502
|
}
|
|
2484
|
-
async fetchMetadata() {
|
|
2485
|
-
const state = this.state ?? _globalState;
|
|
2486
|
-
await state.login({});
|
|
2487
|
-
const resp = await state.apiConn().get("/attachment", {
|
|
2488
|
-
key: this.reference.key,
|
|
2489
|
-
filename: this.reference.filename,
|
|
2490
|
-
content_type: this.reference.content_type,
|
|
2491
|
-
org_id: state.orgId || ""
|
|
2492
|
-
});
|
|
2493
|
-
if (!resp.ok) {
|
|
2494
|
-
const errorStr = JSON.stringify(resp);
|
|
2495
|
-
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
2496
|
-
}
|
|
2497
|
-
return attachmentMetadataSchema.parse(await resp.json());
|
|
2498
|
-
}
|
|
2499
2503
|
};
|
|
2500
2504
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
2501
2505
|
id,
|
package/dist/index.d.mts
CHANGED
|
@@ -523,6 +523,32 @@ declare class Attachment {
|
|
|
523
523
|
private initUploader;
|
|
524
524
|
private initData;
|
|
525
525
|
}
|
|
526
|
+
declare const attachmentMetadataSchema: z.ZodObject<{
|
|
527
|
+
downloadUrl: z.ZodString;
|
|
528
|
+
status: z.ZodObject<{
|
|
529
|
+
upload_status: z.ZodEnum<["uploading", "done", "error"]>;
|
|
530
|
+
error_message: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
531
|
+
}, "strip", z.ZodTypeAny, {
|
|
532
|
+
upload_status: "error" | "done" | "uploading";
|
|
533
|
+
error_message?: string | undefined;
|
|
534
|
+
}, {
|
|
535
|
+
upload_status: "error" | "done" | "uploading";
|
|
536
|
+
error_message?: string | null | undefined;
|
|
537
|
+
}>;
|
|
538
|
+
}, "strip", z.ZodTypeAny, {
|
|
539
|
+
status: {
|
|
540
|
+
upload_status: "error" | "done" | "uploading";
|
|
541
|
+
error_message?: string | undefined;
|
|
542
|
+
};
|
|
543
|
+
downloadUrl: string;
|
|
544
|
+
}, {
|
|
545
|
+
status: {
|
|
546
|
+
upload_status: "error" | "done" | "uploading";
|
|
547
|
+
error_message?: string | null | undefined;
|
|
548
|
+
};
|
|
549
|
+
downloadUrl: string;
|
|
550
|
+
}>;
|
|
551
|
+
type AttachmentMetadata = z.infer<typeof attachmentMetadataSchema>;
|
|
526
552
|
/**
|
|
527
553
|
* A readonly alternative to `Attachment`, which can be used for fetching
|
|
528
554
|
* already-uploaded Attachments.
|
|
@@ -548,13 +574,17 @@ declare class ReadonlyAttachment {
|
|
|
548
574
|
* contents from the object store on first access.
|
|
549
575
|
*/
|
|
550
576
|
data(): Promise<Blob>;
|
|
577
|
+
/**
|
|
578
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
579
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
580
|
+
*/
|
|
581
|
+
metadata(): Promise<AttachmentMetadata>;
|
|
551
582
|
/**
|
|
552
583
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
553
584
|
* in case it changes over time.
|
|
554
585
|
*/
|
|
555
586
|
status(): Promise<AttachmentStatus>;
|
|
556
587
|
private initDownloader;
|
|
557
|
-
private fetchMetadata;
|
|
558
588
|
}
|
|
559
589
|
/**
|
|
560
590
|
* Update a span using the output of `span.export()`. It is important that you only resume updating
|
|
@@ -2170,6 +2200,7 @@ interface ChatLike {
|
|
|
2170
2200
|
interface OpenAILike {
|
|
2171
2201
|
chat: ChatLike;
|
|
2172
2202
|
embeddings: any;
|
|
2203
|
+
moderations: any;
|
|
2173
2204
|
beta?: BetaLike;
|
|
2174
2205
|
}
|
|
2175
2206
|
declare global {
|
package/dist/index.d.ts
CHANGED
|
@@ -523,6 +523,32 @@ declare class Attachment {
|
|
|
523
523
|
private initUploader;
|
|
524
524
|
private initData;
|
|
525
525
|
}
|
|
526
|
+
declare const attachmentMetadataSchema: z.ZodObject<{
|
|
527
|
+
downloadUrl: z.ZodString;
|
|
528
|
+
status: z.ZodObject<{
|
|
529
|
+
upload_status: z.ZodEnum<["uploading", "done", "error"]>;
|
|
530
|
+
error_message: z.ZodEffects<z.ZodOptional<z.ZodNullable<z.ZodString>>, string | undefined, string | null | undefined>;
|
|
531
|
+
}, "strip", z.ZodTypeAny, {
|
|
532
|
+
upload_status: "error" | "done" | "uploading";
|
|
533
|
+
error_message?: string | undefined;
|
|
534
|
+
}, {
|
|
535
|
+
upload_status: "error" | "done" | "uploading";
|
|
536
|
+
error_message?: string | null | undefined;
|
|
537
|
+
}>;
|
|
538
|
+
}, "strip", z.ZodTypeAny, {
|
|
539
|
+
status: {
|
|
540
|
+
upload_status: "error" | "done" | "uploading";
|
|
541
|
+
error_message?: string | undefined;
|
|
542
|
+
};
|
|
543
|
+
downloadUrl: string;
|
|
544
|
+
}, {
|
|
545
|
+
status: {
|
|
546
|
+
upload_status: "error" | "done" | "uploading";
|
|
547
|
+
error_message?: string | null | undefined;
|
|
548
|
+
};
|
|
549
|
+
downloadUrl: string;
|
|
550
|
+
}>;
|
|
551
|
+
type AttachmentMetadata = z.infer<typeof attachmentMetadataSchema>;
|
|
526
552
|
/**
|
|
527
553
|
* A readonly alternative to `Attachment`, which can be used for fetching
|
|
528
554
|
* already-uploaded Attachments.
|
|
@@ -548,13 +574,17 @@ declare class ReadonlyAttachment {
|
|
|
548
574
|
* contents from the object store on first access.
|
|
549
575
|
*/
|
|
550
576
|
data(): Promise<Blob>;
|
|
577
|
+
/**
|
|
578
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
579
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
580
|
+
*/
|
|
581
|
+
metadata(): Promise<AttachmentMetadata>;
|
|
551
582
|
/**
|
|
552
583
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
553
584
|
* in case it changes over time.
|
|
554
585
|
*/
|
|
555
586
|
status(): Promise<AttachmentStatus>;
|
|
556
587
|
private initDownloader;
|
|
557
|
-
private fetchMetadata;
|
|
558
588
|
}
|
|
559
589
|
/**
|
|
560
590
|
* Update a span using the output of `span.export()`. It is important that you only resume updating
|
|
@@ -2170,6 +2200,7 @@ interface ChatLike {
|
|
|
2170
2200
|
interface OpenAILike {
|
|
2171
2201
|
chat: ChatLike;
|
|
2172
2202
|
embeddings: any;
|
|
2203
|
+
moderations: any;
|
|
2173
2204
|
beta?: BetaLike;
|
|
2174
2205
|
}
|
|
2175
2206
|
declare global {
|
package/dist/index.js
CHANGED
|
@@ -1425,16 +1425,35 @@ var ReadonlyAttachment = class {
|
|
|
1425
1425
|
async data() {
|
|
1426
1426
|
return this._data.get();
|
|
1427
1427
|
}
|
|
1428
|
+
/**
|
|
1429
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
1430
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
1431
|
+
*/
|
|
1432
|
+
async metadata() {
|
|
1433
|
+
const state = this.state ?? _globalState;
|
|
1434
|
+
await state.login({});
|
|
1435
|
+
const resp = await state.apiConn().get("/attachment", {
|
|
1436
|
+
key: this.reference.key,
|
|
1437
|
+
filename: this.reference.filename,
|
|
1438
|
+
content_type: this.reference.content_type,
|
|
1439
|
+
org_id: state.orgId || ""
|
|
1440
|
+
});
|
|
1441
|
+
if (!resp.ok) {
|
|
1442
|
+
const errorStr = JSON.stringify(resp);
|
|
1443
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1444
|
+
}
|
|
1445
|
+
return attachmentMetadataSchema.parse(await resp.json());
|
|
1446
|
+
}
|
|
1428
1447
|
/**
|
|
1429
1448
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
1430
1449
|
* in case it changes over time.
|
|
1431
1450
|
*/
|
|
1432
1451
|
async status() {
|
|
1433
|
-
return (await this.
|
|
1452
|
+
return (await this.metadata()).status;
|
|
1434
1453
|
}
|
|
1435
1454
|
initDownloader() {
|
|
1436
1455
|
const download = async () => {
|
|
1437
|
-
const { downloadUrl, status } = await this.
|
|
1456
|
+
const { downloadUrl, status } = await this.metadata();
|
|
1438
1457
|
if (status.upload_status !== "done") {
|
|
1439
1458
|
throw new Error(
|
|
1440
1459
|
`Expected attachment status "done", got "${status.upload_status}"`
|
|
@@ -1449,21 +1468,6 @@ var ReadonlyAttachment = class {
|
|
|
1449
1468
|
};
|
|
1450
1469
|
return new LazyValue(download);
|
|
1451
1470
|
}
|
|
1452
|
-
async fetchMetadata() {
|
|
1453
|
-
const state = this.state ?? _globalState;
|
|
1454
|
-
await state.login({});
|
|
1455
|
-
const resp = await state.apiConn().get("/attachment", {
|
|
1456
|
-
key: this.reference.key,
|
|
1457
|
-
filename: this.reference.filename,
|
|
1458
|
-
content_type: this.reference.content_type,
|
|
1459
|
-
org_id: state.orgId || ""
|
|
1460
|
-
});
|
|
1461
|
-
if (!resp.ok) {
|
|
1462
|
-
const errorStr = JSON.stringify(resp);
|
|
1463
|
-
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1464
|
-
}
|
|
1465
|
-
return attachmentMetadataSchema.parse(await resp.json());
|
|
1466
|
-
}
|
|
1467
1471
|
};
|
|
1468
1472
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
1469
1473
|
id,
|
|
@@ -6186,16 +6190,11 @@ function wrapOpenAI(openai) {
|
|
|
6186
6190
|
}
|
|
6187
6191
|
globalThis.__inherited_braintrust_wrap_openai = wrapOpenAI;
|
|
6188
6192
|
function wrapOpenAIv4(openai) {
|
|
6189
|
-
|
|
6190
|
-
|
|
6191
|
-
|
|
6192
|
-
|
|
6193
|
-
|
|
6194
|
-
}
|
|
6195
|
-
return baseVal;
|
|
6196
|
-
}
|
|
6197
|
-
});
|
|
6198
|
-
let chatProxy = new Proxy(openai.chat, {
|
|
6193
|
+
const completionProxy = createEndpointProxy(
|
|
6194
|
+
openai.chat.completions,
|
|
6195
|
+
wrapChatCompletion
|
|
6196
|
+
);
|
|
6197
|
+
const chatProxy = new Proxy(openai.chat, {
|
|
6199
6198
|
get(target, name, receiver) {
|
|
6200
6199
|
if (name === "completions") {
|
|
6201
6200
|
return completionProxy;
|
|
@@ -6203,18 +6202,11 @@ function wrapOpenAIv4(openai) {
|
|
|
6203
6202
|
return Reflect.get(target, name, receiver);
|
|
6204
6203
|
}
|
|
6205
6204
|
});
|
|
6206
|
-
|
|
6207
|
-
|
|
6208
|
-
const baseVal = Reflect.get(target, name, receiver);
|
|
6209
|
-
if (name === "create") {
|
|
6210
|
-
return wrapEmbeddings(baseVal.bind(target));
|
|
6211
|
-
}
|
|
6212
|
-
return baseVal;
|
|
6213
|
-
}
|
|
6214
|
-
});
|
|
6205
|
+
const embeddingProxy = createEndpointProxy(openai.embeddings, wrapEmbeddings);
|
|
6206
|
+
const moderationProxy = createEndpointProxy(openai.moderations, wrapModerations);
|
|
6215
6207
|
let betaProxy;
|
|
6216
6208
|
if (openai.beta?.chat?.completions?.stream) {
|
|
6217
|
-
|
|
6209
|
+
const betaChatCompletionProxy = new Proxy(openai?.beta?.chat.completions, {
|
|
6218
6210
|
get(target, name, receiver) {
|
|
6219
6211
|
const baseVal = Reflect.get(target, name, receiver);
|
|
6220
6212
|
if (name === "parse") {
|
|
@@ -6225,7 +6217,7 @@ function wrapOpenAIv4(openai) {
|
|
|
6225
6217
|
return baseVal;
|
|
6226
6218
|
}
|
|
6227
6219
|
});
|
|
6228
|
-
|
|
6220
|
+
const betaChatProxy = new Proxy(openai.beta.chat, {
|
|
6229
6221
|
get(target, name, receiver) {
|
|
6230
6222
|
if (name === "completions") {
|
|
6231
6223
|
return betaChatCompletionProxy;
|
|
@@ -6242,7 +6234,7 @@ function wrapOpenAIv4(openai) {
|
|
|
6242
6234
|
}
|
|
6243
6235
|
});
|
|
6244
6236
|
}
|
|
6245
|
-
|
|
6237
|
+
return new Proxy(openai, {
|
|
6246
6238
|
get(target, name, receiver) {
|
|
6247
6239
|
if (name === "chat") {
|
|
6248
6240
|
return chatProxy;
|
|
@@ -6250,13 +6242,15 @@ function wrapOpenAIv4(openai) {
|
|
|
6250
6242
|
if (name === "embeddings") {
|
|
6251
6243
|
return embeddingProxy;
|
|
6252
6244
|
}
|
|
6245
|
+
if (name === "moderations") {
|
|
6246
|
+
return moderationProxy;
|
|
6247
|
+
}
|
|
6253
6248
|
if (name === "beta" && betaProxy) {
|
|
6254
6249
|
return betaProxy;
|
|
6255
6250
|
}
|
|
6256
6251
|
return Reflect.get(target, name, receiver);
|
|
6257
6252
|
}
|
|
6258
6253
|
});
|
|
6259
|
-
return proxy;
|
|
6260
6254
|
}
|
|
6261
6255
|
function logCompletionResponse(startTime, response, span) {
|
|
6262
6256
|
span.log({
|
|
@@ -6405,7 +6399,7 @@ function wrapChatCompletion(completion) {
|
|
|
6405
6399
|
}
|
|
6406
6400
|
};
|
|
6407
6401
|
}
|
|
6408
|
-
function
|
|
6402
|
+
function parseBaseParams(allParams, inputField) {
|
|
6409
6403
|
const { span_info, ...params } = allParams;
|
|
6410
6404
|
const { metadata: spanInfoMetadata, ...spanInfoRest } = span_info ?? {};
|
|
6411
6405
|
let ret = {
|
|
@@ -6414,10 +6408,12 @@ function parseChatCompletionParams(allParams) {
|
|
|
6414
6408
|
metadata: spanInfoMetadata
|
|
6415
6409
|
}
|
|
6416
6410
|
};
|
|
6417
|
-
const
|
|
6418
|
-
|
|
6411
|
+
const input = params[inputField];
|
|
6412
|
+
const paramsRest = { ...params };
|
|
6413
|
+
delete paramsRest[inputField];
|
|
6414
|
+
return (0, import_core4.mergeDicts)(ret, { event: { input, metadata: paramsRest } });
|
|
6419
6415
|
}
|
|
6420
|
-
function
|
|
6416
|
+
function createApiWrapper(name, create, processResponse, parseParams) {
|
|
6421
6417
|
return async (allParams, options) => {
|
|
6422
6418
|
const { span_info: _, ...params } = allParams;
|
|
6423
6419
|
return traced(
|
|
@@ -6427,42 +6423,61 @@ function wrapEmbeddings(create) {
|
|
|
6427
6423
|
options
|
|
6428
6424
|
).withResponse();
|
|
6429
6425
|
logHeaders(response, span);
|
|
6430
|
-
|
|
6431
|
-
span.log({
|
|
6432
|
-
// TODO: Add a flag to control whether to log the full embedding vector,
|
|
6433
|
-
// possibly w/ JSON compression.
|
|
6434
|
-
output: { embedding_length },
|
|
6435
|
-
metrics: {
|
|
6436
|
-
tokens: result.usage?.total_tokens,
|
|
6437
|
-
prompt_tokens: result.usage?.prompt_tokens
|
|
6438
|
-
}
|
|
6439
|
-
});
|
|
6426
|
+
processResponse(result, span);
|
|
6440
6427
|
return result;
|
|
6441
6428
|
},
|
|
6442
6429
|
(0, import_core4.mergeDicts)(
|
|
6443
6430
|
{
|
|
6444
|
-
name
|
|
6431
|
+
name,
|
|
6445
6432
|
spanAttributes: {
|
|
6446
6433
|
type: import_core3.SpanTypeAttribute.LLM
|
|
6447
6434
|
}
|
|
6448
6435
|
},
|
|
6449
|
-
|
|
6436
|
+
parseParams(allParams)
|
|
6450
6437
|
)
|
|
6451
6438
|
);
|
|
6452
6439
|
};
|
|
6453
6440
|
}
|
|
6454
|
-
function
|
|
6455
|
-
|
|
6456
|
-
|
|
6457
|
-
|
|
6458
|
-
|
|
6459
|
-
|
|
6460
|
-
|
|
6441
|
+
function createEndpointProxy(target, wrapperFn) {
|
|
6442
|
+
return new Proxy(target, {
|
|
6443
|
+
get(target2, name, receiver) {
|
|
6444
|
+
const baseVal = Reflect.get(target2, name, receiver);
|
|
6445
|
+
if (name === "create") {
|
|
6446
|
+
return wrapperFn(baseVal.bind(target2));
|
|
6447
|
+
}
|
|
6448
|
+
return baseVal;
|
|
6461
6449
|
}
|
|
6462
|
-
};
|
|
6463
|
-
|
|
6464
|
-
|
|
6450
|
+
});
|
|
6451
|
+
}
|
|
6452
|
+
function parseChatCompletionParams(params) {
|
|
6453
|
+
return parseBaseParams(params, "messages");
|
|
6454
|
+
}
|
|
6455
|
+
function processEmbeddingResponse(result, span) {
|
|
6456
|
+
span.log({
|
|
6457
|
+
output: { embedding_length: result.data[0].embedding.length },
|
|
6458
|
+
metrics: {
|
|
6459
|
+
tokens: result.usage?.total_tokens,
|
|
6460
|
+
prompt_tokens: result.usage?.prompt_tokens
|
|
6461
|
+
}
|
|
6462
|
+
});
|
|
6463
|
+
}
|
|
6464
|
+
function processModerationResponse(result, span) {
|
|
6465
|
+
span.log({
|
|
6466
|
+
output: result.results
|
|
6467
|
+
});
|
|
6465
6468
|
}
|
|
6469
|
+
var wrapEmbeddings = (create) => createApiWrapper(
|
|
6470
|
+
"Embedding",
|
|
6471
|
+
create,
|
|
6472
|
+
processEmbeddingResponse,
|
|
6473
|
+
(params) => parseBaseParams(params, "input")
|
|
6474
|
+
);
|
|
6475
|
+
var wrapModerations = (create) => createApiWrapper(
|
|
6476
|
+
"Moderation",
|
|
6477
|
+
create,
|
|
6478
|
+
processModerationResponse,
|
|
6479
|
+
(params) => parseBaseParams(params, "input")
|
|
6480
|
+
);
|
|
6466
6481
|
function postprocessStreamingResults(allResults) {
|
|
6467
6482
|
let role = void 0;
|
|
6468
6483
|
let content = void 0;
|
package/dist/index.mjs
CHANGED
|
@@ -1357,16 +1357,35 @@ var ReadonlyAttachment = class {
|
|
|
1357
1357
|
async data() {
|
|
1358
1358
|
return this._data.get();
|
|
1359
1359
|
}
|
|
1360
|
+
/**
|
|
1361
|
+
* Fetch the attachment metadata, which includes a downloadUrl and a status.
|
|
1362
|
+
* This will re-fetch the status each time in case it changes over time.
|
|
1363
|
+
*/
|
|
1364
|
+
async metadata() {
|
|
1365
|
+
const state = this.state ?? _globalState;
|
|
1366
|
+
await state.login({});
|
|
1367
|
+
const resp = await state.apiConn().get("/attachment", {
|
|
1368
|
+
key: this.reference.key,
|
|
1369
|
+
filename: this.reference.filename,
|
|
1370
|
+
content_type: this.reference.content_type,
|
|
1371
|
+
org_id: state.orgId || ""
|
|
1372
|
+
});
|
|
1373
|
+
if (!resp.ok) {
|
|
1374
|
+
const errorStr = JSON.stringify(resp);
|
|
1375
|
+
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1376
|
+
}
|
|
1377
|
+
return attachmentMetadataSchema.parse(await resp.json());
|
|
1378
|
+
}
|
|
1360
1379
|
/**
|
|
1361
1380
|
* Fetch the attachment upload status. This will re-fetch the status each time
|
|
1362
1381
|
* in case it changes over time.
|
|
1363
1382
|
*/
|
|
1364
1383
|
async status() {
|
|
1365
|
-
return (await this.
|
|
1384
|
+
return (await this.metadata()).status;
|
|
1366
1385
|
}
|
|
1367
1386
|
initDownloader() {
|
|
1368
1387
|
const download = async () => {
|
|
1369
|
-
const { downloadUrl, status } = await this.
|
|
1388
|
+
const { downloadUrl, status } = await this.metadata();
|
|
1370
1389
|
if (status.upload_status !== "done") {
|
|
1371
1390
|
throw new Error(
|
|
1372
1391
|
`Expected attachment status "done", got "${status.upload_status}"`
|
|
@@ -1381,21 +1400,6 @@ var ReadonlyAttachment = class {
|
|
|
1381
1400
|
};
|
|
1382
1401
|
return new LazyValue(download);
|
|
1383
1402
|
}
|
|
1384
|
-
async fetchMetadata() {
|
|
1385
|
-
const state = this.state ?? _globalState;
|
|
1386
|
-
await state.login({});
|
|
1387
|
-
const resp = await state.apiConn().get("/attachment", {
|
|
1388
|
-
key: this.reference.key,
|
|
1389
|
-
filename: this.reference.filename,
|
|
1390
|
-
content_type: this.reference.content_type,
|
|
1391
|
-
org_id: state.orgId || ""
|
|
1392
|
-
});
|
|
1393
|
-
if (!resp.ok) {
|
|
1394
|
-
const errorStr = JSON.stringify(resp);
|
|
1395
|
-
throw new Error(`Invalid response from API server: ${errorStr}`);
|
|
1396
|
-
}
|
|
1397
|
-
return attachmentMetadataSchema.parse(await resp.json());
|
|
1398
|
-
}
|
|
1399
1403
|
};
|
|
1400
1404
|
function logFeedbackImpl(state, parentObjectType, parentObjectId, {
|
|
1401
1405
|
id,
|
|
@@ -6122,16 +6126,11 @@ function wrapOpenAI(openai) {
|
|
|
6122
6126
|
}
|
|
6123
6127
|
globalThis.__inherited_braintrust_wrap_openai = wrapOpenAI;
|
|
6124
6128
|
function wrapOpenAIv4(openai) {
|
|
6125
|
-
|
|
6126
|
-
|
|
6127
|
-
|
|
6128
|
-
|
|
6129
|
-
|
|
6130
|
-
}
|
|
6131
|
-
return baseVal;
|
|
6132
|
-
}
|
|
6133
|
-
});
|
|
6134
|
-
let chatProxy = new Proxy(openai.chat, {
|
|
6129
|
+
const completionProxy = createEndpointProxy(
|
|
6130
|
+
openai.chat.completions,
|
|
6131
|
+
wrapChatCompletion
|
|
6132
|
+
);
|
|
6133
|
+
const chatProxy = new Proxy(openai.chat, {
|
|
6135
6134
|
get(target, name, receiver) {
|
|
6136
6135
|
if (name === "completions") {
|
|
6137
6136
|
return completionProxy;
|
|
@@ -6139,18 +6138,11 @@ function wrapOpenAIv4(openai) {
|
|
|
6139
6138
|
return Reflect.get(target, name, receiver);
|
|
6140
6139
|
}
|
|
6141
6140
|
});
|
|
6142
|
-
|
|
6143
|
-
|
|
6144
|
-
const baseVal = Reflect.get(target, name, receiver);
|
|
6145
|
-
if (name === "create") {
|
|
6146
|
-
return wrapEmbeddings(baseVal.bind(target));
|
|
6147
|
-
}
|
|
6148
|
-
return baseVal;
|
|
6149
|
-
}
|
|
6150
|
-
});
|
|
6141
|
+
const embeddingProxy = createEndpointProxy(openai.embeddings, wrapEmbeddings);
|
|
6142
|
+
const moderationProxy = createEndpointProxy(openai.moderations, wrapModerations);
|
|
6151
6143
|
let betaProxy;
|
|
6152
6144
|
if (openai.beta?.chat?.completions?.stream) {
|
|
6153
|
-
|
|
6145
|
+
const betaChatCompletionProxy = new Proxy(openai?.beta?.chat.completions, {
|
|
6154
6146
|
get(target, name, receiver) {
|
|
6155
6147
|
const baseVal = Reflect.get(target, name, receiver);
|
|
6156
6148
|
if (name === "parse") {
|
|
@@ -6161,7 +6153,7 @@ function wrapOpenAIv4(openai) {
|
|
|
6161
6153
|
return baseVal;
|
|
6162
6154
|
}
|
|
6163
6155
|
});
|
|
6164
|
-
|
|
6156
|
+
const betaChatProxy = new Proxy(openai.beta.chat, {
|
|
6165
6157
|
get(target, name, receiver) {
|
|
6166
6158
|
if (name === "completions") {
|
|
6167
6159
|
return betaChatCompletionProxy;
|
|
@@ -6178,7 +6170,7 @@ function wrapOpenAIv4(openai) {
|
|
|
6178
6170
|
}
|
|
6179
6171
|
});
|
|
6180
6172
|
}
|
|
6181
|
-
|
|
6173
|
+
return new Proxy(openai, {
|
|
6182
6174
|
get(target, name, receiver) {
|
|
6183
6175
|
if (name === "chat") {
|
|
6184
6176
|
return chatProxy;
|
|
@@ -6186,13 +6178,15 @@ function wrapOpenAIv4(openai) {
|
|
|
6186
6178
|
if (name === "embeddings") {
|
|
6187
6179
|
return embeddingProxy;
|
|
6188
6180
|
}
|
|
6181
|
+
if (name === "moderations") {
|
|
6182
|
+
return moderationProxy;
|
|
6183
|
+
}
|
|
6189
6184
|
if (name === "beta" && betaProxy) {
|
|
6190
6185
|
return betaProxy;
|
|
6191
6186
|
}
|
|
6192
6187
|
return Reflect.get(target, name, receiver);
|
|
6193
6188
|
}
|
|
6194
6189
|
});
|
|
6195
|
-
return proxy;
|
|
6196
6190
|
}
|
|
6197
6191
|
function logCompletionResponse(startTime, response, span) {
|
|
6198
6192
|
span.log({
|
|
@@ -6341,7 +6335,7 @@ function wrapChatCompletion(completion) {
|
|
|
6341
6335
|
}
|
|
6342
6336
|
};
|
|
6343
6337
|
}
|
|
6344
|
-
function
|
|
6338
|
+
function parseBaseParams(allParams, inputField) {
|
|
6345
6339
|
const { span_info, ...params } = allParams;
|
|
6346
6340
|
const { metadata: spanInfoMetadata, ...spanInfoRest } = span_info ?? {};
|
|
6347
6341
|
let ret = {
|
|
@@ -6350,10 +6344,12 @@ function parseChatCompletionParams(allParams) {
|
|
|
6350
6344
|
metadata: spanInfoMetadata
|
|
6351
6345
|
}
|
|
6352
6346
|
};
|
|
6353
|
-
const
|
|
6354
|
-
|
|
6347
|
+
const input = params[inputField];
|
|
6348
|
+
const paramsRest = { ...params };
|
|
6349
|
+
delete paramsRest[inputField];
|
|
6350
|
+
return mergeDicts3(ret, { event: { input, metadata: paramsRest } });
|
|
6355
6351
|
}
|
|
6356
|
-
function
|
|
6352
|
+
function createApiWrapper(name, create, processResponse, parseParams) {
|
|
6357
6353
|
return async (allParams, options) => {
|
|
6358
6354
|
const { span_info: _, ...params } = allParams;
|
|
6359
6355
|
return traced(
|
|
@@ -6363,42 +6359,61 @@ function wrapEmbeddings(create) {
|
|
|
6363
6359
|
options
|
|
6364
6360
|
).withResponse();
|
|
6365
6361
|
logHeaders(response, span);
|
|
6366
|
-
|
|
6367
|
-
span.log({
|
|
6368
|
-
// TODO: Add a flag to control whether to log the full embedding vector,
|
|
6369
|
-
// possibly w/ JSON compression.
|
|
6370
|
-
output: { embedding_length },
|
|
6371
|
-
metrics: {
|
|
6372
|
-
tokens: result.usage?.total_tokens,
|
|
6373
|
-
prompt_tokens: result.usage?.prompt_tokens
|
|
6374
|
-
}
|
|
6375
|
-
});
|
|
6362
|
+
processResponse(result, span);
|
|
6376
6363
|
return result;
|
|
6377
6364
|
},
|
|
6378
6365
|
mergeDicts3(
|
|
6379
6366
|
{
|
|
6380
|
-
name
|
|
6367
|
+
name,
|
|
6381
6368
|
spanAttributes: {
|
|
6382
6369
|
type: SpanTypeAttribute3.LLM
|
|
6383
6370
|
}
|
|
6384
6371
|
},
|
|
6385
|
-
|
|
6372
|
+
parseParams(allParams)
|
|
6386
6373
|
)
|
|
6387
6374
|
);
|
|
6388
6375
|
};
|
|
6389
6376
|
}
|
|
6390
|
-
function
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
|
|
6396
|
-
|
|
6377
|
+
function createEndpointProxy(target, wrapperFn) {
|
|
6378
|
+
return new Proxy(target, {
|
|
6379
|
+
get(target2, name, receiver) {
|
|
6380
|
+
const baseVal = Reflect.get(target2, name, receiver);
|
|
6381
|
+
if (name === "create") {
|
|
6382
|
+
return wrapperFn(baseVal.bind(target2));
|
|
6383
|
+
}
|
|
6384
|
+
return baseVal;
|
|
6397
6385
|
}
|
|
6398
|
-
};
|
|
6399
|
-
|
|
6400
|
-
|
|
6386
|
+
});
|
|
6387
|
+
}
|
|
6388
|
+
function parseChatCompletionParams(params) {
|
|
6389
|
+
return parseBaseParams(params, "messages");
|
|
6390
|
+
}
|
|
6391
|
+
function processEmbeddingResponse(result, span) {
|
|
6392
|
+
span.log({
|
|
6393
|
+
output: { embedding_length: result.data[0].embedding.length },
|
|
6394
|
+
metrics: {
|
|
6395
|
+
tokens: result.usage?.total_tokens,
|
|
6396
|
+
prompt_tokens: result.usage?.prompt_tokens
|
|
6397
|
+
}
|
|
6398
|
+
});
|
|
6399
|
+
}
|
|
6400
|
+
function processModerationResponse(result, span) {
|
|
6401
|
+
span.log({
|
|
6402
|
+
output: result.results
|
|
6403
|
+
});
|
|
6401
6404
|
}
|
|
6405
|
+
var wrapEmbeddings = (create) => createApiWrapper(
|
|
6406
|
+
"Embedding",
|
|
6407
|
+
create,
|
|
6408
|
+
processEmbeddingResponse,
|
|
6409
|
+
(params) => parseBaseParams(params, "input")
|
|
6410
|
+
);
|
|
6411
|
+
var wrapModerations = (create) => createApiWrapper(
|
|
6412
|
+
"Moderation",
|
|
6413
|
+
create,
|
|
6414
|
+
processModerationResponse,
|
|
6415
|
+
(params) => parseBaseParams(params, "input")
|
|
6416
|
+
);
|
|
6402
6417
|
function postprocessStreamingResults(allResults) {
|
|
6403
6418
|
let role = void 0;
|
|
6404
6419
|
let content = void 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "braintrust",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.182",
|
|
4
4
|
"description": "SDK for integrating Braintrust",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
77
|
"@ai-sdk/provider": "^1.0.1",
|
|
78
|
-
"@braintrust/core": "0.0.
|
|
78
|
+
"@braintrust/core": "0.0.76",
|
|
79
79
|
"@next/env": "^14.2.3",
|
|
80
80
|
"@vercel/functions": "^1.0.2",
|
|
81
81
|
"ai": "^3.2.16",
|