langsmith 0.10.4 → 0.10.6
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/address.cjs +119 -0
- package/dist/address.d.ts +13 -0
- package/dist/address.js +107 -0
- package/dist/client.cjs +68 -22
- package/dist/client.d.ts +13 -0
- package/dist/client.js +68 -22
- package/dist/evaluation/_runner.cjs +47 -5
- package/dist/evaluation/_runner.d.ts +12 -0
- package/dist/evaluation/_runner.js +47 -5
- package/dist/experimental/otel/constants.cjs +5 -1
- package/dist/experimental/otel/constants.d.ts +3 -0
- package/dist/experimental/otel/constants.js +3 -0
- package/dist/experimental/otel/translator.cjs +14 -0
- package/dist/experimental/otel/translator.js +14 -0
- package/dist/index.cjs +4 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/run_trees.cjs +154 -24
- package/dist/run_trees.d.ts +13 -1
- package/dist/run_trees.js +154 -24
- package/dist/sandbox/access_delegation.cjs +24 -0
- package/dist/sandbox/access_delegation.d.ts +15 -0
- package/dist/sandbox/access_delegation.js +21 -0
- package/dist/sandbox/client.cjs +70 -5
- package/dist/sandbox/client.d.ts +18 -0
- package/dist/sandbox/client.js +70 -5
- package/dist/sandbox/command_handle.cjs +34 -0
- package/dist/sandbox/command_handle.d.ts +10 -0
- package/dist/sandbox/command_handle.js +34 -0
- package/dist/sandbox/errors.cjs +12 -1
- package/dist/sandbox/errors.d.ts +7 -0
- package/dist/sandbox/errors.js +10 -0
- package/dist/sandbox/helpers.cjs +129 -0
- package/dist/sandbox/helpers.d.ts +29 -0
- package/dist/sandbox/helpers.js +123 -0
- package/dist/sandbox/index.cjs +12 -1
- package/dist/sandbox/index.d.ts +8 -2
- package/dist/sandbox/index.js +4 -1
- package/dist/sandbox/mounts.cjs +21 -3
- package/dist/sandbox/mounts.d.ts +7 -1
- package/dist/sandbox/mounts.js +21 -3
- package/dist/sandbox/proxy_config.cjs +41 -10
- package/dist/sandbox/proxy_config.d.ts +33 -6
- package/dist/sandbox/proxy_config.js +40 -10
- package/dist/sandbox/sandbox.cjs +160 -4
- package/dist/sandbox/sandbox.d.ts +71 -1
- package/dist/sandbox/sandbox.js +161 -5
- package/dist/sandbox/service_url.cjs +125 -0
- package/dist/sandbox/service_url.d.ts +50 -0
- package/dist/sandbox/service_url.js +120 -0
- package/dist/sandbox/types.d.ts +251 -8
- package/dist/sandbox/verify.cjs +300 -0
- package/dist/sandbox/verify.d.ts +122 -0
- package/dist/sandbox/verify.js +296 -0
- package/dist/sandbox/ws_execute.cjs +31 -1
- package/dist/sandbox/ws_execute.d.ts +9 -0
- package/dist/sandbox/ws_execute.js +31 -1
- package/dist/schemas.d.ts +5 -0
- package/dist/traceable.cjs +7 -1
- package/dist/traceable.js +7 -1
- package/dist/utils/agent_addressing.cjs +92 -0
- package/dist/utils/agent_addressing.d.ts +30 -0
- package/dist/utils/agent_addressing.js +83 -0
- package/dist/utils/env.cjs +2 -0
- package/dist/utils/env.js +2 -0
- package/dist/utils/error.cjs +17 -22
- package/dist/utils/error.js +17 -22
- package/package.json +5 -5
package/dist/address.cjs
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EnvAddressError = void 0;
|
|
4
|
+
exports.normalizeAddress = normalizeAddress;
|
|
5
|
+
exports.wireKeys = wireKeys;
|
|
6
|
+
exports.envNames = envNames;
|
|
7
|
+
exports.toWire = toWire;
|
|
8
|
+
exports.fromWire = fromWire;
|
|
9
|
+
exports.addressFromEnv = addressFromEnv;
|
|
10
|
+
exports.seed = seed;
|
|
11
|
+
exports.sameAddress = sameAddress;
|
|
12
|
+
// Wire key per field; env var is `LANGSMITH_<WIRE KEY>`.
|
|
13
|
+
const FIELDS = {
|
|
14
|
+
agentId: "agent_id",
|
|
15
|
+
agentEnvironment: "agent_environment",
|
|
16
|
+
};
|
|
17
|
+
// The server's agent id rule: a DNS label, so a hostname can carry the id.
|
|
18
|
+
const AGENT_ID_PATTERN = /^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
19
|
+
// Not `utils/env`: it imports the package index, which imports this module.
|
|
20
|
+
function getEnv(name) {
|
|
21
|
+
try {
|
|
22
|
+
// eslint-disable-next-line no-process-env
|
|
23
|
+
return typeof process !== "undefined" ? process.env?.[name] : undefined;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
30
|
+
class EnvAddressError extends Error {
|
|
31
|
+
constructor(message) {
|
|
32
|
+
super(message);
|
|
33
|
+
this.name = "EnvAddressError";
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
exports.EnvAddressError = EnvAddressError;
|
|
37
|
+
/**
|
|
38
|
+
* @internal Validate `value` and return a frozen copy of its fields.
|
|
39
|
+
* @throws If it isn't an object with exactly the address fields, or a value is invalid.
|
|
40
|
+
*/
|
|
41
|
+
function normalizeAddress(value) {
|
|
42
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
43
|
+
throw new Error("`address` must be an object: { agentId, agentEnvironment }.");
|
|
44
|
+
}
|
|
45
|
+
const fields = value;
|
|
46
|
+
const unknown = Object.keys(fields).filter((key) => !(key in FIELDS));
|
|
47
|
+
if (unknown.length > 0) {
|
|
48
|
+
throw new Error(`Unknown address fields: ${unknown.join(", ")}.`);
|
|
49
|
+
}
|
|
50
|
+
for (const name of Object.keys(FIELDS)) {
|
|
51
|
+
const field = fields[name];
|
|
52
|
+
if (typeof field !== "string" || field === "") {
|
|
53
|
+
throw new Error(`Address ${name} must be a non-empty string.`);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
const { agentId, agentEnvironment } = fields;
|
|
57
|
+
if (!AGENT_ID_PATTERN.test(agentId)) {
|
|
58
|
+
throw new Error("Address agentId must be 1 to 63 lowercase ASCII letters, digits, or " +
|
|
59
|
+
"hyphens, start with a letter, and end with a letter or digit, got " +
|
|
60
|
+
`${JSON.stringify(agentId)}. Use an id such as "support-agent".`);
|
|
61
|
+
}
|
|
62
|
+
return Object.freeze({ agentId, agentEnvironment });
|
|
63
|
+
}
|
|
64
|
+
/** @internal */
|
|
65
|
+
function wireKeys() {
|
|
66
|
+
return Object.values(FIELDS);
|
|
67
|
+
}
|
|
68
|
+
/** @internal */
|
|
69
|
+
function envNames() {
|
|
70
|
+
return wireKeys().map((key) => `LANGSMITH_${key.toUpperCase()}`);
|
|
71
|
+
}
|
|
72
|
+
/** @internal */
|
|
73
|
+
function toWire(address) {
|
|
74
|
+
return {
|
|
75
|
+
[FIELDS.agentId]: address.agentId,
|
|
76
|
+
[FIELDS.agentEnvironment]: address.agentEnvironment,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/** @internal `undefined` if no field is set; throws if only some are. */
|
|
80
|
+
function fromWire(values) {
|
|
81
|
+
const fields = Object.fromEntries(Object.entries(FIELDS).map(([name, key]) => [
|
|
82
|
+
name,
|
|
83
|
+
values[key] ?? undefined,
|
|
84
|
+
]));
|
|
85
|
+
const missing = Object.entries(FIELDS)
|
|
86
|
+
.filter(([name]) => fields[name] === undefined)
|
|
87
|
+
.map(([, key]) => key);
|
|
88
|
+
if (missing.length === Object.keys(FIELDS).length) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
if (missing.length > 0) {
|
|
92
|
+
throw new Error(`An address needs ${missing.join(" and ")} as well.`);
|
|
93
|
+
}
|
|
94
|
+
return normalizeAddress(fields);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* @internal
|
|
98
|
+
* @throws {EnvAddressError} If only some `LANGSMITH_AGENT_*` vars are set, or one is invalid.
|
|
99
|
+
*/
|
|
100
|
+
function addressFromEnv() {
|
|
101
|
+
const values = Object.fromEntries(wireKeys().map((key, i) => [key, getEnv(envNames()[i]) || undefined]));
|
|
102
|
+
try {
|
|
103
|
+
return fromWire(values);
|
|
104
|
+
}
|
|
105
|
+
catch (e) {
|
|
106
|
+
throw new EnvAddressError(`The LANGSMITH_AGENT_* env vars can't address a run: ${e.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** @internal Replica id derivation seed. */
|
|
110
|
+
function seed(address) {
|
|
111
|
+
return ["agent", ...Object.values(toWire(address))].join("/");
|
|
112
|
+
}
|
|
113
|
+
/** @internal */
|
|
114
|
+
function sameAddress(a, b) {
|
|
115
|
+
if (!a || !b) {
|
|
116
|
+
return a === b;
|
|
117
|
+
}
|
|
118
|
+
return a.agentId === b.agentId && a.agentEnvironment === b.agentEnvironment;
|
|
119
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* (beta) An address that runs are sent to instead of a project.
|
|
3
|
+
* Enabled per workspace; a workspace without it rejects the runs.
|
|
4
|
+
*/
|
|
5
|
+
export interface Address {
|
|
6
|
+
/** 1 to 63 lowercase ASCII letters, digits or hyphens; starts with a letter. */
|
|
7
|
+
agentId: string;
|
|
8
|
+
agentEnvironment: string;
|
|
9
|
+
}
|
|
10
|
+
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
11
|
+
export declare class EnvAddressError extends Error {
|
|
12
|
+
constructor(message: string);
|
|
13
|
+
}
|
package/dist/address.js
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
// Wire key per field; env var is `LANGSMITH_<WIRE KEY>`.
|
|
2
|
+
const FIELDS = {
|
|
3
|
+
agentId: "agent_id",
|
|
4
|
+
agentEnvironment: "agent_environment",
|
|
5
|
+
};
|
|
6
|
+
// The server's agent id rule: a DNS label, so a hostname can carry the id.
|
|
7
|
+
const AGENT_ID_PATTERN = /^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
8
|
+
// Not `utils/env`: it imports the package index, which imports this module.
|
|
9
|
+
function getEnv(name) {
|
|
10
|
+
try {
|
|
11
|
+
// eslint-disable-next-line no-process-env
|
|
12
|
+
return typeof process !== "undefined" ? process.env?.[name] : undefined;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return undefined;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
19
|
+
export class EnvAddressError extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = "EnvAddressError";
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* @internal Validate `value` and return a frozen copy of its fields.
|
|
27
|
+
* @throws If it isn't an object with exactly the address fields, or a value is invalid.
|
|
28
|
+
*/
|
|
29
|
+
export function normalizeAddress(value) {
|
|
30
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
31
|
+
throw new Error("`address` must be an object: { agentId, agentEnvironment }.");
|
|
32
|
+
}
|
|
33
|
+
const fields = value;
|
|
34
|
+
const unknown = Object.keys(fields).filter((key) => !(key in FIELDS));
|
|
35
|
+
if (unknown.length > 0) {
|
|
36
|
+
throw new Error(`Unknown address fields: ${unknown.join(", ")}.`);
|
|
37
|
+
}
|
|
38
|
+
for (const name of Object.keys(FIELDS)) {
|
|
39
|
+
const field = fields[name];
|
|
40
|
+
if (typeof field !== "string" || field === "") {
|
|
41
|
+
throw new Error(`Address ${name} must be a non-empty string.`);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
const { agentId, agentEnvironment } = fields;
|
|
45
|
+
if (!AGENT_ID_PATTERN.test(agentId)) {
|
|
46
|
+
throw new Error("Address agentId must be 1 to 63 lowercase ASCII letters, digits, or " +
|
|
47
|
+
"hyphens, start with a letter, and end with a letter or digit, got " +
|
|
48
|
+
`${JSON.stringify(agentId)}. Use an id such as "support-agent".`);
|
|
49
|
+
}
|
|
50
|
+
return Object.freeze({ agentId, agentEnvironment });
|
|
51
|
+
}
|
|
52
|
+
/** @internal */
|
|
53
|
+
export function wireKeys() {
|
|
54
|
+
return Object.values(FIELDS);
|
|
55
|
+
}
|
|
56
|
+
/** @internal */
|
|
57
|
+
export function envNames() {
|
|
58
|
+
return wireKeys().map((key) => `LANGSMITH_${key.toUpperCase()}`);
|
|
59
|
+
}
|
|
60
|
+
/** @internal */
|
|
61
|
+
export function toWire(address) {
|
|
62
|
+
return {
|
|
63
|
+
[FIELDS.agentId]: address.agentId,
|
|
64
|
+
[FIELDS.agentEnvironment]: address.agentEnvironment,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/** @internal `undefined` if no field is set; throws if only some are. */
|
|
68
|
+
export function fromWire(values) {
|
|
69
|
+
const fields = Object.fromEntries(Object.entries(FIELDS).map(([name, key]) => [
|
|
70
|
+
name,
|
|
71
|
+
values[key] ?? undefined,
|
|
72
|
+
]));
|
|
73
|
+
const missing = Object.entries(FIELDS)
|
|
74
|
+
.filter(([name]) => fields[name] === undefined)
|
|
75
|
+
.map(([, key]) => key);
|
|
76
|
+
if (missing.length === Object.keys(FIELDS).length) {
|
|
77
|
+
return undefined;
|
|
78
|
+
}
|
|
79
|
+
if (missing.length > 0) {
|
|
80
|
+
throw new Error(`An address needs ${missing.join(" and ")} as well.`);
|
|
81
|
+
}
|
|
82
|
+
return normalizeAddress(fields);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* @internal
|
|
86
|
+
* @throws {EnvAddressError} If only some `LANGSMITH_AGENT_*` vars are set, or one is invalid.
|
|
87
|
+
*/
|
|
88
|
+
export function addressFromEnv() {
|
|
89
|
+
const values = Object.fromEntries(wireKeys().map((key, i) => [key, getEnv(envNames()[i]) || undefined]));
|
|
90
|
+
try {
|
|
91
|
+
return fromWire(values);
|
|
92
|
+
}
|
|
93
|
+
catch (e) {
|
|
94
|
+
throw new EnvAddressError(`The LANGSMITH_AGENT_* env vars can't address a run: ${e.message}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/** @internal Replica id derivation seed. */
|
|
98
|
+
export function seed(address) {
|
|
99
|
+
return ["agent", ...Object.values(toWire(address))].join("/");
|
|
100
|
+
}
|
|
101
|
+
/** @internal */
|
|
102
|
+
export function sameAddress(a, b) {
|
|
103
|
+
if (!a || !b) {
|
|
104
|
+
return a === b;
|
|
105
|
+
}
|
|
106
|
+
return a.agentId === b.agentId && a.agentEnvironment === b.agentEnvironment;
|
|
107
|
+
}
|
package/dist/client.cjs
CHANGED
|
@@ -47,6 +47,8 @@ const index_js_2 = require("./_openapi_client/index.cjs");
|
|
|
47
47
|
const _uuid_js_1 = require("./utils/_uuid.cjs");
|
|
48
48
|
const sampling_js_1 = require("./utils/sampling.cjs");
|
|
49
49
|
const warn_js_1 = require("./utils/warn.cjs");
|
|
50
|
+
const address_js_1 = require("./address.cjs");
|
|
51
|
+
const agent_addressing_js_1 = require("./utils/agent_addressing.cjs");
|
|
50
52
|
const v2_migration_js_1 = require("./utils/v2_migration.cjs");
|
|
51
53
|
const prompts_js_1 = require("./utils/prompts.cjs");
|
|
52
54
|
const error_js_1 = require("./utils/error.cjs");
|
|
@@ -82,6 +84,26 @@ function _normalizeRunTimestamps(run) {
|
|
|
82
84
|
end_time: _ensureUTCTimestamp(run.end_time),
|
|
83
85
|
};
|
|
84
86
|
}
|
|
87
|
+
/** Index creates by id (last wins); warns when one id goes to two projects. */
|
|
88
|
+
function indexRunCreatesById(creates) {
|
|
89
|
+
const byId = {};
|
|
90
|
+
for (const run of creates) {
|
|
91
|
+
if (!run.id) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
const previous = byId[run.id];
|
|
95
|
+
if (previous !== undefined && previous.session_name !== run.session_name) {
|
|
96
|
+
console.warn(`LangSmith run ${run.id} was queued for two projects with the same id ` +
|
|
97
|
+
`(${JSON.stringify(previous.session_name)} and ` +
|
|
98
|
+
`${JSON.stringify(run.session_name)}); only one of the projects will ` +
|
|
99
|
+
"keep the run. This usually means two write replicas both keep the " +
|
|
100
|
+
"original run ids, for example a replica marked `primary` plus one " +
|
|
101
|
+
"for the run's own project.");
|
|
102
|
+
}
|
|
103
|
+
byId[run.id] = run;
|
|
104
|
+
}
|
|
105
|
+
return byId;
|
|
106
|
+
}
|
|
85
107
|
function mergeRuntimeEnvIntoRun(run, cachedEnvVars, omitTracedRuntimeInfo, tracingSampleRate) {
|
|
86
108
|
if (omitTracedRuntimeInfo) {
|
|
87
109
|
return run;
|
|
@@ -866,6 +888,10 @@ class Client {
|
|
|
866
888
|
throw new Error("Trace batch concurrency must be positive.");
|
|
867
889
|
}
|
|
868
890
|
this.debug = config.debug ?? this.debug;
|
|
891
|
+
if (this.debug) {
|
|
892
|
+
const source = config.apiUrl != null ? "apiUrl option" : defaultConfig.apiUrlSource;
|
|
893
|
+
console.log(`LangSmith API URL ${this.apiUrl} resolved from ${source}`);
|
|
894
|
+
}
|
|
869
895
|
this.fetchImplementation = config.fetchImplementation;
|
|
870
896
|
// Failed trace dump configuration
|
|
871
897
|
this.failedTracesDir =
|
|
@@ -917,6 +943,7 @@ class Client {
|
|
|
917
943
|
}
|
|
918
944
|
// Cache metadata env vars once during construction to avoid repeatedly scanning process.env
|
|
919
945
|
this.cachedLSEnvVarsForMetadata = (0, env_js_1.getLangSmithEnvVarsMetadata)();
|
|
946
|
+
(0, agent_addressing_js_1.warnOnEnv)();
|
|
920
947
|
// Initialize prompt cache
|
|
921
948
|
// Handle backwards compatibility for deprecated `cache` parameter
|
|
922
949
|
if (config.cache !== undefined && config.disablePromptCache) {
|
|
@@ -952,12 +979,18 @@ class Client {
|
|
|
952
979
|
const envWorkspaceId = (0, env_js_1.getLangSmithEnvironmentVariable)("WORKSPACE_ID");
|
|
953
980
|
const envAuthSet = (0, profiles_js_1.hasValue)(envApiKey);
|
|
954
981
|
const apiUrl = envApiUrl ?? profileConfig.apiUrl ?? profiles_js_1.DEFAULT_API_URL;
|
|
982
|
+
const apiUrlSource = envApiUrl != null
|
|
983
|
+
? "LANGSMITH_ENDPOINT / LANGCHAIN_ENDPOINT environment variable"
|
|
984
|
+
: profileConfig.apiUrl != null
|
|
985
|
+
? "profile config"
|
|
986
|
+
: "built-in default";
|
|
955
987
|
const workspaceId = envWorkspaceId ?? profileConfig.workspaceId;
|
|
956
988
|
const hideInputs = (0, env_js_1.getLangSmithEnvironmentVariable)("HIDE_INPUTS") === "true";
|
|
957
989
|
const hideOutputs = (0, env_js_1.getLangSmithEnvironmentVariable)("HIDE_OUTPUTS") === "true";
|
|
958
990
|
const hideMetadata = (0, env_js_1.getLangSmithEnvironmentVariable)("HIDE_METADATA") === "true";
|
|
959
991
|
return {
|
|
960
992
|
apiUrl: apiUrl,
|
|
993
|
+
apiUrlSource,
|
|
961
994
|
apiKey: envApiKey,
|
|
962
995
|
webUrl: undefined,
|
|
963
996
|
hideInputs: hideInputs,
|
|
@@ -1278,8 +1311,9 @@ class Client {
|
|
|
1278
1311
|
return event;
|
|
1279
1312
|
});
|
|
1280
1313
|
}
|
|
1281
|
-
async prepareRunCreateOrUpdateInputs(run) {
|
|
1314
|
+
async prepareRunCreateOrUpdateInputs(run, options) {
|
|
1282
1315
|
const runParams = { ...run };
|
|
1316
|
+
(0, agent_addressing_js_1.applyToPayload)(runParams, { update: options?.update ?? false });
|
|
1283
1317
|
if (runParams.inputs !== undefined) {
|
|
1284
1318
|
runParams.inputs = await this.processInputs(runParams.inputs);
|
|
1285
1319
|
}
|
|
@@ -1761,8 +1795,24 @@ class Client {
|
|
|
1761
1795
|
...this._mergedHeaders,
|
|
1762
1796
|
"Content-Type": "application/json",
|
|
1763
1797
|
};
|
|
1798
|
+
const address = (0, agent_addressing_js_1.checkAddress)(run.address);
|
|
1799
|
+
// `RunTree.postRun` passes a built run body, carrying the wire `session_name`.
|
|
1800
|
+
const bodySessionName = run.session_name;
|
|
1801
|
+
(0, agent_addressing_js_1.rejectConflicting)(run.project_name ?? bodySessionName, address);
|
|
1764
1802
|
const session_name = run.project_name;
|
|
1765
1803
|
delete run.project_name;
|
|
1804
|
+
if (!session_name && bodySessionName == null && !address) {
|
|
1805
|
+
try {
|
|
1806
|
+
run.address = (0, agent_addressing_js_1.resolveFromEnv)()[1];
|
|
1807
|
+
}
|
|
1808
|
+
catch (e) {
|
|
1809
|
+
if (!(e instanceof address_js_1.EnvAddressError)) {
|
|
1810
|
+
throw e;
|
|
1811
|
+
}
|
|
1812
|
+
(0, agent_addressing_js_1.logUntraced)(e);
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1766
1816
|
const runCreate = await this.prepareRunCreateOrUpdateInputs({
|
|
1767
1817
|
session_name,
|
|
1768
1818
|
...run,
|
|
@@ -1811,15 +1861,10 @@ class Client {
|
|
|
1811
1861
|
return;
|
|
1812
1862
|
}
|
|
1813
1863
|
let preparedCreateParams = await Promise.all(runCreates?.map((create) => this.prepareRunCreateOrUpdateInputs(create)) ?? []);
|
|
1814
|
-
let preparedUpdateParams = await Promise.all(runUpdates?.map((update) => this.prepareRunCreateOrUpdateInputs(update)) ?? []);
|
|
1864
|
+
let preparedUpdateParams = await Promise.all(runUpdates?.map((update) => this.prepareRunCreateOrUpdateInputs(update, { update: true })) ?? []);
|
|
1865
|
+
// Index even without updates: the collision warning must see creates-only batches.
|
|
1866
|
+
const createById = indexRunCreatesById(preparedCreateParams);
|
|
1815
1867
|
if (preparedCreateParams.length > 0 && preparedUpdateParams.length > 0) {
|
|
1816
|
-
const createById = preparedCreateParams.reduce((params, run) => {
|
|
1817
|
-
if (!run.id) {
|
|
1818
|
-
return params;
|
|
1819
|
-
}
|
|
1820
|
-
params[run.id] = run;
|
|
1821
|
-
return params;
|
|
1822
|
-
}, {});
|
|
1823
1868
|
const standaloneUpdates = [];
|
|
1824
1869
|
for (const updateParam of preparedUpdateParams) {
|
|
1825
1870
|
if (updateParam.id !== undefined && createById[updateParam.id]) {
|
|
@@ -1910,7 +1955,7 @@ class Client {
|
|
|
1910
1955
|
}
|
|
1911
1956
|
let preparedUpdateParams = [];
|
|
1912
1957
|
for (const update of runUpdates ?? []) {
|
|
1913
|
-
preparedUpdateParams.push(await this.prepareRunCreateOrUpdateInputs(update));
|
|
1958
|
+
preparedUpdateParams.push(await this.prepareRunCreateOrUpdateInputs(update, { update: true }));
|
|
1914
1959
|
}
|
|
1915
1960
|
// require trace_id and dotted_order
|
|
1916
1961
|
const invalidRunCreate = preparedCreateParams.find((runCreate) => {
|
|
@@ -1926,14 +1971,8 @@ class Client {
|
|
|
1926
1971
|
throw new Error(`Multipart ingest requires "trace_id" and "dotted_order" to be set when updating a run`);
|
|
1927
1972
|
}
|
|
1928
1973
|
// combine post and patch dicts where possible
|
|
1974
|
+
const createById = indexRunCreatesById(preparedCreateParams);
|
|
1929
1975
|
if (preparedCreateParams.length > 0 && preparedUpdateParams.length > 0) {
|
|
1930
|
-
const createById = preparedCreateParams.reduce((params, run) => {
|
|
1931
|
-
if (!run.id) {
|
|
1932
|
-
return params;
|
|
1933
|
-
}
|
|
1934
|
-
params[run.id] = run;
|
|
1935
|
-
return params;
|
|
1936
|
-
}, {});
|
|
1937
1976
|
const standaloneUpdates = [];
|
|
1938
1977
|
for (const updateParam of preparedUpdateParams) {
|
|
1939
1978
|
if (updateParam.id !== undefined && createById[updateParam.id]) {
|
|
@@ -2183,6 +2222,8 @@ class Client {
|
|
|
2183
2222
|
if (run.events) {
|
|
2184
2223
|
run.events = this._filterNewTokenEvents(run.events);
|
|
2185
2224
|
}
|
|
2225
|
+
// On `run` too: the direct path below serializes it.
|
|
2226
|
+
(0, agent_addressing_js_1.applyToPayload)(run, { update: true });
|
|
2186
2227
|
// TODO: Untangle types
|
|
2187
2228
|
const data = { ...run, id: runId };
|
|
2188
2229
|
if (!this._filterForSampling([data]).length) {
|
|
@@ -2274,6 +2315,9 @@ class Client {
|
|
|
2274
2315
|
"Use client.runs.getURL() instead. " +
|
|
2275
2316
|
"See https://docs.langchain.com/langsmith/smithdb-sdk-migration-runs#runs-get-url for the migration guide.", { type: "DeprecationWarning", code: "LANGSMITH_DEPRECATED_GET_RUN_URL" });
|
|
2276
2317
|
if (run !== undefined) {
|
|
2318
|
+
if (!run.session_id && run.address) {
|
|
2319
|
+
throw new Error("Addressed runs have no URL until read back.");
|
|
2320
|
+
}
|
|
2277
2321
|
let sessionId;
|
|
2278
2322
|
if (run.session_id) {
|
|
2279
2323
|
sessionId = run.session_id;
|
|
@@ -3603,7 +3647,7 @@ class Client {
|
|
|
3603
3647
|
if (attachment_urls) {
|
|
3604
3648
|
example.attachments = Object.entries(attachment_urls).reduce((acc, [key, value]) => {
|
|
3605
3649
|
acc[key.slice("attachment.".length)] = {
|
|
3606
|
-
presigned_url: value.presigned_url,
|
|
3650
|
+
presigned_url: new URL(value.presigned_url, this.apiUrl).href,
|
|
3607
3651
|
mime_type: value.mime_type,
|
|
3608
3652
|
};
|
|
3609
3653
|
return acc;
|
|
@@ -3671,7 +3715,7 @@ class Client {
|
|
|
3671
3715
|
if (attachment_urls) {
|
|
3672
3716
|
example.attachments = Object.entries(attachment_urls).reduce((acc, [key, value]) => {
|
|
3673
3717
|
acc[key.slice("attachment.".length)] = {
|
|
3674
|
-
presigned_url: value.presigned_url,
|
|
3718
|
+
presigned_url: new URL(value.presigned_url, this.apiUrl).href,
|
|
3675
3719
|
mime_type: value.mime_type || undefined,
|
|
3676
3720
|
};
|
|
3677
3721
|
return acc;
|
|
@@ -3896,16 +3940,18 @@ class Client {
|
|
|
3896
3940
|
});
|
|
3897
3941
|
}
|
|
3898
3942
|
async createFeedback(runIdOrParams, keyArg, optionsArg) {
|
|
3899
|
-
const { runId = null, key, score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, feedbackConfig, projectId, traceId, comparativeExperimentId, sessionId, startTime, extendTraceRetention, } = typeof runIdOrParams === "object" && runIdOrParams !== null
|
|
3943
|
+
const { runId = null, key, score, value, correction, comment, sourceInfo, feedbackSourceType = "api", sourceRunId, feedbackId, feedbackConfig, projectId, traceId, comparativeExperimentId, sessionId, startTime, extendTraceRetention, address: rawAddress, } = typeof runIdOrParams === "object" && runIdOrParams !== null
|
|
3900
3944
|
? runIdOrParams
|
|
3901
3945
|
: { runId: runIdOrParams, key: keyArg, ...optionsArg };
|
|
3946
|
+
const address = (0, agent_addressing_js_1.checkAddress)(rawAddress);
|
|
3947
|
+
(0, agent_addressing_js_1.rejectConflicting)(sessionId ?? projectId, address);
|
|
3902
3948
|
if (!runId && !projectId) {
|
|
3903
3949
|
throw new Error("One of runId or projectId must be provided");
|
|
3904
3950
|
}
|
|
3905
3951
|
if (runId && projectId) {
|
|
3906
3952
|
throw new Error("Only one of runId or projectId can be provided");
|
|
3907
3953
|
}
|
|
3908
|
-
if (runId && sessionId === undefined) {
|
|
3954
|
+
if (runId && sessionId === undefined && !address) {
|
|
3909
3955
|
await this._checkFeedbackSessionId();
|
|
3910
3956
|
}
|
|
3911
3957
|
const feedback_source = {
|
|
@@ -3941,7 +3987,7 @@ class Client {
|
|
|
3941
3987
|
if (samplingId != null && !this._shouldSample(samplingId)) {
|
|
3942
3988
|
return feedback;
|
|
3943
3989
|
}
|
|
3944
|
-
const body = JSON.stringify(feedback);
|
|
3990
|
+
const body = JSON.stringify(address ? { ...feedback, ...(0, address_js_1.toWire)(address) } : feedback);
|
|
3945
3991
|
const url = `${this.apiUrl}/feedback`;
|
|
3946
3992
|
await this.caller.call(async () => {
|
|
3947
3993
|
const res = await this._fetch(url, {
|
package/dist/client.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { AnnotationQueues } from "./_openapi_client/resources/annotation-queues/
|
|
|
11
11
|
import { Threads } from "./_openapi_client/resources/threads.js";
|
|
12
12
|
import { Traces } from "./_openapi_client/resources/traces.js";
|
|
13
13
|
import { Public } from "./_openapi_client/resources/public/public.js";
|
|
14
|
+
import { type Address } from "./address.js";
|
|
14
15
|
import { PromptCache } from "./utils/prompt_cache/index.js";
|
|
15
16
|
import { ProfileAuth } from "./utils/profiles.js";
|
|
16
17
|
export interface ClientConfig {
|
|
@@ -300,6 +301,7 @@ interface UploadCSVParams {
|
|
|
300
301
|
}
|
|
301
302
|
type DefaultClientConfig = {
|
|
302
303
|
apiUrl: string;
|
|
304
|
+
apiUrlSource: string;
|
|
303
305
|
apiKey?: string;
|
|
304
306
|
webUrl?: string;
|
|
305
307
|
hideInputs?: boolean;
|
|
@@ -325,6 +327,8 @@ interface CreateRunParams {
|
|
|
325
327
|
child_runs?: RunCreate[];
|
|
326
328
|
parent_run_id?: string;
|
|
327
329
|
project_name?: string;
|
|
330
|
+
/** (beta) Send the run to this address instead of a project. */
|
|
331
|
+
address?: Address;
|
|
328
332
|
revision_id?: string;
|
|
329
333
|
trace_id?: string;
|
|
330
334
|
dotted_order?: string;
|
|
@@ -377,11 +381,20 @@ export type CreateFeedbackParams = CreateFeedbackOptions & ({
|
|
|
377
381
|
/** The session (project) ID of the run. */
|
|
378
382
|
sessionId: string;
|
|
379
383
|
projectId?: never;
|
|
384
|
+
address?: never;
|
|
385
|
+
} | {
|
|
386
|
+
/** The run to provide feedback on. */
|
|
387
|
+
runId: string;
|
|
388
|
+
/** (beta) The address the run was sent to, e.g. `runTree.address`. */
|
|
389
|
+
address: Address;
|
|
390
|
+
sessionId?: never;
|
|
391
|
+
projectId?: never;
|
|
380
392
|
} | {
|
|
381
393
|
runId?: null;
|
|
382
394
|
/** The project (or experiment) to provide feedback on. */
|
|
383
395
|
projectId: string;
|
|
384
396
|
sessionId?: never;
|
|
397
|
+
address?: never;
|
|
385
398
|
});
|
|
386
399
|
export type CreateExampleOptions = {
|
|
387
400
|
/** The ID of the dataset to create the example in. */
|