langsmith 0.5.2 → 0.5.4
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/client.cjs +125 -10
- package/dist/client.d.ts +54 -2
- package/dist/client.js +126 -11
- package/dist/evaluation/_runner.cjs +2 -2
- package/dist/evaluation/_runner.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +26 -0
- package/dist/singletons/fetch.cjs +13 -13
- package/dist/singletons/fetch.d.ts +3 -3
- package/dist/singletons/fetch.js +11 -11
- package/dist/traceable.cjs +7 -4
- package/dist/traceable.d.ts +2 -1
- package/dist/traceable.js +7 -4
- package/dist/utils/jestlike/index.cjs +3 -0
- package/dist/utils/jestlike/index.js +3 -0
- package/package.json +6 -6
package/dist/client.cjs
CHANGED
|
@@ -1321,7 +1321,6 @@ class Client {
|
|
|
1321
1321
|
async _sendMultipartRequest(parts, context, options) {
|
|
1322
1322
|
// Create multipart form data boundary
|
|
1323
1323
|
const boundary = "----LangSmithFormBoundary" + Math.random().toString(36).slice(2);
|
|
1324
|
-
const isNodeFetch = (0, fetch_js_1._globalFetchImplementationIsNodeFetch)();
|
|
1325
1324
|
const buildBuffered = () => this._createNodeFetchBody(parts, boundary);
|
|
1326
1325
|
const buildStream = () => this._createMultipartStream(parts, boundary);
|
|
1327
1326
|
const sendWithRetry = async (bodyFactory) => {
|
|
@@ -1356,8 +1355,9 @@ class Client {
|
|
|
1356
1355
|
try {
|
|
1357
1356
|
let res;
|
|
1358
1357
|
let streamedAttempt = false;
|
|
1359
|
-
|
|
1360
|
-
if
|
|
1358
|
+
const shouldStream = (0, fetch_js_1._shouldStreamForGlobalFetchImplementation)();
|
|
1359
|
+
// attempt stream only if not disabled and not using node-fetch or Bun;
|
|
1360
|
+
if (shouldStream &&
|
|
1361
1361
|
!this.multipartStreamingDisabled &&
|
|
1362
1362
|
(0, env_js_1.getEnv)() !== "bun") {
|
|
1363
1363
|
streamedAttempt = true;
|
|
@@ -3229,6 +3229,115 @@ class Client {
|
|
|
3229
3229
|
const [results] = await this._logEvaluationFeedback(evaluatorResponse, run, sourceInfo);
|
|
3230
3230
|
return results;
|
|
3231
3231
|
}
|
|
3232
|
+
/**
|
|
3233
|
+
* API for managing feedback configs
|
|
3234
|
+
*/
|
|
3235
|
+
/**
|
|
3236
|
+
* Create a feedback configuration on the LangSmith API.
|
|
3237
|
+
*
|
|
3238
|
+
* This upserts: if an identical config already exists, it returns it.
|
|
3239
|
+
* If a conflicting config exists for the same key, a 400 error is raised.
|
|
3240
|
+
*
|
|
3241
|
+
* @param options - The options for creating a feedback config
|
|
3242
|
+
* @param options.feedbackKey - The unique key for this feedback config
|
|
3243
|
+
* @param options.feedbackConfig - The config specifying type, bounds, and categories
|
|
3244
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
3245
|
+
* @returns The created FeedbackConfigSchema object
|
|
3246
|
+
*/
|
|
3247
|
+
async createFeedbackConfig(options) {
|
|
3248
|
+
const { feedbackKey, feedbackConfig, isLowerScoreBetter = false } = options;
|
|
3249
|
+
const body = {
|
|
3250
|
+
feedback_key: feedbackKey,
|
|
3251
|
+
feedback_config: feedbackConfig,
|
|
3252
|
+
is_lower_score_better: isLowerScoreBetter,
|
|
3253
|
+
};
|
|
3254
|
+
const response = await this.caller.call(async () => {
|
|
3255
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs`, {
|
|
3256
|
+
method: "POST",
|
|
3257
|
+
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
3258
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3259
|
+
...this.fetchOptions,
|
|
3260
|
+
body: JSON.stringify(body),
|
|
3261
|
+
});
|
|
3262
|
+
await (0, error_js_1.raiseForStatus)(res, "create feedback config");
|
|
3263
|
+
return res;
|
|
3264
|
+
});
|
|
3265
|
+
return response.json();
|
|
3266
|
+
}
|
|
3267
|
+
/**
|
|
3268
|
+
* List feedback configurations on the LangSmith API.
|
|
3269
|
+
* @param options - The options for listing feedback configs
|
|
3270
|
+
* @param options.feedbackKeys - Filter by specific feedback keys
|
|
3271
|
+
* @param options.nameContains - Filter by name substring
|
|
3272
|
+
* @param options.limit - The maximum number of configs to return
|
|
3273
|
+
* @returns An async iterator of FeedbackConfigSchema objects
|
|
3274
|
+
*/
|
|
3275
|
+
async *listFeedbackConfigs(options = {}) {
|
|
3276
|
+
const { feedbackKeys, nameContains, limit } = options;
|
|
3277
|
+
const params = new URLSearchParams();
|
|
3278
|
+
if (feedbackKeys) {
|
|
3279
|
+
feedbackKeys.forEach((key) => {
|
|
3280
|
+
params.append("key", key);
|
|
3281
|
+
});
|
|
3282
|
+
}
|
|
3283
|
+
if (nameContains)
|
|
3284
|
+
params.append("name_contains", nameContains);
|
|
3285
|
+
params.append("limit", (limit !== undefined ? Math.min(limit, 100) : 100).toString());
|
|
3286
|
+
let count = 0;
|
|
3287
|
+
for await (const configs of this._getPaginated("/feedback-configs", params)) {
|
|
3288
|
+
yield* configs;
|
|
3289
|
+
count += configs.length;
|
|
3290
|
+
if (limit !== undefined && count >= limit)
|
|
3291
|
+
break;
|
|
3292
|
+
}
|
|
3293
|
+
}
|
|
3294
|
+
/**
|
|
3295
|
+
* Update a feedback configuration on the LangSmith API.
|
|
3296
|
+
* @param feedbackKey - The key of the feedback config to update
|
|
3297
|
+
* @param options - The options for updating the feedback config
|
|
3298
|
+
* @param options.feedbackConfig - The new feedback config
|
|
3299
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
3300
|
+
* @returns The updated FeedbackConfigSchema object
|
|
3301
|
+
*/
|
|
3302
|
+
async updateFeedbackConfig(feedbackKey, options = {}) {
|
|
3303
|
+
const { feedbackConfig, isLowerScoreBetter } = options;
|
|
3304
|
+
const body = { feedback_key: feedbackKey };
|
|
3305
|
+
if (feedbackConfig !== undefined) {
|
|
3306
|
+
body.feedback_config = feedbackConfig;
|
|
3307
|
+
}
|
|
3308
|
+
if (isLowerScoreBetter !== undefined) {
|
|
3309
|
+
body.is_lower_score_better = isLowerScoreBetter;
|
|
3310
|
+
}
|
|
3311
|
+
const response = await this.caller.call(async () => {
|
|
3312
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs`, {
|
|
3313
|
+
method: "PATCH",
|
|
3314
|
+
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
3315
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3316
|
+
...this.fetchOptions,
|
|
3317
|
+
body: JSON.stringify(body),
|
|
3318
|
+
});
|
|
3319
|
+
await (0, error_js_1.raiseForStatus)(res, "update feedback config");
|
|
3320
|
+
return res;
|
|
3321
|
+
});
|
|
3322
|
+
return response.json();
|
|
3323
|
+
}
|
|
3324
|
+
/**
|
|
3325
|
+
* Delete a feedback configuration on the LangSmith API.
|
|
3326
|
+
* @param feedbackKey - The key of the feedback config to delete
|
|
3327
|
+
*/
|
|
3328
|
+
async deleteFeedbackConfig(feedbackKey) {
|
|
3329
|
+
const params = new URLSearchParams({ feedback_key: feedbackKey });
|
|
3330
|
+
await this.caller.call(async () => {
|
|
3331
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs?${params}`, {
|
|
3332
|
+
method: "DELETE",
|
|
3333
|
+
headers: this.headers,
|
|
3334
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3335
|
+
...this.fetchOptions,
|
|
3336
|
+
});
|
|
3337
|
+
await (0, error_js_1.raiseForStatus)(res, "delete feedback config", true);
|
|
3338
|
+
return res;
|
|
3339
|
+
});
|
|
3340
|
+
}
|
|
3232
3341
|
/**
|
|
3233
3342
|
* API for managing annotation queues
|
|
3234
3343
|
*/
|
|
@@ -3272,12 +3381,13 @@ class Client {
|
|
|
3272
3381
|
* @returns The created AnnotationQueue object
|
|
3273
3382
|
*/
|
|
3274
3383
|
async createAnnotationQueue(options) {
|
|
3275
|
-
const { name, description, queueId, rubricInstructions } = options;
|
|
3384
|
+
const { name, description, queueId, rubricInstructions, rubricItems } = options;
|
|
3276
3385
|
const body = {
|
|
3277
3386
|
name,
|
|
3278
3387
|
description,
|
|
3279
3388
|
id: queueId || uuid.v4(),
|
|
3280
3389
|
rubric_instructions: rubricInstructions,
|
|
3390
|
+
rubric_items: rubricItems,
|
|
3281
3391
|
};
|
|
3282
3392
|
const serializedBody = JSON.stringify(Object.fromEntries(Object.entries(body).filter(([_, v]) => v !== undefined)));
|
|
3283
3393
|
const response = await this.caller.call(async () => {
|
|
@@ -3319,12 +3429,17 @@ class Client {
|
|
|
3319
3429
|
* @param options.description - The new description for the annotation queue
|
|
3320
3430
|
*/
|
|
3321
3431
|
async updateAnnotationQueue(queueId, options) {
|
|
3322
|
-
const { name, description, rubricInstructions } = options;
|
|
3323
|
-
const
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3432
|
+
const { name, description, rubricInstructions, rubricItems } = options;
|
|
3433
|
+
const bodyObj = {};
|
|
3434
|
+
if (name !== undefined)
|
|
3435
|
+
bodyObj.name = name;
|
|
3436
|
+
if (description !== undefined)
|
|
3437
|
+
bodyObj.description = description;
|
|
3438
|
+
if (rubricInstructions !== undefined)
|
|
3439
|
+
bodyObj.rubric_instructions = rubricInstructions;
|
|
3440
|
+
if (rubricItems !== undefined)
|
|
3441
|
+
bodyObj.rubric_items = rubricItems;
|
|
3442
|
+
const body = JSON.stringify(bodyObj);
|
|
3328
3443
|
await this.caller.call(async () => {
|
|
3329
3444
|
const res = await this._fetch(`${this.apiUrl}/annotation-queues/${(0, _uuid_js_1.assertUuid)(queueId, "queueId")}`, {
|
|
3330
3445
|
method: "PATCH",
|
package/dist/client.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { OTELContext } from "./experimental/otel/types.js";
|
|
2
2
|
import { AsyncCallerParams } from "./utils/async_caller.js";
|
|
3
|
-
import { ComparativeExperiment, DataType, Dataset, DatasetDiffInfo, DatasetShareSchema, Example, ExampleCreate, ExampleUpdate, ExampleUpdateWithoutId, Feedback, FeedbackConfig, FeedbackIngestToken, KVMap, LangChainBaseMessage, LangSmithSettings, LikePromptResponse, Prompt, PromptCommit, PromptSortField, Run, RunCreate, RunUpdate, ScoreType, ExampleSearch, TimeDelta, TracerSession, TracerSessionResult, ValueType, AnnotationQueue, RunWithAnnotationQueueInfo, Attachments, UploadExamplesResponse, UpdateExamplesResponse, DatasetVersion, AnnotationQueueWithDetails } from "./schemas.js";
|
|
3
|
+
import { ComparativeExperiment, DataType, Dataset, DatasetDiffInfo, DatasetShareSchema, Example, ExampleCreate, ExampleUpdate, ExampleUpdateWithoutId, Feedback, FeedbackConfig, FeedbackIngestToken, KVMap, LangChainBaseMessage, LangSmithSettings, LikePromptResponse, Prompt, PromptCommit, PromptSortField, Run, RunCreate, RunUpdate, ScoreType, ExampleSearch, TimeDelta, TracerSession, TracerSessionResult, ValueType, AnnotationQueue, RunWithAnnotationQueueInfo, Attachments, UploadExamplesResponse, UpdateExamplesResponse, DatasetVersion, AnnotationQueueWithDetails, AnnotationQueueRubricItem, FeedbackConfigSchema } from "./schemas.js";
|
|
4
4
|
import { EvaluationResult, EvaluationResults } from "./evaluation/evaluator.js";
|
|
5
5
|
import { PromptCache } from "./utils/prompt_cache/index.js";
|
|
6
6
|
export interface ClientConfig {
|
|
@@ -906,6 +906,56 @@ export declare class Client implements LangSmithTracingClientInterface {
|
|
|
906
906
|
logEvaluationFeedback(evaluatorResponse: EvaluationResult | EvaluationResult[] | EvaluationResults, run?: Run, sourceInfo?: {
|
|
907
907
|
[key: string]: any;
|
|
908
908
|
}): Promise<EvaluationResult[]>;
|
|
909
|
+
/**
|
|
910
|
+
* API for managing feedback configs
|
|
911
|
+
*/
|
|
912
|
+
/**
|
|
913
|
+
* Create a feedback configuration on the LangSmith API.
|
|
914
|
+
*
|
|
915
|
+
* This upserts: if an identical config already exists, it returns it.
|
|
916
|
+
* If a conflicting config exists for the same key, a 400 error is raised.
|
|
917
|
+
*
|
|
918
|
+
* @param options - The options for creating a feedback config
|
|
919
|
+
* @param options.feedbackKey - The unique key for this feedback config
|
|
920
|
+
* @param options.feedbackConfig - The config specifying type, bounds, and categories
|
|
921
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
922
|
+
* @returns The created FeedbackConfigSchema object
|
|
923
|
+
*/
|
|
924
|
+
createFeedbackConfig(options: {
|
|
925
|
+
feedbackKey: string;
|
|
926
|
+
feedbackConfig: FeedbackConfig;
|
|
927
|
+
isLowerScoreBetter?: boolean;
|
|
928
|
+
}): Promise<FeedbackConfigSchema>;
|
|
929
|
+
/**
|
|
930
|
+
* List feedback configurations on the LangSmith API.
|
|
931
|
+
* @param options - The options for listing feedback configs
|
|
932
|
+
* @param options.feedbackKeys - Filter by specific feedback keys
|
|
933
|
+
* @param options.nameContains - Filter by name substring
|
|
934
|
+
* @param options.limit - The maximum number of configs to return
|
|
935
|
+
* @returns An async iterator of FeedbackConfigSchema objects
|
|
936
|
+
*/
|
|
937
|
+
listFeedbackConfigs(options?: {
|
|
938
|
+
feedbackKeys?: string[];
|
|
939
|
+
nameContains?: string;
|
|
940
|
+
limit?: number;
|
|
941
|
+
}): AsyncIterableIterator<FeedbackConfigSchema>;
|
|
942
|
+
/**
|
|
943
|
+
* Update a feedback configuration on the LangSmith API.
|
|
944
|
+
* @param feedbackKey - The key of the feedback config to update
|
|
945
|
+
* @param options - The options for updating the feedback config
|
|
946
|
+
* @param options.feedbackConfig - The new feedback config
|
|
947
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
948
|
+
* @returns The updated FeedbackConfigSchema object
|
|
949
|
+
*/
|
|
950
|
+
updateFeedbackConfig(feedbackKey: string, options?: {
|
|
951
|
+
feedbackConfig?: FeedbackConfig;
|
|
952
|
+
isLowerScoreBetter?: boolean;
|
|
953
|
+
}): Promise<FeedbackConfigSchema>;
|
|
954
|
+
/**
|
|
955
|
+
* Delete a feedback configuration on the LangSmith API.
|
|
956
|
+
* @param feedbackKey - The key of the feedback config to delete
|
|
957
|
+
*/
|
|
958
|
+
deleteFeedbackConfig(feedbackKey: string): Promise<void>;
|
|
909
959
|
/**
|
|
910
960
|
* API for managing annotation queues
|
|
911
961
|
*/
|
|
@@ -937,6 +987,7 @@ export declare class Client implements LangSmithTracingClientInterface {
|
|
|
937
987
|
description?: string;
|
|
938
988
|
queueId?: string;
|
|
939
989
|
rubricInstructions?: string;
|
|
990
|
+
rubricItems?: AnnotationQueueRubricItem[];
|
|
940
991
|
}): Promise<AnnotationQueueWithDetails>;
|
|
941
992
|
/**
|
|
942
993
|
* Read an annotation queue with the specified queue ID.
|
|
@@ -952,9 +1003,10 @@ export declare class Client implements LangSmithTracingClientInterface {
|
|
|
952
1003
|
* @param options.description - The new description for the annotation queue
|
|
953
1004
|
*/
|
|
954
1005
|
updateAnnotationQueue(queueId: string, options: {
|
|
955
|
-
name
|
|
1006
|
+
name?: string;
|
|
956
1007
|
description?: string;
|
|
957
1008
|
rubricInstructions?: string;
|
|
1009
|
+
rubricItems?: AnnotationQueueRubricItem[];
|
|
958
1010
|
}): Promise<void>;
|
|
959
1011
|
/**
|
|
960
1012
|
* Delete an annotation queue with the specified queue ID.
|
package/dist/client.js
CHANGED
|
@@ -10,7 +10,7 @@ import { warnOnce } from "./utils/warn.js";
|
|
|
10
10
|
import { parsePromptIdentifier } from "./utils/prompts.js";
|
|
11
11
|
import { raiseForStatus, isLangSmithNotFoundError } from "./utils/error.js";
|
|
12
12
|
import { promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
13
|
-
import {
|
|
13
|
+
import { _shouldStreamForGlobalFetchImplementation, _getFetchImplementation, } from "./singletons/fetch.js";
|
|
14
14
|
import { serialize as serializePayloadForTracing } from "./utils/fast-safe-stringify/index.js";
|
|
15
15
|
export function mergeRuntimeEnvIntoRun(run, cachedEnvVars, omitTracedRuntimeInfo) {
|
|
16
16
|
if (omitTracedRuntimeInfo) {
|
|
@@ -1283,7 +1283,6 @@ export class Client {
|
|
|
1283
1283
|
async _sendMultipartRequest(parts, context, options) {
|
|
1284
1284
|
// Create multipart form data boundary
|
|
1285
1285
|
const boundary = "----LangSmithFormBoundary" + Math.random().toString(36).slice(2);
|
|
1286
|
-
const isNodeFetch = _globalFetchImplementationIsNodeFetch();
|
|
1287
1286
|
const buildBuffered = () => this._createNodeFetchBody(parts, boundary);
|
|
1288
1287
|
const buildStream = () => this._createMultipartStream(parts, boundary);
|
|
1289
1288
|
const sendWithRetry = async (bodyFactory) => {
|
|
@@ -1318,8 +1317,9 @@ export class Client {
|
|
|
1318
1317
|
try {
|
|
1319
1318
|
let res;
|
|
1320
1319
|
let streamedAttempt = false;
|
|
1321
|
-
|
|
1322
|
-
if
|
|
1320
|
+
const shouldStream = _shouldStreamForGlobalFetchImplementation();
|
|
1321
|
+
// attempt stream only if not disabled and not using node-fetch or Bun;
|
|
1322
|
+
if (shouldStream &&
|
|
1323
1323
|
!this.multipartStreamingDisabled &&
|
|
1324
1324
|
getEnv() !== "bun") {
|
|
1325
1325
|
streamedAttempt = true;
|
|
@@ -3191,6 +3191,115 @@ export class Client {
|
|
|
3191
3191
|
const [results] = await this._logEvaluationFeedback(evaluatorResponse, run, sourceInfo);
|
|
3192
3192
|
return results;
|
|
3193
3193
|
}
|
|
3194
|
+
/**
|
|
3195
|
+
* API for managing feedback configs
|
|
3196
|
+
*/
|
|
3197
|
+
/**
|
|
3198
|
+
* Create a feedback configuration on the LangSmith API.
|
|
3199
|
+
*
|
|
3200
|
+
* This upserts: if an identical config already exists, it returns it.
|
|
3201
|
+
* If a conflicting config exists for the same key, a 400 error is raised.
|
|
3202
|
+
*
|
|
3203
|
+
* @param options - The options for creating a feedback config
|
|
3204
|
+
* @param options.feedbackKey - The unique key for this feedback config
|
|
3205
|
+
* @param options.feedbackConfig - The config specifying type, bounds, and categories
|
|
3206
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
3207
|
+
* @returns The created FeedbackConfigSchema object
|
|
3208
|
+
*/
|
|
3209
|
+
async createFeedbackConfig(options) {
|
|
3210
|
+
const { feedbackKey, feedbackConfig, isLowerScoreBetter = false } = options;
|
|
3211
|
+
const body = {
|
|
3212
|
+
feedback_key: feedbackKey,
|
|
3213
|
+
feedback_config: feedbackConfig,
|
|
3214
|
+
is_lower_score_better: isLowerScoreBetter,
|
|
3215
|
+
};
|
|
3216
|
+
const response = await this.caller.call(async () => {
|
|
3217
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs`, {
|
|
3218
|
+
method: "POST",
|
|
3219
|
+
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
3220
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3221
|
+
...this.fetchOptions,
|
|
3222
|
+
body: JSON.stringify(body),
|
|
3223
|
+
});
|
|
3224
|
+
await raiseForStatus(res, "create feedback config");
|
|
3225
|
+
return res;
|
|
3226
|
+
});
|
|
3227
|
+
return response.json();
|
|
3228
|
+
}
|
|
3229
|
+
/**
|
|
3230
|
+
* List feedback configurations on the LangSmith API.
|
|
3231
|
+
* @param options - The options for listing feedback configs
|
|
3232
|
+
* @param options.feedbackKeys - Filter by specific feedback keys
|
|
3233
|
+
* @param options.nameContains - Filter by name substring
|
|
3234
|
+
* @param options.limit - The maximum number of configs to return
|
|
3235
|
+
* @returns An async iterator of FeedbackConfigSchema objects
|
|
3236
|
+
*/
|
|
3237
|
+
async *listFeedbackConfigs(options = {}) {
|
|
3238
|
+
const { feedbackKeys, nameContains, limit } = options;
|
|
3239
|
+
const params = new URLSearchParams();
|
|
3240
|
+
if (feedbackKeys) {
|
|
3241
|
+
feedbackKeys.forEach((key) => {
|
|
3242
|
+
params.append("key", key);
|
|
3243
|
+
});
|
|
3244
|
+
}
|
|
3245
|
+
if (nameContains)
|
|
3246
|
+
params.append("name_contains", nameContains);
|
|
3247
|
+
params.append("limit", (limit !== undefined ? Math.min(limit, 100) : 100).toString());
|
|
3248
|
+
let count = 0;
|
|
3249
|
+
for await (const configs of this._getPaginated("/feedback-configs", params)) {
|
|
3250
|
+
yield* configs;
|
|
3251
|
+
count += configs.length;
|
|
3252
|
+
if (limit !== undefined && count >= limit)
|
|
3253
|
+
break;
|
|
3254
|
+
}
|
|
3255
|
+
}
|
|
3256
|
+
/**
|
|
3257
|
+
* Update a feedback configuration on the LangSmith API.
|
|
3258
|
+
* @param feedbackKey - The key of the feedback config to update
|
|
3259
|
+
* @param options - The options for updating the feedback config
|
|
3260
|
+
* @param options.feedbackConfig - The new feedback config
|
|
3261
|
+
* @param options.isLowerScoreBetter - Whether a lower score is better
|
|
3262
|
+
* @returns The updated FeedbackConfigSchema object
|
|
3263
|
+
*/
|
|
3264
|
+
async updateFeedbackConfig(feedbackKey, options = {}) {
|
|
3265
|
+
const { feedbackConfig, isLowerScoreBetter } = options;
|
|
3266
|
+
const body = { feedback_key: feedbackKey };
|
|
3267
|
+
if (feedbackConfig !== undefined) {
|
|
3268
|
+
body.feedback_config = feedbackConfig;
|
|
3269
|
+
}
|
|
3270
|
+
if (isLowerScoreBetter !== undefined) {
|
|
3271
|
+
body.is_lower_score_better = isLowerScoreBetter;
|
|
3272
|
+
}
|
|
3273
|
+
const response = await this.caller.call(async () => {
|
|
3274
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs`, {
|
|
3275
|
+
method: "PATCH",
|
|
3276
|
+
headers: { ...this.headers, "Content-Type": "application/json" },
|
|
3277
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3278
|
+
...this.fetchOptions,
|
|
3279
|
+
body: JSON.stringify(body),
|
|
3280
|
+
});
|
|
3281
|
+
await raiseForStatus(res, "update feedback config");
|
|
3282
|
+
return res;
|
|
3283
|
+
});
|
|
3284
|
+
return response.json();
|
|
3285
|
+
}
|
|
3286
|
+
/**
|
|
3287
|
+
* Delete a feedback configuration on the LangSmith API.
|
|
3288
|
+
* @param feedbackKey - The key of the feedback config to delete
|
|
3289
|
+
*/
|
|
3290
|
+
async deleteFeedbackConfig(feedbackKey) {
|
|
3291
|
+
const params = new URLSearchParams({ feedback_key: feedbackKey });
|
|
3292
|
+
await this.caller.call(async () => {
|
|
3293
|
+
const res = await this._fetch(`${this.apiUrl}/feedback-configs?${params}`, {
|
|
3294
|
+
method: "DELETE",
|
|
3295
|
+
headers: this.headers,
|
|
3296
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
3297
|
+
...this.fetchOptions,
|
|
3298
|
+
});
|
|
3299
|
+
await raiseForStatus(res, "delete feedback config", true);
|
|
3300
|
+
return res;
|
|
3301
|
+
});
|
|
3302
|
+
}
|
|
3194
3303
|
/**
|
|
3195
3304
|
* API for managing annotation queues
|
|
3196
3305
|
*/
|
|
@@ -3234,12 +3343,13 @@ export class Client {
|
|
|
3234
3343
|
* @returns The created AnnotationQueue object
|
|
3235
3344
|
*/
|
|
3236
3345
|
async createAnnotationQueue(options) {
|
|
3237
|
-
const { name, description, queueId, rubricInstructions } = options;
|
|
3346
|
+
const { name, description, queueId, rubricInstructions, rubricItems } = options;
|
|
3238
3347
|
const body = {
|
|
3239
3348
|
name,
|
|
3240
3349
|
description,
|
|
3241
3350
|
id: queueId || uuid.v4(),
|
|
3242
3351
|
rubric_instructions: rubricInstructions,
|
|
3352
|
+
rubric_items: rubricItems,
|
|
3243
3353
|
};
|
|
3244
3354
|
const serializedBody = JSON.stringify(Object.fromEntries(Object.entries(body).filter(([_, v]) => v !== undefined)));
|
|
3245
3355
|
const response = await this.caller.call(async () => {
|
|
@@ -3281,12 +3391,17 @@ export class Client {
|
|
|
3281
3391
|
* @param options.description - The new description for the annotation queue
|
|
3282
3392
|
*/
|
|
3283
3393
|
async updateAnnotationQueue(queueId, options) {
|
|
3284
|
-
const { name, description, rubricInstructions } = options;
|
|
3285
|
-
const
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3394
|
+
const { name, description, rubricInstructions, rubricItems } = options;
|
|
3395
|
+
const bodyObj = {};
|
|
3396
|
+
if (name !== undefined)
|
|
3397
|
+
bodyObj.name = name;
|
|
3398
|
+
if (description !== undefined)
|
|
3399
|
+
bodyObj.description = description;
|
|
3400
|
+
if (rubricInstructions !== undefined)
|
|
3401
|
+
bodyObj.rubric_instructions = rubricInstructions;
|
|
3402
|
+
if (rubricItems !== undefined)
|
|
3403
|
+
bodyObj.rubric_items = rubricItems;
|
|
3404
|
+
const body = JSON.stringify(bodyObj);
|
|
3290
3405
|
await this.caller.call(async () => {
|
|
3291
3406
|
const res = await this._fetch(`${this.apiUrl}/annotation-queues/${assertUuid(queueId, "queueId")}`, {
|
|
3292
3407
|
method: "PATCH",
|
|
@@ -783,13 +783,13 @@ async function _evaluate(target, fields) {
|
|
|
783
783
|
return results;
|
|
784
784
|
}
|
|
785
785
|
async function _forward(fn, example, experimentName, metadata, client, includeAttachments) {
|
|
786
|
-
let run =
|
|
786
|
+
let run = undefined;
|
|
787
787
|
const _getRun = (r) => {
|
|
788
788
|
run = r;
|
|
789
789
|
};
|
|
790
790
|
const defaultOptions = {
|
|
791
791
|
reference_example_id: example.id,
|
|
792
|
-
|
|
792
|
+
on_start: _getRun,
|
|
793
793
|
project_name: experimentName,
|
|
794
794
|
metadata: {
|
|
795
795
|
...metadata,
|
|
@@ -776,13 +776,13 @@ async function _evaluate(target, fields) {
|
|
|
776
776
|
return results;
|
|
777
777
|
}
|
|
778
778
|
async function _forward(fn, example, experimentName, metadata, client, includeAttachments) {
|
|
779
|
-
let run =
|
|
779
|
+
let run = undefined;
|
|
780
780
|
const _getRun = (r) => {
|
|
781
781
|
run = r;
|
|
782
782
|
};
|
|
783
783
|
const defaultOptions = {
|
|
784
784
|
reference_example_id: example.id,
|
|
785
|
-
|
|
785
|
+
on_start: _getRun,
|
|
786
786
|
project_name: experimentName,
|
|
787
787
|
metadata: {
|
|
788
788
|
...metadata,
|
package/dist/index.cjs
CHANGED
|
@@ -18,4 +18,4 @@ Object.defineProperty(exports, "PromptCache", { enumerable: true, get: function
|
|
|
18
18
|
Object.defineProperty(exports, "configureGlobalPromptCache", { enumerable: true, get: function () { return index_js_1.configureGlobalPromptCache; } });
|
|
19
19
|
Object.defineProperty(exports, "promptCacheSingleton", { enumerable: true, get: function () { return index_js_1.promptCacheSingleton; } });
|
|
20
20
|
// Update using yarn bump-version
|
|
21
|
-
exports.__version__ = "0.5.
|
|
21
|
+
exports.__version__ = "0.5.4";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export { Client, type ClientConfig, type LangSmithTracingClientInterface, } from "./client.js";
|
|
2
|
-
export type { Dataset, Example, TracerSession, Run, Feedback, RetrieverOutput, } from "./schemas.js";
|
|
2
|
+
export type { Dataset, Example, TracerSession, Run, Feedback, FeedbackConfigSchema, RetrieverOutput, } from "./schemas.js";
|
|
3
3
|
export { RunTree, type RunTreeConfig } from "./run_trees.js";
|
|
4
4
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
5
5
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
6
6
|
export { uuid7, uuid7FromTime } from "./uuid.js";
|
|
7
7
|
export { Cache, PromptCache, type CacheConfig, type CacheMetrics, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
8
|
-
export declare const __version__ = "0.5.
|
|
8
|
+
export declare const __version__ = "0.5.4";
|
package/dist/index.js
CHANGED
|
@@ -5,4 +5,4 @@ export { getDefaultProjectName } from "./utils/project.js";
|
|
|
5
5
|
export { uuid7, uuid7FromTime } from "./uuid.js";
|
|
6
6
|
export { Cache, PromptCache, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
7
7
|
// Update using yarn bump-version
|
|
8
|
-
export const __version__ = "0.5.
|
|
8
|
+
export const __version__ = "0.5.4";
|
package/dist/schemas.d.ts
CHANGED
|
@@ -457,9 +457,35 @@ export interface AnnotationQueue {
|
|
|
457
457
|
/** The ID of the tenant associated with the annotation queue. */
|
|
458
458
|
tenant_id: string;
|
|
459
459
|
}
|
|
460
|
+
export interface AnnotationQueueRubricItem {
|
|
461
|
+
/** The feedback key this rubric item is associated with. */
|
|
462
|
+
feedback_key: string;
|
|
463
|
+
/** An optional description of the rubric item. */
|
|
464
|
+
description?: string | null;
|
|
465
|
+
/** Descriptions for categorical values. */
|
|
466
|
+
value_descriptions?: Record<string, string> | null;
|
|
467
|
+
/** Descriptions for continuous score values. */
|
|
468
|
+
score_descriptions?: Record<string, string> | null;
|
|
469
|
+
/** Whether this rubric item is required. */
|
|
470
|
+
is_required?: boolean | null;
|
|
471
|
+
}
|
|
460
472
|
export interface AnnotationQueueWithDetails extends AnnotationQueue {
|
|
461
473
|
/** The rubric instructions for the annotation queue. */
|
|
462
474
|
rubric_instructions?: string;
|
|
475
|
+
/** The rubric items for the annotation queue. */
|
|
476
|
+
rubric_items?: AnnotationQueueRubricItem[];
|
|
477
|
+
}
|
|
478
|
+
export interface FeedbackConfigSchema {
|
|
479
|
+
/** The unique key identifying this feedback configuration. */
|
|
480
|
+
feedback_key: string;
|
|
481
|
+
/** The configuration specifying the type, bounds, and categories. */
|
|
482
|
+
feedback_config: FeedbackConfig;
|
|
483
|
+
/** The ID of the tenant that owns this feedback configuration. */
|
|
484
|
+
tenant_id: string;
|
|
485
|
+
/** When this feedback configuration was last modified. */
|
|
486
|
+
modified_at: string;
|
|
487
|
+
/** Whether a lower score is considered better for this feedback key. */
|
|
488
|
+
is_lower_score_better?: boolean | null;
|
|
463
489
|
}
|
|
464
490
|
export interface RunWithAnnotationQueueInfo extends BaseRun {
|
|
465
491
|
/** The last time this run was reviewed. */
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._getFetchImplementation = exports.
|
|
3
|
+
exports._getFetchImplementation = exports._shouldStreamForGlobalFetchImplementation = exports.clearFetchImplementation = exports.overrideFetchImplementation = void 0;
|
|
4
4
|
const env_js_1 = require("../utils/env.cjs");
|
|
5
5
|
// Wrap the default fetch call due to issues with illegal invocations
|
|
6
6
|
// in some environments:
|
|
7
7
|
// https://stackoverflow.com/questions/69876859/why-does-bind-fix-failed-to-execute-fetch-on-window-illegal-invocation-err
|
|
8
8
|
// @ts-expect-error Broad typing to support a range of fetch implementations
|
|
9
9
|
const DEFAULT_FETCH_IMPLEMENTATION = (...args) => fetch(...args);
|
|
10
|
+
let globalFetchSupportsWebStreaming = undefined;
|
|
10
11
|
const LANGSMITH_FETCH_IMPLEMENTATION_KEY = Symbol.for("ls:fetch_implementation");
|
|
11
12
|
/**
|
|
12
13
|
* Overrides the fetch implementation used for LangSmith calls.
|
|
13
14
|
* You should use this if you need to use an implementation of fetch
|
|
14
15
|
* other than the default global (e.g. for dealing with proxies).
|
|
15
|
-
* @param fetch The new fetch
|
|
16
|
+
* @param fetch The new fetch function to use.
|
|
16
17
|
*/
|
|
17
|
-
const overrideFetchImplementation = (fetch) => {
|
|
18
|
+
const overrideFetchImplementation = (fetch, supportsWebStreaming) => {
|
|
18
19
|
globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY] = fetch;
|
|
20
|
+
globalFetchSupportsWebStreaming = supportsWebStreaming;
|
|
19
21
|
};
|
|
20
22
|
exports.overrideFetchImplementation = overrideFetchImplementation;
|
|
21
23
|
const clearFetchImplementation = () => {
|
|
22
24
|
delete globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY];
|
|
25
|
+
globalFetchSupportsWebStreaming = undefined;
|
|
23
26
|
};
|
|
24
27
|
exports.clearFetchImplementation = clearFetchImplementation;
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
if (
|
|
28
|
-
return
|
|
29
|
-
|
|
30
|
-
return
|
|
31
|
-
"Headers" in fetchImpl &&
|
|
32
|
-
"Request" in fetchImpl &&
|
|
33
|
-
"Response" in fetchImpl);
|
|
28
|
+
const _shouldStreamForGlobalFetchImplementation = () => {
|
|
29
|
+
const overriddenFetchImpl = globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY];
|
|
30
|
+
if (overriddenFetchImpl === undefined) {
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return globalFetchSupportsWebStreaming ?? false;
|
|
34
34
|
};
|
|
35
|
-
exports.
|
|
35
|
+
exports._shouldStreamForGlobalFetchImplementation = _shouldStreamForGlobalFetchImplementation;
|
|
36
36
|
/**
|
|
37
37
|
* @internal
|
|
38
38
|
*/
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Overrides the fetch implementation used for LangSmith calls.
|
|
3
3
|
* You should use this if you need to use an implementation of fetch
|
|
4
4
|
* other than the default global (e.g. for dealing with proxies).
|
|
5
|
-
* @param fetch The new fetch
|
|
5
|
+
* @param fetch The new fetch function to use.
|
|
6
6
|
*/
|
|
7
|
-
export declare const overrideFetchImplementation: (fetch: (...args: any[]) => any) => void;
|
|
7
|
+
export declare const overrideFetchImplementation: (fetch: (...args: any[]) => any, supportsWebStreaming?: boolean) => void;
|
|
8
8
|
export declare const clearFetchImplementation: () => void;
|
|
9
|
-
export declare const
|
|
9
|
+
export declare const _shouldStreamForGlobalFetchImplementation: () => boolean;
|
package/dist/singletons/fetch.js
CHANGED
|
@@ -4,28 +4,28 @@ import { getLangSmithEnvironmentVariable } from "../utils/env.js";
|
|
|
4
4
|
// https://stackoverflow.com/questions/69876859/why-does-bind-fix-failed-to-execute-fetch-on-window-illegal-invocation-err
|
|
5
5
|
// @ts-expect-error Broad typing to support a range of fetch implementations
|
|
6
6
|
const DEFAULT_FETCH_IMPLEMENTATION = (...args) => fetch(...args);
|
|
7
|
+
let globalFetchSupportsWebStreaming = undefined;
|
|
7
8
|
const LANGSMITH_FETCH_IMPLEMENTATION_KEY = Symbol.for("ls:fetch_implementation");
|
|
8
9
|
/**
|
|
9
10
|
* Overrides the fetch implementation used for LangSmith calls.
|
|
10
11
|
* You should use this if you need to use an implementation of fetch
|
|
11
12
|
* other than the default global (e.g. for dealing with proxies).
|
|
12
|
-
* @param fetch The new fetch
|
|
13
|
+
* @param fetch The new fetch function to use.
|
|
13
14
|
*/
|
|
14
|
-
export const overrideFetchImplementation = (fetch) => {
|
|
15
|
+
export const overrideFetchImplementation = (fetch, supportsWebStreaming) => {
|
|
15
16
|
globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY] = fetch;
|
|
17
|
+
globalFetchSupportsWebStreaming = supportsWebStreaming;
|
|
16
18
|
};
|
|
17
19
|
export const clearFetchImplementation = () => {
|
|
18
20
|
delete globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY];
|
|
21
|
+
globalFetchSupportsWebStreaming = undefined;
|
|
19
22
|
};
|
|
20
|
-
export const
|
|
21
|
-
const
|
|
22
|
-
if (
|
|
23
|
-
return
|
|
24
|
-
|
|
25
|
-
return
|
|
26
|
-
"Headers" in fetchImpl &&
|
|
27
|
-
"Request" in fetchImpl &&
|
|
28
|
-
"Response" in fetchImpl);
|
|
23
|
+
export const _shouldStreamForGlobalFetchImplementation = () => {
|
|
24
|
+
const overriddenFetchImpl = globalThis[LANGSMITH_FETCH_IMPLEMENTATION_KEY];
|
|
25
|
+
if (overriddenFetchImpl === undefined) {
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
return globalFetchSupportsWebStreaming ?? false;
|
|
29
29
|
};
|
|
30
30
|
/**
|
|
31
31
|
* @internal
|
package/dist/traceable.cjs
CHANGED
|
@@ -123,7 +123,7 @@ async function handleEnd(params) {
|
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
-
const
|
|
126
|
+
const _populateUsageMetadataAndOutputs = (processedOutputs, runTree) => {
|
|
127
127
|
if (runTree !== undefined) {
|
|
128
128
|
let usageMetadata;
|
|
129
129
|
try {
|
|
@@ -139,6 +139,8 @@ const _populateUsageMetadata = (processedOutputs, runTree) => {
|
|
|
139
139
|
};
|
|
140
140
|
processedOutputs.usage_metadata = usageMetadata;
|
|
141
141
|
}
|
|
142
|
+
// Set outputs on run tree as soon as available
|
|
143
|
+
runTree.outputs = processedOutputs;
|
|
142
144
|
}
|
|
143
145
|
};
|
|
144
146
|
function isAsyncFn(fn) {
|
|
@@ -170,7 +172,7 @@ async function handleRunOutputs(params) {
|
|
|
170
172
|
if (isAsyncFn(processOutputsFn)) {
|
|
171
173
|
void outputs
|
|
172
174
|
.then(async (processedOutputs) => {
|
|
173
|
-
|
|
175
|
+
_populateUsageMetadataAndOutputs(processedOutputs, runTree);
|
|
174
176
|
await childRunEndPromises;
|
|
175
177
|
await runTree?.end(processedOutputs);
|
|
176
178
|
})
|
|
@@ -203,7 +205,7 @@ async function handleRunOutputs(params) {
|
|
|
203
205
|
catch (e) {
|
|
204
206
|
console.error("Error occurred during processOutputs. Sending unprocessed outputs:", e);
|
|
205
207
|
}
|
|
206
|
-
|
|
208
|
+
_populateUsageMetadataAndOutputs(outputs, runTree);
|
|
207
209
|
void childRunEndPromises
|
|
208
210
|
.then(async () => {
|
|
209
211
|
try {
|
|
@@ -441,7 +443,7 @@ const convertSerializableArg = (arg, options) => {
|
|
|
441
443
|
*/
|
|
442
444
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
443
445
|
function traceable(wrappedFunc, config) {
|
|
444
|
-
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, extractAttachments, ...runTreeConfig } = config ?? {};
|
|
446
|
+
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, extractAttachments, on_start, ...runTreeConfig } = config ?? {};
|
|
445
447
|
const processInputsFn = processInputs ?? ((x) => x);
|
|
446
448
|
const processOutputsFn = processOutputs ?? ((x) => x);
|
|
447
449
|
const extractAttachmentsFn = extractAttachments ?? ((...x) => [undefined, runInputsToMap(x)]);
|
|
@@ -577,6 +579,7 @@ function traceable(wrappedFunc, config) {
|
|
|
577
579
|
const currentRunTree = (0, run_trees_js_1.isRunTree)(currentContext)
|
|
578
580
|
? currentContext
|
|
579
581
|
: undefined;
|
|
582
|
+
on_start?.(currentRunTree);
|
|
580
583
|
const otelContextManager = maybeCreateOtelContext(currentRunTree, config?.project_name, config?.tracer);
|
|
581
584
|
const otel_context = (0, otel_js_1.getOTELContext)();
|
|
582
585
|
const runWithContext = () => {
|
package/dist/traceable.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RunTreeConfig } from "./run_trees.js";
|
|
1
|
+
import { RunTree, RunTreeConfig } from "./run_trees.js";
|
|
2
2
|
import { Attachments, InvocationParamsSchema, KVMap } from "./schemas.js";
|
|
3
3
|
import type { TraceableFunction } from "./singletons/types.js";
|
|
4
4
|
import { OTELTracer } from "./experimental/otel/types.js";
|
|
@@ -18,6 +18,7 @@ export type TraceableConfig<Func extends (...args: any[]) => any> = Partial<Omit
|
|
|
18
18
|
aggregator?: (args: any[]) => any;
|
|
19
19
|
argsConfigPath?: [number] | [number, string];
|
|
20
20
|
tracer?: OTELTracer;
|
|
21
|
+
on_start?: (runTree: RunTree | undefined) => void;
|
|
21
22
|
__finalTracedIteratorKey?: string;
|
|
22
23
|
__deferredSerializableArgOptions?: {
|
|
23
24
|
depth?: number;
|
package/dist/traceable.js
CHANGED
|
@@ -119,7 +119,7 @@ async function handleEnd(params) {
|
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
const
|
|
122
|
+
const _populateUsageMetadataAndOutputs = (processedOutputs, runTree) => {
|
|
123
123
|
if (runTree !== undefined) {
|
|
124
124
|
let usageMetadata;
|
|
125
125
|
try {
|
|
@@ -135,6 +135,8 @@ const _populateUsageMetadata = (processedOutputs, runTree) => {
|
|
|
135
135
|
};
|
|
136
136
|
processedOutputs.usage_metadata = usageMetadata;
|
|
137
137
|
}
|
|
138
|
+
// Set outputs on run tree as soon as available
|
|
139
|
+
runTree.outputs = processedOutputs;
|
|
138
140
|
}
|
|
139
141
|
};
|
|
140
142
|
function isAsyncFn(fn) {
|
|
@@ -166,7 +168,7 @@ async function handleRunOutputs(params) {
|
|
|
166
168
|
if (isAsyncFn(processOutputsFn)) {
|
|
167
169
|
void outputs
|
|
168
170
|
.then(async (processedOutputs) => {
|
|
169
|
-
|
|
171
|
+
_populateUsageMetadataAndOutputs(processedOutputs, runTree);
|
|
170
172
|
await childRunEndPromises;
|
|
171
173
|
await runTree?.end(processedOutputs);
|
|
172
174
|
})
|
|
@@ -199,7 +201,7 @@ async function handleRunOutputs(params) {
|
|
|
199
201
|
catch (e) {
|
|
200
202
|
console.error("Error occurred during processOutputs. Sending unprocessed outputs:", e);
|
|
201
203
|
}
|
|
202
|
-
|
|
204
|
+
_populateUsageMetadataAndOutputs(outputs, runTree);
|
|
203
205
|
void childRunEndPromises
|
|
204
206
|
.then(async () => {
|
|
205
207
|
try {
|
|
@@ -437,7 +439,7 @@ const convertSerializableArg = (arg, options) => {
|
|
|
437
439
|
*/
|
|
438
440
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
439
441
|
export function traceable(wrappedFunc, config) {
|
|
440
|
-
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, extractAttachments, ...runTreeConfig } = config ?? {};
|
|
442
|
+
const { aggregator, argsConfigPath, __finalTracedIteratorKey, processInputs, processOutputs, extractAttachments, on_start, ...runTreeConfig } = config ?? {};
|
|
441
443
|
const processInputsFn = processInputs ?? ((x) => x);
|
|
442
444
|
const processOutputsFn = processOutputs ?? ((x) => x);
|
|
443
445
|
const extractAttachmentsFn = extractAttachments ?? ((...x) => [undefined, runInputsToMap(x)]);
|
|
@@ -573,6 +575,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
573
575
|
const currentRunTree = isRunTree(currentContext)
|
|
574
576
|
? currentContext
|
|
575
577
|
: undefined;
|
|
578
|
+
on_start?.(currentRunTree);
|
|
576
579
|
const otelContextManager = maybeCreateOtelContext(currentRunTree, config?.project_name, config?.tracer);
|
|
577
580
|
const otel_context = getOTELContext();
|
|
578
581
|
const runWithContext = () => {
|
|
@@ -517,6 +517,9 @@ function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
517
517
|
const strippedErrorMessage = e.message.replace(constants_js_1.STRIP_ANSI_REGEX, "");
|
|
518
518
|
const langsmithFriendlyError = new Error(strippedErrorMessage);
|
|
519
519
|
langsmithFriendlyError.rawJestError = rawError;
|
|
520
|
+
if (testContext.testRootRunTree) {
|
|
521
|
+
testContext.testRootRunTree.outputs = loggedOutput;
|
|
522
|
+
}
|
|
520
523
|
throw langsmithFriendlyError;
|
|
521
524
|
}
|
|
522
525
|
});
|
|
@@ -470,6 +470,9 @@ export function generateWrapperFromJestlikeMethods(methods, testRunnerName) {
|
|
|
470
470
|
const strippedErrorMessage = e.message.replace(STRIP_ANSI_REGEX, "");
|
|
471
471
|
const langsmithFriendlyError = new Error(strippedErrorMessage);
|
|
472
472
|
langsmithFriendlyError.rawJestError = rawError;
|
|
473
|
+
if (testContext.testRootRunTree) {
|
|
474
|
+
testContext.testRootRunTree.outputs = loggedOutput;
|
|
475
|
+
}
|
|
473
476
|
throw langsmithFriendlyError;
|
|
474
477
|
}
|
|
475
478
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "langsmith",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"description": "Client library to connect to the LangSmith Observability and Evaluation Platform.",
|
|
5
5
|
"packageManager": "yarn@1.22.19",
|
|
6
6
|
"files": [
|
|
@@ -158,7 +158,7 @@
|
|
|
158
158
|
"@ai-sdk/provider": "^3.0.0",
|
|
159
159
|
"@anthropic-ai/claude-agent-sdk": "^0.2.34",
|
|
160
160
|
"@google/genai": "^1.29.0",
|
|
161
|
-
"@anthropic-ai/sdk": "^0.
|
|
161
|
+
"@anthropic-ai/sdk": "^0.74.0",
|
|
162
162
|
"@babel/preset-env": "^7.22.4",
|
|
163
163
|
"@faker-js/faker": "^8.4.1",
|
|
164
164
|
"@jest/globals": "^29.5.0",
|
|
@@ -178,18 +178,18 @@
|
|
|
178
178
|
"@typescript-eslint/parser": "^5.59.8",
|
|
179
179
|
"ai": "^6.0.1",
|
|
180
180
|
"babel-jest": "^30.2.0",
|
|
181
|
-
"cross-env": "^
|
|
181
|
+
"cross-env": "^10.1.0",
|
|
182
182
|
"dotenv": "^16.1.3",
|
|
183
183
|
"eslint": "^8.41.0",
|
|
184
|
-
"eslint-config-prettier": "^
|
|
184
|
+
"eslint-config-prettier": "^10.1.8",
|
|
185
185
|
"eslint-plugin-import": "^2.27.5",
|
|
186
186
|
"eslint-plugin-no-instanceof": "^1.0.1",
|
|
187
187
|
"eslint-plugin-prettier": "^4.2.1",
|
|
188
188
|
"jest": "^29.5.0",
|
|
189
189
|
"langchain": "^0.3.29",
|
|
190
190
|
"msw": "^2.11.2",
|
|
191
|
-
"node-fetch": "^
|
|
192
|
-
"openai": "^
|
|
191
|
+
"node-fetch": "^3.3.2",
|
|
192
|
+
"openai": "^6.18.0",
|
|
193
193
|
"prettier": "^2.8.8",
|
|
194
194
|
"ts-jest": "^29.1.0",
|
|
195
195
|
"ts-node": "^10.9.1",
|