langsmith 0.5.21 → 0.5.23
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 +327 -10
- package/dist/client.d.ts +90 -1
- package/dist/client.js +330 -13
- package/dist/evaluation/_runner.cjs +1 -4
- package/dist/evaluation/_runner.js +1 -4
- package/dist/experimental/sandbox/client.cjs +102 -427
- package/dist/experimental/sandbox/client.d.ts +68 -159
- package/dist/experimental/sandbox/client.js +104 -429
- package/dist/experimental/sandbox/errors.cjs +1 -2
- package/dist/experimental/sandbox/errors.d.ts +1 -2
- package/dist/experimental/sandbox/errors.js +1 -2
- package/dist/experimental/sandbox/helpers.cjs +8 -98
- package/dist/experimental/sandbox/helpers.d.ts +0 -29
- package/dist/experimental/sandbox/helpers.js +9 -95
- package/dist/experimental/sandbox/index.cjs +6 -1
- package/dist/experimental/sandbox/index.d.ts +7 -2
- package/dist/experimental/sandbox/index.js +6 -1
- package/dist/experimental/sandbox/sandbox.cjs +3 -11
- package/dist/experimental/sandbox/sandbox.d.ts +3 -5
- package/dist/experimental/sandbox/sandbox.js +3 -11
- package/dist/experimental/sandbox/types.d.ts +32 -149
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/schemas.d.ts +54 -0
- package/dist/utils/error.cjs +7 -0
- package/dist/utils/error.d.ts +1 -0
- package/dist/utils/error.js +6 -0
- package/dist/utils/fast-safe-stringify/index.cjs +228 -0
- package/dist/utils/fast-safe-stringify/index.d.ts +33 -0
- package/dist/utils/fast-safe-stringify/index.js +227 -0
- package/dist/utils/prompts.cjs +7 -2
- package/dist/utils/prompts.d.ts +6 -1
- package/dist/utils/prompts.js +6 -1
- package/dist/wrappers/openai_agents.cjs +849 -0
- package/dist/wrappers/openai_agents.d.ts +92 -0
- package/dist/wrappers/openai_agents.js +845 -0
- package/package.json +22 -6
- package/wrappers/openai_agents.cjs +1 -0
- package/wrappers/openai_agents.d.cts +1 -0
- package/wrappers/openai_agents.d.ts +1 -0
- package/wrappers/openai_agents.js +1 -0
package/dist/client.js
CHANGED
|
@@ -7,12 +7,12 @@ import { getEnvironmentVariable, getLangSmithEnvVarsMetadata, getLangSmithEnviro
|
|
|
7
7
|
import { __version__ } from "./index.js";
|
|
8
8
|
import { assertUuid } from "./utils/_uuid.js";
|
|
9
9
|
import { warnOnce } from "./utils/warn.js";
|
|
10
|
-
import {
|
|
11
|
-
import { raiseForStatus, isLangSmithNotFoundError } from "./utils/error.js";
|
|
10
|
+
import { parseHubIdentifier } from "./utils/prompts.js";
|
|
11
|
+
import { raiseForStatus, isLangSmithNotFoundError, isLangSmithConflictError, } from "./utils/error.js";
|
|
12
12
|
import { promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
13
13
|
import * as fsUtils from "./utils/fs.js";
|
|
14
14
|
import { _shouldStreamForGlobalFetchImplementation, _getFetchImplementation, } from "./singletons/fetch.js";
|
|
15
|
-
import { serialize as serializePayloadForTracing } from "./utils/fast-safe-stringify/index.js";
|
|
15
|
+
import { serialize as serializePayloadForTracing, estimateSerializedSize, } from "./utils/fast-safe-stringify/index.js";
|
|
16
16
|
/**
|
|
17
17
|
* Catches timestamps without a timezone suffix.
|
|
18
18
|
*/
|
|
@@ -152,7 +152,19 @@ export class AutoBatchQueue {
|
|
|
152
152
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/Promise
|
|
153
153
|
itemPromiseResolve = resolve;
|
|
154
154
|
});
|
|
155
|
-
|
|
155
|
+
// By default we compute the exact serialized size here by stringifying
|
|
156
|
+
// the payload. This is expensive: JSON.stringify on large payloads
|
|
157
|
+
// blocks the event loop on the user's hot path.
|
|
158
|
+
//
|
|
159
|
+
// Opting into LANGSMITH_PERF_OPTIMIZATION=true switches to a cheap
|
|
160
|
+
// structural estimate instead. The estimate is only used for soft
|
|
161
|
+
// memory accounting (queue size limit and downstream async caller
|
|
162
|
+
// memory tracking), never for anything correctness-critical -- the
|
|
163
|
+
// real serialization still happens later, off the hot path, when the
|
|
164
|
+
// batch is assembled for sending.
|
|
165
|
+
const size = getLangSmithEnvironmentVariable("PERF_OPTIMIZATION") === "true"
|
|
166
|
+
? estimateSerializedSize(item.item)
|
|
167
|
+
: serializePayloadForTracing(item.item, `Serializing run with id: ${item.item.id}`).length;
|
|
156
168
|
// Check if adding this item would exceed the size limit
|
|
157
169
|
// Allow the run if the queue is empty (to support large single traces)
|
|
158
170
|
if (this.sizeBytes + size > this.maxSizeBytes && this.items.length > 0) {
|
|
@@ -279,6 +291,12 @@ export class Client {
|
|
|
279
291
|
writable: true,
|
|
280
292
|
value: void 0
|
|
281
293
|
});
|
|
294
|
+
Object.defineProperty(this, "hideMetadata", {
|
|
295
|
+
enumerable: true,
|
|
296
|
+
configurable: true,
|
|
297
|
+
writable: true,
|
|
298
|
+
value: void 0
|
|
299
|
+
});
|
|
282
300
|
Object.defineProperty(this, "omitTracedRuntimeInfo", {
|
|
283
301
|
enumerable: true,
|
|
284
302
|
configurable: true,
|
|
@@ -491,6 +509,7 @@ export class Client {
|
|
|
491
509
|
config.hideInputs ?? config.anonymizer ?? defaultConfig.hideInputs;
|
|
492
510
|
this.hideOutputs =
|
|
493
511
|
config.hideOutputs ?? config.anonymizer ?? defaultConfig.hideOutputs;
|
|
512
|
+
this.hideMetadata = config.hideMetadata ?? defaultConfig.hideMetadata;
|
|
494
513
|
this.omitTracedRuntimeInfo = config.omitTracedRuntimeInfo ?? false;
|
|
495
514
|
this.autoBatchTracing = config.autoBatchTracing ?? this.autoBatchTracing;
|
|
496
515
|
this.autoBatchQueue = new AutoBatchQueue(maxMemory);
|
|
@@ -540,12 +559,14 @@ export class Client {
|
|
|
540
559
|
const apiUrl = getLangSmithEnvironmentVariable("ENDPOINT") ?? DEFAULT_API_URL;
|
|
541
560
|
const hideInputs = getLangSmithEnvironmentVariable("HIDE_INPUTS") === "true";
|
|
542
561
|
const hideOutputs = getLangSmithEnvironmentVariable("HIDE_OUTPUTS") === "true";
|
|
562
|
+
const hideMetadata = getLangSmithEnvironmentVariable("HIDE_METADATA") === "true";
|
|
543
563
|
return {
|
|
544
564
|
apiUrl: apiUrl,
|
|
545
565
|
apiKey: apiKey,
|
|
546
566
|
webUrl: undefined,
|
|
547
567
|
hideInputs: hideInputs,
|
|
548
568
|
hideOutputs: hideOutputs,
|
|
569
|
+
hideMetadata: hideMetadata,
|
|
549
570
|
};
|
|
550
571
|
}
|
|
551
572
|
getHostUrl() {
|
|
@@ -641,6 +662,18 @@ export class Client {
|
|
|
641
662
|
}
|
|
642
663
|
return outputs;
|
|
643
664
|
}
|
|
665
|
+
async processMetadata(metadata) {
|
|
666
|
+
if (this.hideMetadata === false) {
|
|
667
|
+
return metadata;
|
|
668
|
+
}
|
|
669
|
+
if (this.hideMetadata === true) {
|
|
670
|
+
return {};
|
|
671
|
+
}
|
|
672
|
+
if (typeof this.hideMetadata === "function") {
|
|
673
|
+
return this.hideMetadata(metadata);
|
|
674
|
+
}
|
|
675
|
+
return metadata;
|
|
676
|
+
}
|
|
644
677
|
/**
|
|
645
678
|
* Filter content from new_token events to prevent streaming LLM output
|
|
646
679
|
* from being uploaded via events.
|
|
@@ -667,6 +700,12 @@ export class Client {
|
|
|
667
700
|
if (runParams.outputs !== undefined) {
|
|
668
701
|
runParams.outputs = await this.processOutputs(runParams.outputs);
|
|
669
702
|
}
|
|
703
|
+
if (runParams.extra != null && "metadata" in runParams.extra) {
|
|
704
|
+
runParams.extra = {
|
|
705
|
+
...runParams.extra,
|
|
706
|
+
metadata: await this.processMetadata(runParams.extra.metadata),
|
|
707
|
+
};
|
|
708
|
+
}
|
|
670
709
|
if (runParams.events !== undefined) {
|
|
671
710
|
runParams.events = this._filterNewTokenEvents(runParams.events);
|
|
672
711
|
}
|
|
@@ -1514,6 +1553,12 @@ export class Client {
|
|
|
1514
1553
|
if (run.outputs) {
|
|
1515
1554
|
run.outputs = await this.processOutputs(run.outputs);
|
|
1516
1555
|
}
|
|
1556
|
+
if (run.extra != null && "metadata" in run.extra) {
|
|
1557
|
+
run.extra = {
|
|
1558
|
+
...run.extra,
|
|
1559
|
+
metadata: await this.processMetadata(run.extra.metadata),
|
|
1560
|
+
};
|
|
1561
|
+
}
|
|
1517
1562
|
if (run.events) {
|
|
1518
1563
|
run.events = this._filterNewTokenEvents(run.events);
|
|
1519
1564
|
}
|
|
@@ -3750,7 +3795,7 @@ export class Client {
|
|
|
3750
3795
|
return json.commits[0].commit_hash;
|
|
3751
3796
|
}
|
|
3752
3797
|
async _likeOrUnlikePrompt(promptIdentifier, like) {
|
|
3753
|
-
const [owner, promptName, _] =
|
|
3798
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
3754
3799
|
const body = JSON.stringify({ like: like });
|
|
3755
3800
|
const response = await this.caller.call(async () => {
|
|
3756
3801
|
const res = await this._fetch(`${this.apiUrl}/likes/${owner}/${promptName}`, {
|
|
@@ -3769,7 +3814,7 @@ export class Client {
|
|
|
3769
3814
|
return response.json();
|
|
3770
3815
|
}
|
|
3771
3816
|
async _getPromptUrl(promptIdentifier) {
|
|
3772
|
-
const [owner, promptName, commitHash] =
|
|
3817
|
+
const [owner, promptName, commitHash] = parseHubIdentifier(promptIdentifier);
|
|
3773
3818
|
if (!(await this._currentTenantIsOwner(owner))) {
|
|
3774
3819
|
if (commitHash !== "latest") {
|
|
3775
3820
|
return `${this.getHostUrl()}/hub/${owner}/${promptName}/${commitHash.substring(0, 8)}`;
|
|
@@ -3861,7 +3906,7 @@ export class Client {
|
|
|
3861
3906
|
* ```
|
|
3862
3907
|
*/
|
|
3863
3908
|
async *listCommits(promptIdentifier) {
|
|
3864
|
-
const [owner, promptName, _] =
|
|
3909
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
3865
3910
|
for await (const commits of this._getPaginated(`/commits/${owner}/${promptName}/`, new URLSearchParams(), (res) => res.commits)) {
|
|
3866
3911
|
yield* commits;
|
|
3867
3912
|
}
|
|
@@ -3924,7 +3969,7 @@ export class Client {
|
|
|
3924
3969
|
* ```
|
|
3925
3970
|
*/
|
|
3926
3971
|
async getPrompt(promptIdentifier) {
|
|
3927
|
-
const [owner, promptName, _] =
|
|
3972
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
3928
3973
|
const response = await this.caller.call(async () => {
|
|
3929
3974
|
const res = await this._fetch(`${this.apiUrl}/repos/${owner}/${promptName}`, {
|
|
3930
3975
|
method: "GET",
|
|
@@ -3981,7 +4026,7 @@ export class Client {
|
|
|
3981
4026
|
You can add a handle by creating a public prompt at:\n
|
|
3982
4027
|
https://smith.langchain.com/prompts`);
|
|
3983
4028
|
}
|
|
3984
|
-
const [owner, promptName, _] =
|
|
4029
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
3985
4030
|
if (!(await this._currentTenantIsOwner(owner))) {
|
|
3986
4031
|
throw await this._ownerConflictError("create a prompt", owner);
|
|
3987
4032
|
}
|
|
@@ -4040,7 +4085,7 @@ export class Client {
|
|
|
4040
4085
|
if (!(await this.promptExists(promptIdentifier))) {
|
|
4041
4086
|
throw new Error("Prompt does not exist, you must create it first.");
|
|
4042
4087
|
}
|
|
4043
|
-
const [owner, promptName, _] =
|
|
4088
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
4044
4089
|
const resolvedParentCommitHash = options?.parentCommitHash === "latest" || !options?.parentCommitHash
|
|
4045
4090
|
? await this._getLatestCommitHash(`${owner}/${promptName}`)
|
|
4046
4091
|
: options?.parentCommitHash;
|
|
@@ -4238,7 +4283,7 @@ export class Client {
|
|
|
4238
4283
|
if (!(await this.promptExists(promptIdentifier))) {
|
|
4239
4284
|
throw new Error("Prompt does not exist, you must create it first.");
|
|
4240
4285
|
}
|
|
4241
|
-
const [owner, promptName] =
|
|
4286
|
+
const [owner, promptName] = parseHubIdentifier(promptIdentifier);
|
|
4242
4287
|
if (!(await this._currentTenantIsOwner(owner))) {
|
|
4243
4288
|
throw await this._ownerConflictError("update a prompt", owner);
|
|
4244
4289
|
}
|
|
@@ -4278,7 +4323,7 @@ export class Client {
|
|
|
4278
4323
|
if (!(await this.promptExists(promptIdentifier))) {
|
|
4279
4324
|
throw new Error("Prompt does not exist, you must create it first.");
|
|
4280
4325
|
}
|
|
4281
|
-
const [owner, promptName, _] =
|
|
4326
|
+
const [owner, promptName, _] = parseHubIdentifier(promptIdentifier);
|
|
4282
4327
|
if (!(await this._currentTenantIsOwner(owner))) {
|
|
4283
4328
|
throw await this._ownerConflictError("delete a prompt", owner);
|
|
4284
4329
|
}
|
|
@@ -4306,7 +4351,7 @@ export class Client {
|
|
|
4306
4351
|
* Fetch a prompt commit directly from the API (bypassing cache).
|
|
4307
4352
|
*/
|
|
4308
4353
|
async _fetchPromptFromApi(promptIdentifier, options) {
|
|
4309
|
-
const [owner, promptName, commitHash] =
|
|
4354
|
+
const [owner, promptName, commitHash] = parseHubIdentifier(promptIdentifier);
|
|
4310
4355
|
const response = await this.caller.call(async () => {
|
|
4311
4356
|
const res = await this._fetch(`${this.apiUrl}/commits/${owner}/${promptName}/${commitHash}${options?.includeModel ? "?include_model=true" : ""}`, {
|
|
4312
4357
|
method: "GET",
|
|
@@ -4386,6 +4431,251 @@ export class Client {
|
|
|
4386
4431
|
});
|
|
4387
4432
|
return url;
|
|
4388
4433
|
}
|
|
4434
|
+
/**
|
|
4435
|
+
* Check if an agent repo exists.
|
|
4436
|
+
*/
|
|
4437
|
+
async agentExists(identifier) {
|
|
4438
|
+
const [owner, name] = parseHubIdentifier(identifier);
|
|
4439
|
+
return this._repoExists(owner, name);
|
|
4440
|
+
}
|
|
4441
|
+
/**
|
|
4442
|
+
* Check if a skill repo exists.
|
|
4443
|
+
*/
|
|
4444
|
+
async skillExists(identifier) {
|
|
4445
|
+
const [owner, name] = parseHubIdentifier(identifier);
|
|
4446
|
+
return this._repoExists(owner, name);
|
|
4447
|
+
}
|
|
4448
|
+
/**
|
|
4449
|
+
* Pull an agent directory from Hub.
|
|
4450
|
+
* @param identifier The identifier (owner/name[:version]).
|
|
4451
|
+
* @param options.version Commit hash or tag; overrides identifier's version.
|
|
4452
|
+
*/
|
|
4453
|
+
async pullAgent(identifier, options) {
|
|
4454
|
+
return (await this._pullDirectory(identifier, "agent", options?.version));
|
|
4455
|
+
}
|
|
4456
|
+
/**
|
|
4457
|
+
* Pull a skill directory from Hub.
|
|
4458
|
+
*/
|
|
4459
|
+
async pullSkill(identifier, options) {
|
|
4460
|
+
return (await this._pullDirectory(identifier, "skill", options?.version));
|
|
4461
|
+
}
|
|
4462
|
+
/**
|
|
4463
|
+
* Push an agent to Hub. Creates the repo if missing, patches metadata if
|
|
4464
|
+
* provided, then commits the given files.
|
|
4465
|
+
* @returns The URL of the resulting commit.
|
|
4466
|
+
*/
|
|
4467
|
+
async pushAgent(identifier, options) {
|
|
4468
|
+
return this._pushDirectory(identifier, "agent", options);
|
|
4469
|
+
}
|
|
4470
|
+
/**
|
|
4471
|
+
* Push a skill to Hub.
|
|
4472
|
+
*/
|
|
4473
|
+
async pushSkill(identifier, options) {
|
|
4474
|
+
return this._pushDirectory(identifier, "skill", options);
|
|
4475
|
+
}
|
|
4476
|
+
/**
|
|
4477
|
+
* Delete an agent and all its owned child file repos.
|
|
4478
|
+
*/
|
|
4479
|
+
async deleteAgent(identifier) {
|
|
4480
|
+
return this._deleteDirectory(identifier);
|
|
4481
|
+
}
|
|
4482
|
+
/**
|
|
4483
|
+
* Delete a skill and all its owned child file repos.
|
|
4484
|
+
*/
|
|
4485
|
+
async deleteSkill(identifier) {
|
|
4486
|
+
return this._deleteDirectory(identifier);
|
|
4487
|
+
}
|
|
4488
|
+
/**
|
|
4489
|
+
* List agent repos. Yields one at a time, auto-paginating.
|
|
4490
|
+
*/
|
|
4491
|
+
async *listAgents(options) {
|
|
4492
|
+
yield* this._listReposByType("agent", options);
|
|
4493
|
+
}
|
|
4494
|
+
/**
|
|
4495
|
+
* List skill repos. Yields one at a time, auto-paginating.
|
|
4496
|
+
*/
|
|
4497
|
+
async *listSkills(options) {
|
|
4498
|
+
yield* this._listReposByType("skill", options);
|
|
4499
|
+
}
|
|
4500
|
+
async *_listReposByType(repoType, options) {
|
|
4501
|
+
const params = new URLSearchParams();
|
|
4502
|
+
params.append("repo_type", repoType);
|
|
4503
|
+
params.append("is_archived", (!!options?.isArchived).toString());
|
|
4504
|
+
if (options?.isPublic !== undefined) {
|
|
4505
|
+
params.append("is_public", options.isPublic.toString());
|
|
4506
|
+
}
|
|
4507
|
+
if (options?.query) {
|
|
4508
|
+
params.append("query", options.query);
|
|
4509
|
+
}
|
|
4510
|
+
for await (const repos of this._getPaginated("/repos", params, (res) => res.repos)) {
|
|
4511
|
+
yield* repos;
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
async _pullDirectory(identifier, repoType, version) {
|
|
4515
|
+
const [owner, name, parsedVersion] = parseHubIdentifier(identifier);
|
|
4516
|
+
const resolvedVersion = version ?? (parsedVersion !== "latest" ? parsedVersion : undefined);
|
|
4517
|
+
const url = new URL(`${this.apiUrl}/v1/platform/hub/repos/${owner}/${name}/directories`);
|
|
4518
|
+
url.searchParams.set("repo_type", repoType);
|
|
4519
|
+
if (resolvedVersion) {
|
|
4520
|
+
url.searchParams.set("commit", resolvedVersion);
|
|
4521
|
+
}
|
|
4522
|
+
const response = await this.caller.call(async () => {
|
|
4523
|
+
const res = await this._fetch(url.toString(), {
|
|
4524
|
+
method: "GET",
|
|
4525
|
+
headers: this._mergedHeaders,
|
|
4526
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4527
|
+
...this.fetchOptions,
|
|
4528
|
+
});
|
|
4529
|
+
await raiseForStatus(res, "pull directory");
|
|
4530
|
+
return res;
|
|
4531
|
+
});
|
|
4532
|
+
return (await response.json());
|
|
4533
|
+
}
|
|
4534
|
+
async _pushDirectory(identifier, repoType, options) {
|
|
4535
|
+
if (options.parentCommit !== undefined &&
|
|
4536
|
+
(options.parentCommit.length < 8 || options.parentCommit.length > 64)) {
|
|
4537
|
+
throw new Error("parent_commit must be 8-64 characters");
|
|
4538
|
+
}
|
|
4539
|
+
const [owner, name] = parseHubIdentifier(identifier);
|
|
4540
|
+
if (!(await this._currentTenantIsOwner(owner))) {
|
|
4541
|
+
throw await this._ownerConflictError(`push ${repoType}`, owner);
|
|
4542
|
+
}
|
|
4543
|
+
if (await this._repoExists(owner, name)) {
|
|
4544
|
+
if (options.description !== undefined ||
|
|
4545
|
+
options.readme !== undefined ||
|
|
4546
|
+
options.tags !== undefined ||
|
|
4547
|
+
options.isPublic !== undefined) {
|
|
4548
|
+
await this._updateRepoMetadata(owner, name, options);
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
4551
|
+
else {
|
|
4552
|
+
const REPO_HANDLE_PATTERN = /^[a-z][a-z0-9-_]*$/;
|
|
4553
|
+
if (!REPO_HANDLE_PATTERN.test(name)) {
|
|
4554
|
+
throw new Error(`Invalid repo_handle ${JSON.stringify(name)}: must match ${REPO_HANDLE_PATTERN}`);
|
|
4555
|
+
}
|
|
4556
|
+
await this._createRepo(name, repoType, options);
|
|
4557
|
+
}
|
|
4558
|
+
const body = { files: options.files };
|
|
4559
|
+
if (options.parentCommit) {
|
|
4560
|
+
body.parent_commit = options.parentCommit;
|
|
4561
|
+
}
|
|
4562
|
+
const response = await this.caller.call(async () => {
|
|
4563
|
+
const res = await this._fetch(`${this.apiUrl}/v1/platform/hub/repos/${owner}/${name}/directories/commits`, {
|
|
4564
|
+
method: "POST",
|
|
4565
|
+
headers: {
|
|
4566
|
+
...this._mergedHeaders,
|
|
4567
|
+
"Content-Type": "application/json",
|
|
4568
|
+
},
|
|
4569
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4570
|
+
...this.fetchOptions,
|
|
4571
|
+
body: JSON.stringify(body),
|
|
4572
|
+
});
|
|
4573
|
+
await raiseForStatus(res, `push ${repoType}`);
|
|
4574
|
+
return res;
|
|
4575
|
+
});
|
|
4576
|
+
const data = (await response.json());
|
|
4577
|
+
const commitHash = data.commit.commit_hash;
|
|
4578
|
+
return `${this.getHostUrl()}/hub/${owner}/${name}:${commitHash.slice(0, 8)}`;
|
|
4579
|
+
}
|
|
4580
|
+
async _deleteDirectory(identifier) {
|
|
4581
|
+
const [owner, name] = parseHubIdentifier(identifier);
|
|
4582
|
+
if (!(await this._currentTenantIsOwner(owner))) {
|
|
4583
|
+
throw await this._ownerConflictError("delete", owner);
|
|
4584
|
+
}
|
|
4585
|
+
await this.caller.call(async () => {
|
|
4586
|
+
const res = await this._fetch(`${this.apiUrl}/v1/platform/hub/repos/${owner}/${name}/directories`, {
|
|
4587
|
+
method: "DELETE",
|
|
4588
|
+
headers: this._mergedHeaders,
|
|
4589
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4590
|
+
...this.fetchOptions,
|
|
4591
|
+
});
|
|
4592
|
+
await raiseForStatus(res, "delete directory");
|
|
4593
|
+
return res;
|
|
4594
|
+
});
|
|
4595
|
+
}
|
|
4596
|
+
async _repoExists(owner, name) {
|
|
4597
|
+
try {
|
|
4598
|
+
await this.caller.call(async () => {
|
|
4599
|
+
const res = await this._fetch(`${this.apiUrl}/repos/${owner}/${name}`, {
|
|
4600
|
+
method: "GET",
|
|
4601
|
+
headers: this._mergedHeaders,
|
|
4602
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4603
|
+
...this.fetchOptions,
|
|
4604
|
+
});
|
|
4605
|
+
await raiseForStatus(res, "check repo exists");
|
|
4606
|
+
return res;
|
|
4607
|
+
});
|
|
4608
|
+
return true;
|
|
4609
|
+
}
|
|
4610
|
+
catch (e) {
|
|
4611
|
+
if (isLangSmithNotFoundError(e)) {
|
|
4612
|
+
return false;
|
|
4613
|
+
}
|
|
4614
|
+
throw e;
|
|
4615
|
+
}
|
|
4616
|
+
}
|
|
4617
|
+
async _createRepo(name, repoType, options) {
|
|
4618
|
+
const body = {
|
|
4619
|
+
repo_handle: name,
|
|
4620
|
+
repo_type: repoType,
|
|
4621
|
+
is_public: !!options.isPublic,
|
|
4622
|
+
};
|
|
4623
|
+
if (options.description !== undefined)
|
|
4624
|
+
body.description = options.description;
|
|
4625
|
+
if (options.readme !== undefined)
|
|
4626
|
+
body.readme = options.readme;
|
|
4627
|
+
if (options.tags !== undefined)
|
|
4628
|
+
body.tags = options.tags;
|
|
4629
|
+
try {
|
|
4630
|
+
await this.caller.call(async () => {
|
|
4631
|
+
const res = await this._fetch(`${this.apiUrl}/repos/`, {
|
|
4632
|
+
method: "POST",
|
|
4633
|
+
headers: {
|
|
4634
|
+
...this._mergedHeaders,
|
|
4635
|
+
"Content-Type": "application/json",
|
|
4636
|
+
},
|
|
4637
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4638
|
+
...this.fetchOptions,
|
|
4639
|
+
body: JSON.stringify(body),
|
|
4640
|
+
});
|
|
4641
|
+
await raiseForStatus(res, `create ${repoType}`);
|
|
4642
|
+
return res;
|
|
4643
|
+
});
|
|
4644
|
+
}
|
|
4645
|
+
catch (e) {
|
|
4646
|
+
if (isLangSmithConflictError(e)) {
|
|
4647
|
+
return;
|
|
4648
|
+
}
|
|
4649
|
+
throw e;
|
|
4650
|
+
}
|
|
4651
|
+
}
|
|
4652
|
+
async _updateRepoMetadata(owner, name, options) {
|
|
4653
|
+
const body = {};
|
|
4654
|
+
if (options.description !== undefined)
|
|
4655
|
+
body.description = options.description;
|
|
4656
|
+
if (options.readme !== undefined)
|
|
4657
|
+
body.readme = options.readme;
|
|
4658
|
+
if (options.tags !== undefined)
|
|
4659
|
+
body.tags = options.tags;
|
|
4660
|
+
if (options.isPublic !== undefined)
|
|
4661
|
+
body.is_public = options.isPublic;
|
|
4662
|
+
if (Object.keys(body).length === 0)
|
|
4663
|
+
return;
|
|
4664
|
+
await this.caller.call(async () => {
|
|
4665
|
+
const res = await this._fetch(`${this.apiUrl}/repos/${owner}/${name}`, {
|
|
4666
|
+
method: "PATCH",
|
|
4667
|
+
headers: {
|
|
4668
|
+
...this._mergedHeaders,
|
|
4669
|
+
"Content-Type": "application/json",
|
|
4670
|
+
},
|
|
4671
|
+
signal: AbortSignal.timeout(this.timeout_ms),
|
|
4672
|
+
...this.fetchOptions,
|
|
4673
|
+
body: JSON.stringify(body),
|
|
4674
|
+
});
|
|
4675
|
+
await raiseForStatus(res, "update repo metadata");
|
|
4676
|
+
return res;
|
|
4677
|
+
});
|
|
4678
|
+
}
|
|
4389
4679
|
/**
|
|
4390
4680
|
* Clone a public dataset to your own langsmith tenant.
|
|
4391
4681
|
* This operation is idempotent. If you already have a dataset with the given name,
|
|
@@ -4525,6 +4815,33 @@ export class Client {
|
|
|
4525
4815
|
await getDefaultOTLPTracerComponents()?.DEFAULT_LANGSMITH_SPAN_PROCESSOR?.forceFlush();
|
|
4526
4816
|
}
|
|
4527
4817
|
}
|
|
4818
|
+
/**
|
|
4819
|
+
* Returns a string representation of the Client instance.
|
|
4820
|
+
* This method is called when the object is converted to a string
|
|
4821
|
+
* or logged, ensuring sensitive information like API keys is not exposed.
|
|
4822
|
+
*
|
|
4823
|
+
* @returns A string representation of the Client.
|
|
4824
|
+
*/
|
|
4825
|
+
toString() {
|
|
4826
|
+
const params = [`apiUrl=${JSON.stringify(this.apiUrl)}`];
|
|
4827
|
+
if (this.webUrl !== undefined) {
|
|
4828
|
+
params.push(`webUrl=${JSON.stringify(this.webUrl)}`);
|
|
4829
|
+
}
|
|
4830
|
+
if (this.workspaceId !== undefined) {
|
|
4831
|
+
params.push(`workspaceId=${JSON.stringify(this.workspaceId)}`);
|
|
4832
|
+
}
|
|
4833
|
+
return `[LangSmithClient ${params.join(" ")}]`;
|
|
4834
|
+
}
|
|
4835
|
+
/**
|
|
4836
|
+
* Custom inspect method for Node.js.
|
|
4837
|
+
* This method is called when the object is inspected in the Node.js REPL
|
|
4838
|
+
* or with console.log, ensuring sensitive information like API keys is not exposed.
|
|
4839
|
+
*
|
|
4840
|
+
* @returns A string representation of the Client for inspection.
|
|
4841
|
+
*/
|
|
4842
|
+
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
4843
|
+
return this.toString();
|
|
4844
|
+
}
|
|
4528
4845
|
}
|
|
4529
4846
|
Object.defineProperty(Client, "_fallbackDirsCreated", {
|
|
4530
4847
|
enumerable: true,
|
|
@@ -726,10 +726,7 @@ async function _evaluate(target, fields) {
|
|
|
726
726
|
const standardFields = fields;
|
|
727
727
|
const [experiment_, newRuns] = await _resolveExperiment(fields.experiment ?? null, runs, client);
|
|
728
728
|
let manager = await new _ExperimentManager({
|
|
729
|
-
data:
|
|
730
|
-
examples: Array.isArray(standardFields.data)
|
|
731
|
-
? standardFields.data
|
|
732
|
-
: undefined,
|
|
729
|
+
data: standardFields.data,
|
|
733
730
|
client,
|
|
734
731
|
metadata: fields.metadata,
|
|
735
732
|
experiment: experiment_ ?? fields.experimentPrefix,
|
|
@@ -719,10 +719,7 @@ async function _evaluate(target, fields) {
|
|
|
719
719
|
const standardFields = fields;
|
|
720
720
|
const [experiment_, newRuns] = await _resolveExperiment(fields.experiment ?? null, runs, client);
|
|
721
721
|
let manager = await new _ExperimentManager({
|
|
722
|
-
data:
|
|
723
|
-
examples: Array.isArray(standardFields.data)
|
|
724
|
-
? standardFields.data
|
|
725
|
-
: undefined,
|
|
722
|
+
data: standardFields.data,
|
|
726
723
|
client,
|
|
727
724
|
metadata: fields.metadata,
|
|
728
725
|
experiment: experiment_ ?? fields.experimentPrefix,
|