langsmith 0.10.6 → 0.10.8
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 +80 -90
- package/dist/address.d.ts +31 -9
- package/dist/address.js +76 -82
- package/dist/client.cjs +1 -1
- package/dist/client.js +2 -2
- package/dist/experimental/otel/exporter.cjs +21 -4
- package/dist/experimental/otel/exporter.d.ts +4 -2
- package/dist/experimental/otel/exporter.js +21 -4
- package/dist/index.cjs +3 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/run_trees.cjs +17 -31
- package/dist/run_trees.js +18 -32
- package/dist/schemas.d.ts +0 -2
- package/dist/traceable.cjs +23 -4
- package/dist/traceable.js +23 -4
- package/dist/utils/agent_addressing.cjs +8 -10
- package/dist/utils/agent_addressing.d.ts +4 -5
- package/dist/utils/agent_addressing.js +7 -9
- package/package.json +1 -1
package/dist/address.cjs
CHANGED
|
@@ -1,31 +1,40 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EnvAddressError = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.
|
|
3
|
+
exports.address = exports.EnvAddressError = void 0;
|
|
4
|
+
exports.agent = agent;
|
|
5
|
+
exports.parse = parse;
|
|
6
|
+
exports.fromEnv = fromEnv;
|
|
6
7
|
exports.envNames = envNames;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
/**
|
|
9
|
+
* (beta) Addresses that name where runs are sent instead of a project.
|
|
10
|
+
* Enabled per workspace; a workspace without it rejects the runs.
|
|
11
|
+
*
|
|
12
|
+
* An address is a plain string, `lrn:agents/{id}/environments/{environment}`,
|
|
13
|
+
* typed as a template literal so a literal is checked at compile time. A
|
|
14
|
+
* dynamic `string` goes through `address.parse`, which validates it at
|
|
15
|
+
* runtime (JS callers are validated the same way). The environment is always
|
|
16
|
+
* rendered lowercase.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { address, traceable } from "langsmith";
|
|
21
|
+
*
|
|
22
|
+
* const support = address.agent("customer-support", "production");
|
|
23
|
+
* const handle = traceable(fn, { address: support });
|
|
24
|
+
* // or a literal: { address: "lrn:agents/customer-support/environments/staging" }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
const env_js_1 = require("./utils/env.cjs");
|
|
17
28
|
// The server's agent id rule: a DNS label, so a hostname can carry the id.
|
|
18
29
|
const AGENT_ID_PATTERN = /^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
}
|
|
30
|
+
const ENVIRONMENTS = [
|
|
31
|
+
"local",
|
|
32
|
+
"development",
|
|
33
|
+
"staging",
|
|
34
|
+
"production",
|
|
35
|
+
];
|
|
36
|
+
const ADDRESS_PATTERN = /^lrn:agents\/([^/]*)\/environments\/([^/]*)$/;
|
|
37
|
+
const ENV_NAMES = ["LANGSMITH_AGENT_ID", "LANGSMITH_AGENT_ENVIRONMENT"];
|
|
29
38
|
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
30
39
|
class EnvAddressError extends Error {
|
|
31
40
|
constructor(message) {
|
|
@@ -35,85 +44,66 @@ class EnvAddressError extends Error {
|
|
|
35
44
|
}
|
|
36
45
|
exports.EnvAddressError = EnvAddressError;
|
|
37
46
|
/**
|
|
38
|
-
*
|
|
39
|
-
* @
|
|
47
|
+
* (beta) Build the address of an agent's environment.
|
|
48
|
+
* @param agentId 1 to 63 lowercase ASCII letters, digits or hyphens, starting
|
|
49
|
+
* with a letter and ending with a letter or digit.
|
|
50
|
+
* @param agentEnvironment One of `local`, `development`, `staging` or
|
|
51
|
+
* `production`, in any case.
|
|
52
|
+
* @throws If a value is invalid.
|
|
40
53
|
*/
|
|
41
|
-
function
|
|
42
|
-
if (
|
|
43
|
-
throw new Error("
|
|
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 " +
|
|
54
|
+
function agent(agentId, agentEnvironment) {
|
|
55
|
+
if (typeof agentId !== "string" || !AGENT_ID_PATTERN.test(agentId)) {
|
|
56
|
+
throw new Error("Address agent id must be 1 to 63 lowercase ASCII letters, digits, or " +
|
|
59
57
|
"hyphens, start with a letter, and end with a letter or digit, got " +
|
|
60
58
|
`${JSON.stringify(agentId)}. Use an id such as "support-agent".`);
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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;
|
|
60
|
+
const environment = typeof agentEnvironment === "string"
|
|
61
|
+
? agentEnvironment.toLowerCase()
|
|
62
|
+
: undefined;
|
|
63
|
+
if (environment === undefined || !ENVIRONMENTS.includes(environment)) {
|
|
64
|
+
throw new Error(`Address environment must be one of ${ENVIRONMENTS.join(", ")}, got ` +
|
|
65
|
+
`${JSON.stringify(agentEnvironment)}.`);
|
|
90
66
|
}
|
|
91
|
-
|
|
92
|
-
|
|
67
|
+
return `lrn:agents/${agentId}/environments/${environment}`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* (beta) Validate an address string, lowercasing its environment.
|
|
71
|
+
* Only agent addresses, `lrn:agents/{id}/environments/{environment}`, exist.
|
|
72
|
+
* @throws If `value` is not a valid agent address.
|
|
73
|
+
*/
|
|
74
|
+
function parse(value) {
|
|
75
|
+
const match = typeof value === "string" ? ADDRESS_PATTERN.exec(value) : undefined;
|
|
76
|
+
if (!match) {
|
|
77
|
+
throw new Error("An address must be a string like " +
|
|
78
|
+
`"lrn:agents/{id}/environments/{environment}", got ${JSON.stringify(value)}.`);
|
|
93
79
|
}
|
|
94
|
-
return
|
|
80
|
+
return agent(match[1], match[2]);
|
|
95
81
|
}
|
|
96
82
|
/**
|
|
97
|
-
*
|
|
98
|
-
*
|
|
83
|
+
* (beta) Read the address named by `LANGSMITH_AGENT_ID` and
|
|
84
|
+
* `LANGSMITH_AGENT_ENVIRONMENT`; `undefined` if neither is set.
|
|
85
|
+
* @throws {EnvAddressError} If only one is set, or a value is invalid.
|
|
99
86
|
*/
|
|
100
|
-
function
|
|
101
|
-
const values =
|
|
87
|
+
function fromEnv() {
|
|
88
|
+
const values = ENV_NAMES.map((name) => (0, env_js_1.getEnvironmentVariable)(name));
|
|
89
|
+
if (!values.some(Boolean)) {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
102
92
|
try {
|
|
103
|
-
|
|
93
|
+
const missing = ENV_NAMES.filter((_, i) => !values[i]);
|
|
94
|
+
if (missing.length > 0) {
|
|
95
|
+
throw new Error(`An address needs ${missing.join(" and ")} as well.`);
|
|
96
|
+
}
|
|
97
|
+
return agent(values[0], values[1]);
|
|
104
98
|
}
|
|
105
99
|
catch (e) {
|
|
106
|
-
|
|
100
|
+
const present = ENV_NAMES.flatMap((name, i) => values[i] ? [`${name}=${JSON.stringify(values[i])}`] : []).join(", ");
|
|
101
|
+
throw new EnvAddressError(`The LANGSMITH_AGENT_* env vars can't address a run (${present}): ${e.message}`);
|
|
107
102
|
}
|
|
108
103
|
}
|
|
109
|
-
/**
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
function sameAddress(a, b) {
|
|
115
|
-
if (!a || !b) {
|
|
116
|
-
return a === b;
|
|
117
|
-
}
|
|
118
|
-
return a.agentId === b.agentId && a.agentEnvironment === b.agentEnvironment;
|
|
104
|
+
/** (beta) Build, validate and read addresses. */
|
|
105
|
+
exports.address = { agent, parse, fromEnv };
|
|
106
|
+
/** @internal The `LANGSMITH_AGENT_*` env var names an address reads. */
|
|
107
|
+
function envNames() {
|
|
108
|
+
return ENV_NAMES;
|
|
119
109
|
}
|
package/dist/address.d.ts
CHANGED
|
@@ -1,13 +1,35 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
|
|
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
|
-
}
|
|
1
|
+
/** (beta) An agent environment. */
|
|
2
|
+
export type Environment = "local" | "development" | "staging" | "production";
|
|
3
|
+
/** (beta) An address string, `lrn:agents/{id}/environments/{environment}`. */
|
|
4
|
+
export type Address = `lrn:agents/${string}/environments/${Environment}`;
|
|
10
5
|
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
11
6
|
export declare class EnvAddressError extends Error {
|
|
12
7
|
constructor(message: string);
|
|
13
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* (beta) Build the address of an agent's environment.
|
|
11
|
+
* @param agentId 1 to 63 lowercase ASCII letters, digits or hyphens, starting
|
|
12
|
+
* with a letter and ending with a letter or digit.
|
|
13
|
+
* @param agentEnvironment One of `local`, `development`, `staging` or
|
|
14
|
+
* `production`, in any case.
|
|
15
|
+
* @throws If a value is invalid.
|
|
16
|
+
*/
|
|
17
|
+
export declare function agent(agentId: string, agentEnvironment: Environment | (string & {})): Address;
|
|
18
|
+
/**
|
|
19
|
+
* (beta) Validate an address string, lowercasing its environment.
|
|
20
|
+
* Only agent addresses, `lrn:agents/{id}/environments/{environment}`, exist.
|
|
21
|
+
* @throws If `value` is not a valid agent address.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parse(value: string): Address;
|
|
24
|
+
/**
|
|
25
|
+
* (beta) Read the address named by `LANGSMITH_AGENT_ID` and
|
|
26
|
+
* `LANGSMITH_AGENT_ENVIRONMENT`; `undefined` if neither is set.
|
|
27
|
+
* @throws {EnvAddressError} If only one is set, or a value is invalid.
|
|
28
|
+
*/
|
|
29
|
+
export declare function fromEnv(): Address | undefined;
|
|
30
|
+
/** (beta) Build, validate and read addresses. */
|
|
31
|
+
export declare const address: {
|
|
32
|
+
agent: typeof agent;
|
|
33
|
+
parse: typeof parse;
|
|
34
|
+
fromEnv: typeof fromEnv;
|
|
35
|
+
};
|
package/dist/address.js
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* (beta) Addresses that name where runs are sent instead of a project.
|
|
3
|
+
* Enabled per workspace; a workspace without it rejects the runs.
|
|
4
|
+
*
|
|
5
|
+
* An address is a plain string, `lrn:agents/{id}/environments/{environment}`,
|
|
6
|
+
* typed as a template literal so a literal is checked at compile time. A
|
|
7
|
+
* dynamic `string` goes through `address.parse`, which validates it at
|
|
8
|
+
* runtime (JS callers are validated the same way). The environment is always
|
|
9
|
+
* rendered lowercase.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { address, traceable } from "langsmith";
|
|
14
|
+
*
|
|
15
|
+
* const support = address.agent("customer-support", "production");
|
|
16
|
+
* const handle = traceable(fn, { address: support });
|
|
17
|
+
* // or a literal: { address: "lrn:agents/customer-support/environments/staging" }
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
import { getEnvironmentVariable } from "./utils/env.js";
|
|
6
21
|
// The server's agent id rule: a DNS label, so a hostname can carry the id.
|
|
7
22
|
const AGENT_ID_PATTERN = /^[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
}
|
|
23
|
+
const ENVIRONMENTS = [
|
|
24
|
+
"local",
|
|
25
|
+
"development",
|
|
26
|
+
"staging",
|
|
27
|
+
"production",
|
|
28
|
+
];
|
|
29
|
+
const ADDRESS_PATTERN = /^lrn:agents\/([^/]*)\/environments\/([^/]*)$/;
|
|
30
|
+
const ENV_NAMES = ["LANGSMITH_AGENT_ID", "LANGSMITH_AGENT_ENVIRONMENT"];
|
|
18
31
|
/** The `LANGSMITH_AGENT_*` / project env vars name half an address, or both. */
|
|
19
32
|
export class EnvAddressError extends Error {
|
|
20
33
|
constructor(message) {
|
|
@@ -23,85 +36,66 @@ export class EnvAddressError extends Error {
|
|
|
23
36
|
}
|
|
24
37
|
}
|
|
25
38
|
/**
|
|
26
|
-
*
|
|
27
|
-
* @
|
|
39
|
+
* (beta) Build the address of an agent's environment.
|
|
40
|
+
* @param agentId 1 to 63 lowercase ASCII letters, digits or hyphens, starting
|
|
41
|
+
* with a letter and ending with a letter or digit.
|
|
42
|
+
* @param agentEnvironment One of `local`, `development`, `staging` or
|
|
43
|
+
* `production`, in any case.
|
|
44
|
+
* @throws If a value is invalid.
|
|
28
45
|
*/
|
|
29
|
-
export function
|
|
30
|
-
if (
|
|
31
|
-
throw new Error("
|
|
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 " +
|
|
46
|
+
export function agent(agentId, agentEnvironment) {
|
|
47
|
+
if (typeof agentId !== "string" || !AGENT_ID_PATTERN.test(agentId)) {
|
|
48
|
+
throw new Error("Address agent id must be 1 to 63 lowercase ASCII letters, digits, or " +
|
|
47
49
|
"hyphens, start with a letter, and end with a letter or digit, got " +
|
|
48
50
|
`${JSON.stringify(agentId)}. Use an id such as "support-agent".`);
|
|
49
51
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
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;
|
|
52
|
+
const environment = typeof agentEnvironment === "string"
|
|
53
|
+
? agentEnvironment.toLowerCase()
|
|
54
|
+
: undefined;
|
|
55
|
+
if (environment === undefined || !ENVIRONMENTS.includes(environment)) {
|
|
56
|
+
throw new Error(`Address environment must be one of ${ENVIRONMENTS.join(", ")}, got ` +
|
|
57
|
+
`${JSON.stringify(agentEnvironment)}.`);
|
|
78
58
|
}
|
|
79
|
-
|
|
80
|
-
|
|
59
|
+
return `lrn:agents/${agentId}/environments/${environment}`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* (beta) Validate an address string, lowercasing its environment.
|
|
63
|
+
* Only agent addresses, `lrn:agents/{id}/environments/{environment}`, exist.
|
|
64
|
+
* @throws If `value` is not a valid agent address.
|
|
65
|
+
*/
|
|
66
|
+
export function parse(value) {
|
|
67
|
+
const match = typeof value === "string" ? ADDRESS_PATTERN.exec(value) : undefined;
|
|
68
|
+
if (!match) {
|
|
69
|
+
throw new Error("An address must be a string like " +
|
|
70
|
+
`"lrn:agents/{id}/environments/{environment}", got ${JSON.stringify(value)}.`);
|
|
81
71
|
}
|
|
82
|
-
return
|
|
72
|
+
return agent(match[1], match[2]);
|
|
83
73
|
}
|
|
84
74
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
75
|
+
* (beta) Read the address named by `LANGSMITH_AGENT_ID` and
|
|
76
|
+
* `LANGSMITH_AGENT_ENVIRONMENT`; `undefined` if neither is set.
|
|
77
|
+
* @throws {EnvAddressError} If only one is set, or a value is invalid.
|
|
87
78
|
*/
|
|
88
|
-
export function
|
|
89
|
-
const values =
|
|
79
|
+
export function fromEnv() {
|
|
80
|
+
const values = ENV_NAMES.map((name) => getEnvironmentVariable(name));
|
|
81
|
+
if (!values.some(Boolean)) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
90
84
|
try {
|
|
91
|
-
|
|
85
|
+
const missing = ENV_NAMES.filter((_, i) => !values[i]);
|
|
86
|
+
if (missing.length > 0) {
|
|
87
|
+
throw new Error(`An address needs ${missing.join(" and ")} as well.`);
|
|
88
|
+
}
|
|
89
|
+
return agent(values[0], values[1]);
|
|
92
90
|
}
|
|
93
91
|
catch (e) {
|
|
94
|
-
|
|
92
|
+
const present = ENV_NAMES.flatMap((name, i) => values[i] ? [`${name}=${JSON.stringify(values[i])}`] : []).join(", ");
|
|
93
|
+
throw new EnvAddressError(`The LANGSMITH_AGENT_* env vars can't address a run (${present}): ${e.message}`);
|
|
95
94
|
}
|
|
96
95
|
}
|
|
97
|
-
/**
|
|
98
|
-
export
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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;
|
|
96
|
+
/** (beta) Build, validate and read addresses. */
|
|
97
|
+
export const address = { agent, parse, fromEnv };
|
|
98
|
+
/** @internal The `LANGSMITH_AGENT_*` env var names an address reads. */
|
|
99
|
+
export function envNames() {
|
|
100
|
+
return ENV_NAMES;
|
|
107
101
|
}
|
package/dist/client.cjs
CHANGED
|
@@ -3987,7 +3987,7 @@ class Client {
|
|
|
3987
3987
|
if (samplingId != null && !this._shouldSample(samplingId)) {
|
|
3988
3988
|
return feedback;
|
|
3989
3989
|
}
|
|
3990
|
-
const body = JSON.stringify(address ? { ...feedback,
|
|
3990
|
+
const body = JSON.stringify(address ? { ...feedback, address } : feedback);
|
|
3991
3991
|
const url = `${this.apiUrl}/feedback`;
|
|
3992
3992
|
await this.caller.call(async () => {
|
|
3993
3993
|
const res = await this._fetch(url, {
|
package/dist/client.js
CHANGED
|
@@ -9,7 +9,7 @@ import { Langsmith as OpenAPILangsmith } from "./_openapi_client/index.js";
|
|
|
9
9
|
import { assertUuid } from "./utils/_uuid.js";
|
|
10
10
|
import { isSampledById } from "./utils/sampling.js";
|
|
11
11
|
import { warnOnce } from "./utils/warn.js";
|
|
12
|
-
import { EnvAddressError
|
|
12
|
+
import { EnvAddressError } from "./address.js";
|
|
13
13
|
import { applyToPayload, checkAddress, logUntraced, rejectConflicting, resolveFromEnv, warnOnEnv, } from "./utils/agent_addressing.js";
|
|
14
14
|
import { getQueryBackend, QueryBackend } from "./utils/v2_migration.js";
|
|
15
15
|
import { parseHubIdentifier } from "./utils/prompts.js";
|
|
@@ -3948,7 +3948,7 @@ export class Client {
|
|
|
3948
3948
|
if (samplingId != null && !this._shouldSample(samplingId)) {
|
|
3949
3949
|
return feedback;
|
|
3950
3950
|
}
|
|
3951
|
-
const body = JSON.stringify(address ? { ...feedback,
|
|
3951
|
+
const body = JSON.stringify(address ? { ...feedback, address } : feedback);
|
|
3952
3952
|
const url = `${this.apiUrl}/feedback`;
|
|
3953
3953
|
await this.caller.call(async () => {
|
|
3954
3954
|
const res = await this._fetch(url, {
|
|
@@ -39,6 +39,7 @@ const constants = __importStar(require("./constants.cjs"));
|
|
|
39
39
|
const env_js_1 = require("../../env.cjs");
|
|
40
40
|
const env_js_2 = require("../../utils/env.cjs");
|
|
41
41
|
const vercel_js_1 = require("../../utils/vercel.cjs");
|
|
42
|
+
const warn_js_1 = require("../../utils/warn.cjs");
|
|
42
43
|
/**
|
|
43
44
|
* Convert headers string in format "name=value,name2=value2" to object
|
|
44
45
|
*/
|
|
@@ -60,8 +61,10 @@ function parseHeadersString(headersStr) {
|
|
|
60
61
|
*
|
|
61
62
|
* This exporter automatically configures itself with LangSmith endpoints and API keys,
|
|
62
63
|
* based on your LANGSMITH_API_KEY and LANGSMITH_PROJECT environment variables.
|
|
63
|
-
*
|
|
64
|
-
*
|
|
64
|
+
* OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is a full traces URL and takes precedence over
|
|
65
|
+
* OTEL_EXPORTER_OTLP_ENDPOINT, a base URL to which /v1/traces is appended unless
|
|
66
|
+
* it already ends in /traces for compatibility.
|
|
67
|
+
* Also respects OTEL_EXPORTER_OTLP_HEADERS if set.
|
|
65
68
|
*
|
|
66
69
|
* @param config - Optional configuration object that accepts all OTLPTraceExporter parameters.
|
|
67
70
|
* If not provided, uses default LangSmith configuration:
|
|
@@ -74,8 +77,22 @@ class LangSmithOTLPTraceExporter extends exporter_trace_otlp_proto_1.OTLPTraceEx
|
|
|
74
77
|
const defaultLsEndpoint = (0, env_js_2.getLangSmithEnvironmentVariable)("ENDPOINT") ||
|
|
75
78
|
"https://api.smith.langchain.com";
|
|
76
79
|
const defaultBaseUrl = defaultLsEndpoint.replace(/\/$/, "");
|
|
77
|
-
const
|
|
78
|
-
`${defaultBaseUrl}/otel
|
|
80
|
+
const baseEndpoint = (0, env_js_2.getEnvironmentVariable)("OTEL_EXPORTER_OTLP_ENDPOINT") ||
|
|
81
|
+
`${defaultBaseUrl}/otel`;
|
|
82
|
+
const defaultUrl = (0, env_js_2.getEnvironmentVariable)("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") ||
|
|
83
|
+
(baseEndpoint.endsWith("/traces")
|
|
84
|
+
? baseEndpoint
|
|
85
|
+
: `${baseEndpoint.replace(/\/$/, "")}/v1/traces`);
|
|
86
|
+
if (config?.url === undefined &&
|
|
87
|
+
!(0, env_js_2.getEnvironmentVariable)("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") &&
|
|
88
|
+
baseEndpoint.endsWith("/traces")) {
|
|
89
|
+
(0, warn_js_1.warnOnce)("LangSmith now treats OTEL_EXPORTER_OTLP_ENDPOINT as a base URL and " +
|
|
90
|
+
"appends /v1/traces. Your value ends in /traces, so it is being " +
|
|
91
|
+
"preserved unchanged for compatibility. This fallback will be " +
|
|
92
|
+
"removed in the v1 release of the SDK. Move this full URL to " +
|
|
93
|
+
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT to use standard OpenTelemetry " +
|
|
94
|
+
"configuration.");
|
|
95
|
+
}
|
|
79
96
|
// Configure headers with API key and project if available
|
|
80
97
|
let headers = config?.headers;
|
|
81
98
|
if (headers === undefined) {
|
|
@@ -43,8 +43,10 @@ export type LangSmithOTLPTraceExporterConfig = ConstructorParameters<typeof OTLP
|
|
|
43
43
|
*
|
|
44
44
|
* This exporter automatically configures itself with LangSmith endpoints and API keys,
|
|
45
45
|
* based on your LANGSMITH_API_KEY and LANGSMITH_PROJECT environment variables.
|
|
46
|
-
*
|
|
47
|
-
*
|
|
46
|
+
* OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is a full traces URL and takes precedence over
|
|
47
|
+
* OTEL_EXPORTER_OTLP_ENDPOINT, a base URL to which /v1/traces is appended unless
|
|
48
|
+
* it already ends in /traces for compatibility.
|
|
49
|
+
* Also respects OTEL_EXPORTER_OTLP_HEADERS if set.
|
|
48
50
|
*
|
|
49
51
|
* @param config - Optional configuration object that accepts all OTLPTraceExporter parameters.
|
|
50
52
|
* If not provided, uses default LangSmith configuration:
|
|
@@ -3,6 +3,7 @@ import * as constants from "./constants.js";
|
|
|
3
3
|
import { isEnvTracingEnabled } from "../../env.js";
|
|
4
4
|
import { getEnvironmentVariable, getLangSmithEnvironmentVariable, } from "../../utils/env.js";
|
|
5
5
|
import { extractUsageMetadata } from "../../utils/vercel.js";
|
|
6
|
+
import { warnOnce } from "../../utils/warn.js";
|
|
6
7
|
/**
|
|
7
8
|
* Convert headers string in format "name=value,name2=value2" to object
|
|
8
9
|
*/
|
|
@@ -24,8 +25,10 @@ function parseHeadersString(headersStr) {
|
|
|
24
25
|
*
|
|
25
26
|
* This exporter automatically configures itself with LangSmith endpoints and API keys,
|
|
26
27
|
* based on your LANGSMITH_API_KEY and LANGSMITH_PROJECT environment variables.
|
|
27
|
-
*
|
|
28
|
-
*
|
|
28
|
+
* OTEL_EXPORTER_OTLP_TRACES_ENDPOINT is a full traces URL and takes precedence over
|
|
29
|
+
* OTEL_EXPORTER_OTLP_ENDPOINT, a base URL to which /v1/traces is appended unless
|
|
30
|
+
* it already ends in /traces for compatibility.
|
|
31
|
+
* Also respects OTEL_EXPORTER_OTLP_HEADERS if set.
|
|
29
32
|
*
|
|
30
33
|
* @param config - Optional configuration object that accepts all OTLPTraceExporter parameters.
|
|
31
34
|
* If not provided, uses default LangSmith configuration:
|
|
@@ -38,8 +41,22 @@ export class LangSmithOTLPTraceExporter extends OTLPTraceExporter {
|
|
|
38
41
|
const defaultLsEndpoint = getLangSmithEnvironmentVariable("ENDPOINT") ||
|
|
39
42
|
"https://api.smith.langchain.com";
|
|
40
43
|
const defaultBaseUrl = defaultLsEndpoint.replace(/\/$/, "");
|
|
41
|
-
const
|
|
42
|
-
`${defaultBaseUrl}/otel
|
|
44
|
+
const baseEndpoint = getEnvironmentVariable("OTEL_EXPORTER_OTLP_ENDPOINT") ||
|
|
45
|
+
`${defaultBaseUrl}/otel`;
|
|
46
|
+
const defaultUrl = getEnvironmentVariable("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") ||
|
|
47
|
+
(baseEndpoint.endsWith("/traces")
|
|
48
|
+
? baseEndpoint
|
|
49
|
+
: `${baseEndpoint.replace(/\/$/, "")}/v1/traces`);
|
|
50
|
+
if (config?.url === undefined &&
|
|
51
|
+
!getEnvironmentVariable("OTEL_EXPORTER_OTLP_TRACES_ENDPOINT") &&
|
|
52
|
+
baseEndpoint.endsWith("/traces")) {
|
|
53
|
+
warnOnce("LangSmith now treats OTEL_EXPORTER_OTLP_ENDPOINT as a base URL and " +
|
|
54
|
+
"appends /v1/traces. Your value ends in /traces, so it is being " +
|
|
55
|
+
"preserved unchanged for compatibility. This fallback will be " +
|
|
56
|
+
"removed in the v1 release of the SDK. Move this full URL to " +
|
|
57
|
+
"OTEL_EXPORTER_OTLP_TRACES_ENDPOINT to use standard OpenTelemetry " +
|
|
58
|
+
"configuration.");
|
|
59
|
+
}
|
|
43
60
|
// Configure headers with API key and project if available
|
|
44
61
|
let headers = config?.headers;
|
|
45
62
|
if (headers === undefined) {
|
package/dist/index.cjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LS_MESSAGE_VIEW_EXCLUDE = exports.__version__ = exports.InternalServerError = exports.RateLimitError = exports.UnprocessableEntityError = exports.ConflictError = exports.NotFoundError = exports.PermissionDeniedError = exports.AuthenticationError = exports.BadRequestError = exports.APIConnectionTimeoutError = exports.APIConnectionError = exports.APIUserAbortError = exports.APIError = exports.LangsmithError = exports.promptCacheSingleton = exports.configureGlobalPromptCache = exports.PromptCache = exports.Cache = exports.isTracingEnabled = exports.uuid7FromTime = exports.uuid7 = exports.computeRunIdForSecondaryReplica = exports.getDefaultProjectName = exports.overrideFetchImplementation = exports.EnvAddressError = exports.RunTree = exports.Client = void 0;
|
|
3
|
+
exports.LS_MESSAGE_VIEW_EXCLUDE = exports.__version__ = exports.InternalServerError = exports.RateLimitError = exports.UnprocessableEntityError = exports.ConflictError = exports.NotFoundError = exports.PermissionDeniedError = exports.AuthenticationError = exports.BadRequestError = exports.APIConnectionTimeoutError = exports.APIConnectionError = exports.APIUserAbortError = exports.APIError = exports.LangsmithError = exports.promptCacheSingleton = exports.configureGlobalPromptCache = exports.PromptCache = exports.Cache = exports.isTracingEnabled = exports.uuid7FromTime = exports.uuid7 = exports.computeRunIdForSecondaryReplica = exports.getDefaultProjectName = exports.overrideFetchImplementation = exports.EnvAddressError = exports.address = exports.RunTree = exports.Client = void 0;
|
|
4
4
|
var client_js_1 = require("./client.cjs");
|
|
5
5
|
Object.defineProperty(exports, "Client", { enumerable: true, get: function () { return client_js_1.Client; } });
|
|
6
6
|
var run_trees_js_1 = require("./run_trees.cjs");
|
|
7
7
|
Object.defineProperty(exports, "RunTree", { enumerable: true, get: function () { return run_trees_js_1.RunTree; } });
|
|
8
8
|
var address_js_1 = require("./address.cjs");
|
|
9
|
+
Object.defineProperty(exports, "address", { enumerable: true, get: function () { return address_js_1.address; } });
|
|
9
10
|
Object.defineProperty(exports, "EnvAddressError", { enumerable: true, get: function () { return address_js_1.EnvAddressError; } });
|
|
10
11
|
var fetch_js_1 = require("./singletons/fetch.cjs");
|
|
11
12
|
Object.defineProperty(exports, "overrideFetchImplementation", { enumerable: true, get: function () { return fetch_js_1.overrideFetchImplementation; } });
|
|
@@ -37,6 +38,6 @@ Object.defineProperty(exports, "UnprocessableEntityError", { enumerable: true, g
|
|
|
37
38
|
Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return error_js_1.RateLimitError; } });
|
|
38
39
|
Object.defineProperty(exports, "InternalServerError", { enumerable: true, get: function () { return error_js_1.InternalServerError; } });
|
|
39
40
|
// Update using pnpm bump-version
|
|
40
|
-
exports.__version__ = "0.10.
|
|
41
|
+
exports.__version__ = "0.10.8";
|
|
41
42
|
// Metadata key to hide a traced run from LangSmith's Messages View.
|
|
42
43
|
exports.LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
export { Client, type ClientConfig, type LangSmithTracingClientInterface, } from "./client.js";
|
|
2
2
|
export type { Dataset, Example, TracerSession, Run, Feedback, FeedbackConfigSchema, RetrieverOutput, } from "./schemas.js";
|
|
3
3
|
export { RunTree, type RunTreeConfig, type WriteReplica } from "./run_trees.js";
|
|
4
|
-
export { type Address, EnvAddressError } from "./address.js";
|
|
4
|
+
export { address, type Address, type Environment, EnvAddressError, } from "./address.js";
|
|
5
5
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
6
6
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
7
7
|
export { computeRunIdForSecondaryReplica, uuid7, uuid7FromTime, } from "./uuid.js";
|
|
8
8
|
export { isTracingEnabled } from "./utils/guard.js";
|
|
9
9
|
export { Cache, PromptCache, type CacheConfig, type CacheMetrics, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
10
10
|
export { LangsmithError, APIError, APIUserAbortError, APIConnectionError, APIConnectionTimeoutError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, } from "./_openapi_client/core/error.js";
|
|
11
|
-
export declare const __version__ = "0.10.
|
|
11
|
+
export declare const __version__ = "0.10.8";
|
|
12
12
|
export declare const LS_MESSAGE_VIEW_EXCLUDE: "ls_message_view_exclude";
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { Client, } from "./client.js";
|
|
2
2
|
export { RunTree } from "./run_trees.js";
|
|
3
|
-
export { EnvAddressError } from "./address.js";
|
|
3
|
+
export { address, EnvAddressError, } from "./address.js";
|
|
4
4
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
5
5
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
6
6
|
export { computeRunIdForSecondaryReplica, uuid7, uuid7FromTime, } from "./uuid.js";
|
|
@@ -8,6 +8,6 @@ export { isTracingEnabled } from "./utils/guard.js";
|
|
|
8
8
|
export { Cache, PromptCache, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
|
|
9
9
|
export { LangsmithError, APIError, APIUserAbortError, APIConnectionError, APIConnectionTimeoutError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, } from "./_openapi_client/core/error.js";
|
|
10
10
|
// Update using pnpm bump-version
|
|
11
|
-
export const __version__ = "0.10.
|
|
11
|
+
export const __version__ = "0.10.8";
|
|
12
12
|
// Metadata key to hide a traced run from LangSmith's Messages View.
|
|
13
13
|
export const LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
|
package/dist/run_trees.cjs
CHANGED
|
@@ -50,29 +50,22 @@ const HEADER_SAFE_REPLICA_FIELDS = new Set([
|
|
|
50
50
|
"primary",
|
|
51
51
|
"updates",
|
|
52
52
|
"reroot",
|
|
53
|
-
|
|
53
|
+
"address",
|
|
54
54
|
]);
|
|
55
|
-
//
|
|
55
|
+
// The address string, URL-encoded.
|
|
56
56
|
const LANGSMITH_ADDRESS = "langsmith-address";
|
|
57
|
-
/**
|
|
58
|
-
function
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
if (key in values) {
|
|
62
|
-
wire[key] = values[key];
|
|
63
|
-
delete values[key];
|
|
64
|
-
}
|
|
57
|
+
/** Validates an untrusted header address; `undefined` if unusable. */
|
|
58
|
+
function addressFromHeader(value) {
|
|
59
|
+
if (value == null) {
|
|
60
|
+
return undefined;
|
|
65
61
|
}
|
|
66
62
|
try {
|
|
67
|
-
return
|
|
68
|
-
named: Object.keys(wire).length > 0,
|
|
69
|
-
address: (0, address_js_1.fromWire)(wire),
|
|
70
|
-
};
|
|
63
|
+
return (0, address_js_1.parse)(value);
|
|
71
64
|
}
|
|
72
65
|
catch {
|
|
73
66
|
// Values are untrusted, so not logged.
|
|
74
|
-
console.warn("Ignoring an
|
|
75
|
-
return
|
|
67
|
+
console.warn("Ignoring an unusable address in a `baggage` header.");
|
|
68
|
+
return undefined;
|
|
76
69
|
}
|
|
77
70
|
}
|
|
78
71
|
function filterReplicaForHeaders(replica) {
|
|
@@ -148,16 +141,7 @@ class Baggage {
|
|
|
148
141
|
project_name = value;
|
|
149
142
|
}
|
|
150
143
|
else if (key === LANGSMITH_ADDRESS) {
|
|
151
|
-
|
|
152
|
-
try {
|
|
153
|
-
parsed = JSON.parse(value);
|
|
154
|
-
}
|
|
155
|
-
catch {
|
|
156
|
-
parsed = undefined;
|
|
157
|
-
}
|
|
158
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
159
|
-
address = takeHeaderAddress({ ...parsed }).address;
|
|
160
|
-
}
|
|
144
|
+
address = addressFromHeader(value);
|
|
161
145
|
}
|
|
162
146
|
else if (key === "langsmith-replicas") {
|
|
163
147
|
const parsed = JSON.parse(value);
|
|
@@ -166,10 +150,12 @@ class Baggage {
|
|
|
166
150
|
return [replica];
|
|
167
151
|
}
|
|
168
152
|
const filtered = filterReplicaForHeaders(replica);
|
|
169
|
-
const
|
|
153
|
+
const raw = filtered.address;
|
|
154
|
+
delete filtered.address;
|
|
155
|
+
const address = addressFromHeader(raw);
|
|
170
156
|
// A project wins over an address; a replica with an invalid
|
|
171
157
|
// address and no project is dropped.
|
|
172
|
-
if (filtered.projectName ||
|
|
158
|
+
if (filtered.projectName || raw == null) {
|
|
173
159
|
return [filtered];
|
|
174
160
|
}
|
|
175
161
|
return address ? [{ ...filtered, address }] : [];
|
|
@@ -190,7 +176,7 @@ class Baggage {
|
|
|
190
176
|
items.push(`langsmith-project=${encodeURIComponent(this.project_name)}`);
|
|
191
177
|
}
|
|
192
178
|
if (this.address) {
|
|
193
|
-
items.push(`${LANGSMITH_ADDRESS}=${encodeURIComponent(
|
|
179
|
+
items.push(`${LANGSMITH_ADDRESS}=${encodeURIComponent(this.address)}`);
|
|
194
180
|
}
|
|
195
181
|
return items.join(",");
|
|
196
182
|
}
|
|
@@ -683,14 +669,14 @@ class RunTree {
|
|
|
683
669
|
if (primary === undefined &&
|
|
684
670
|
!this.replicas?.some((r) => r.primary === true) &&
|
|
685
671
|
projectName === this.project_name &&
|
|
686
|
-
|
|
672
|
+
address === this.address) {
|
|
687
673
|
return {
|
|
688
674
|
...baseRun,
|
|
689
675
|
session_name: projectName,
|
|
690
676
|
address,
|
|
691
677
|
};
|
|
692
678
|
}
|
|
693
|
-
const seed = projectName ??
|
|
679
|
+
const seed = projectName ?? address ?? "agent//";
|
|
694
680
|
// Apply reroot logic before ID remapping
|
|
695
681
|
if (reroot) {
|
|
696
682
|
if (distributedParentId) {
|
package/dist/run_trees.js
CHANGED
|
@@ -9,7 +9,7 @@ import { warnOnce } from "./utils/warn.js";
|
|
|
9
9
|
import { uuid7FromTime, nonCryptographicUuid7Deterministic, } from "./utils/_uuid.js";
|
|
10
10
|
import { v5 as uuidv5 } from "./utils/uuid/src/index.js";
|
|
11
11
|
import { checkAddress, logUntraced, rejectConflicting, resolveFromEnv, } from "./utils/agent_addressing.js";
|
|
12
|
-
import { EnvAddressError,
|
|
12
|
+
import { EnvAddressError, parse as parseAddress, } from "./address.js";
|
|
13
13
|
const TIMESTAMP_LENGTH = 36;
|
|
14
14
|
// DNS namespace for UUID v5 (same as Python's uuid.NAMESPACE_DNS)
|
|
15
15
|
const UUID_NAMESPACE_DNS = "6ba7b810-9dad-11d1-80b4-00c04fd430c8";
|
|
@@ -44,29 +44,22 @@ const HEADER_SAFE_REPLICA_FIELDS = new Set([
|
|
|
44
44
|
"primary",
|
|
45
45
|
"updates",
|
|
46
46
|
"reroot",
|
|
47
|
-
|
|
47
|
+
"address",
|
|
48
48
|
]);
|
|
49
|
-
//
|
|
49
|
+
// The address string, URL-encoded.
|
|
50
50
|
const LANGSMITH_ADDRESS = "langsmith-address";
|
|
51
|
-
/**
|
|
52
|
-
function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
if (key in values) {
|
|
56
|
-
wire[key] = values[key];
|
|
57
|
-
delete values[key];
|
|
58
|
-
}
|
|
51
|
+
/** Validates an untrusted header address; `undefined` if unusable. */
|
|
52
|
+
function addressFromHeader(value) {
|
|
53
|
+
if (value == null) {
|
|
54
|
+
return undefined;
|
|
59
55
|
}
|
|
60
56
|
try {
|
|
61
|
-
return
|
|
62
|
-
named: Object.keys(wire).length > 0,
|
|
63
|
-
address: fromWire(wire),
|
|
64
|
-
};
|
|
57
|
+
return parseAddress(value);
|
|
65
58
|
}
|
|
66
59
|
catch {
|
|
67
60
|
// Values are untrusted, so not logged.
|
|
68
|
-
console.warn("Ignoring an
|
|
69
|
-
return
|
|
61
|
+
console.warn("Ignoring an unusable address in a `baggage` header.");
|
|
62
|
+
return undefined;
|
|
70
63
|
}
|
|
71
64
|
}
|
|
72
65
|
function filterReplicaForHeaders(replica) {
|
|
@@ -142,16 +135,7 @@ class Baggage {
|
|
|
142
135
|
project_name = value;
|
|
143
136
|
}
|
|
144
137
|
else if (key === LANGSMITH_ADDRESS) {
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
parsed = JSON.parse(value);
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
parsed = undefined;
|
|
151
|
-
}
|
|
152
|
-
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
153
|
-
address = takeHeaderAddress({ ...parsed }).address;
|
|
154
|
-
}
|
|
138
|
+
address = addressFromHeader(value);
|
|
155
139
|
}
|
|
156
140
|
else if (key === "langsmith-replicas") {
|
|
157
141
|
const parsed = JSON.parse(value);
|
|
@@ -160,10 +144,12 @@ class Baggage {
|
|
|
160
144
|
return [replica];
|
|
161
145
|
}
|
|
162
146
|
const filtered = filterReplicaForHeaders(replica);
|
|
163
|
-
const
|
|
147
|
+
const raw = filtered.address;
|
|
148
|
+
delete filtered.address;
|
|
149
|
+
const address = addressFromHeader(raw);
|
|
164
150
|
// A project wins over an address; a replica with an invalid
|
|
165
151
|
// address and no project is dropped.
|
|
166
|
-
if (filtered.projectName ||
|
|
152
|
+
if (filtered.projectName || raw == null) {
|
|
167
153
|
return [filtered];
|
|
168
154
|
}
|
|
169
155
|
return address ? [{ ...filtered, address }] : [];
|
|
@@ -184,7 +170,7 @@ class Baggage {
|
|
|
184
170
|
items.push(`langsmith-project=${encodeURIComponent(this.project_name)}`);
|
|
185
171
|
}
|
|
186
172
|
if (this.address) {
|
|
187
|
-
items.push(`${LANGSMITH_ADDRESS}=${encodeURIComponent(
|
|
173
|
+
items.push(`${LANGSMITH_ADDRESS}=${encodeURIComponent(this.address)}`);
|
|
188
174
|
}
|
|
189
175
|
return items.join(",");
|
|
190
176
|
}
|
|
@@ -677,14 +663,14 @@ export class RunTree {
|
|
|
677
663
|
if (primary === undefined &&
|
|
678
664
|
!this.replicas?.some((r) => r.primary === true) &&
|
|
679
665
|
projectName === this.project_name &&
|
|
680
|
-
|
|
666
|
+
address === this.address) {
|
|
681
667
|
return {
|
|
682
668
|
...baseRun,
|
|
683
669
|
session_name: projectName,
|
|
684
670
|
address,
|
|
685
671
|
};
|
|
686
672
|
}
|
|
687
|
-
const seed = projectName ??
|
|
673
|
+
const seed = projectName ?? address ?? "agent//";
|
|
688
674
|
// Apply reroot logic before ID remapping
|
|
689
675
|
if (reroot) {
|
|
690
676
|
if (distributedParentId) {
|
package/dist/schemas.d.ts
CHANGED
|
@@ -150,7 +150,6 @@ export interface RunCreate extends BaseRun {
|
|
|
150
150
|
revision_id?: string;
|
|
151
151
|
child_runs?: this[];
|
|
152
152
|
session_name?: string;
|
|
153
|
-
/** (beta) Sent as `agent_id` / `agent_environment`. */
|
|
154
153
|
address?: Address;
|
|
155
154
|
}
|
|
156
155
|
export interface RunUpdate {
|
|
@@ -170,7 +169,6 @@ export interface RunUpdate {
|
|
|
170
169
|
events?: KVMap[];
|
|
171
170
|
session_id?: string;
|
|
172
171
|
session_name?: string;
|
|
173
|
-
/** (beta) Sent as `agent_id` / `agent_environment`. */
|
|
174
172
|
address?: Address;
|
|
175
173
|
/** Unique ID assigned to every run within this nested trace. **/
|
|
176
174
|
trace_id?: string;
|
package/dist/traceable.cjs
CHANGED
|
@@ -526,7 +526,7 @@ function traceable(wrappedFunc, config) {
|
|
|
526
526
|
runtimeConfig = undefined;
|
|
527
527
|
}
|
|
528
528
|
// Runtime config outranks decorator config, whichever mode each names.
|
|
529
|
-
[ensuredConfig.project_name, ensuredConfig.address] = (0, agent_addressing_js_1.firstNamed)([runtimeConfig?.project_name, runtimeConfig?.address], [runTreeConfig.project_name, runTreeConfig.address]);
|
|
529
|
+
[ensuredConfig.project_name, ensuredConfig.address] = (0, agent_addressing_js_1.firstNamed)([runtimeConfig?.project_name, (0, agent_addressing_js_1.checkAddress)(runtimeConfig?.address)], [runTreeConfig.project_name, runTreeConfig.address]);
|
|
530
530
|
let runEndedPromiseResolver;
|
|
531
531
|
const runEndedPromise = new Promise((resolve) => {
|
|
532
532
|
runEndedPromiseResolver = resolve;
|
|
@@ -651,9 +651,28 @@ function traceable(wrappedFunc, config) {
|
|
|
651
651
|
async start(controller) {
|
|
652
652
|
// eslint-disable-next-line no-constant-condition
|
|
653
653
|
while (true) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
654
|
+
let result;
|
|
655
|
+
try {
|
|
656
|
+
result = await (snapshot
|
|
657
|
+
? snapshot(() => otel_context.with(capturedOtelContext, () => reader.read()))
|
|
658
|
+
: otel_context.with(capturedOtelContext, () => reader.read()));
|
|
659
|
+
}
|
|
660
|
+
catch (e) {
|
|
661
|
+
// The source stream errored: end the run with the error and the
|
|
662
|
+
// chunks received so far instead of leaving it pending.
|
|
663
|
+
finished = true;
|
|
664
|
+
await currentRunTree?.end(undefined, String(e));
|
|
665
|
+
await handleRunOutputs({
|
|
666
|
+
runTree: currentRunTree,
|
|
667
|
+
rawOutputs: await handleChunks(chunks),
|
|
668
|
+
processOutputsFn,
|
|
669
|
+
on_end,
|
|
670
|
+
postRunPromise,
|
|
671
|
+
deferredInputs,
|
|
672
|
+
skipChildPromiseDelay: true,
|
|
673
|
+
});
|
|
674
|
+
throw e;
|
|
675
|
+
}
|
|
657
676
|
if (result.done) {
|
|
658
677
|
finished = true;
|
|
659
678
|
await handleRunOutputs({
|
package/dist/traceable.js
CHANGED
|
@@ -522,7 +522,7 @@ export function traceable(wrappedFunc, config) {
|
|
|
522
522
|
runtimeConfig = undefined;
|
|
523
523
|
}
|
|
524
524
|
// Runtime config outranks decorator config, whichever mode each names.
|
|
525
|
-
[ensuredConfig.project_name, ensuredConfig.address] = firstNamed([runtimeConfig?.project_name, runtimeConfig?.address], [runTreeConfig.project_name, runTreeConfig.address]);
|
|
525
|
+
[ensuredConfig.project_name, ensuredConfig.address] = firstNamed([runtimeConfig?.project_name, checkAddress(runtimeConfig?.address)], [runTreeConfig.project_name, runTreeConfig.address]);
|
|
526
526
|
let runEndedPromiseResolver;
|
|
527
527
|
const runEndedPromise = new Promise((resolve) => {
|
|
528
528
|
runEndedPromiseResolver = resolve;
|
|
@@ -647,9 +647,28 @@ export function traceable(wrappedFunc, config) {
|
|
|
647
647
|
async start(controller) {
|
|
648
648
|
// eslint-disable-next-line no-constant-condition
|
|
649
649
|
while (true) {
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
650
|
+
let result;
|
|
651
|
+
try {
|
|
652
|
+
result = await (snapshot
|
|
653
|
+
? snapshot(() => otel_context.with(capturedOtelContext, () => reader.read()))
|
|
654
|
+
: otel_context.with(capturedOtelContext, () => reader.read()));
|
|
655
|
+
}
|
|
656
|
+
catch (e) {
|
|
657
|
+
// The source stream errored: end the run with the error and the
|
|
658
|
+
// chunks received so far instead of leaving it pending.
|
|
659
|
+
finished = true;
|
|
660
|
+
await currentRunTree?.end(undefined, String(e));
|
|
661
|
+
await handleRunOutputs({
|
|
662
|
+
runTree: currentRunTree,
|
|
663
|
+
rawOutputs: await handleChunks(chunks),
|
|
664
|
+
processOutputsFn,
|
|
665
|
+
on_end,
|
|
666
|
+
postRunPromise,
|
|
667
|
+
deferredInputs,
|
|
668
|
+
skipChildPromiseDelay: true,
|
|
669
|
+
});
|
|
670
|
+
throw e;
|
|
671
|
+
}
|
|
653
672
|
if (result.done) {
|
|
654
673
|
finished = true;
|
|
655
674
|
await handleRunOutputs({
|
|
@@ -10,9 +10,9 @@ exports.applyToPayload = applyToPayload;
|
|
|
10
10
|
const address_js_1 = require("../address.cjs");
|
|
11
11
|
const env_js_1 = require("./env.cjs");
|
|
12
12
|
const warn_js_1 = require("./warn.cjs");
|
|
13
|
-
/** Validate an address at an entry point; the SDK carries the
|
|
13
|
+
/** Validate and normalise an address at an entry point; the SDK carries the result. */
|
|
14
14
|
function checkAddress(address) {
|
|
15
|
-
return address == null ? undefined : (0, address_js_1.
|
|
15
|
+
return address == null ? undefined : (0, address_js_1.parse)(address);
|
|
16
16
|
}
|
|
17
17
|
function rejectConflicting(project, address) {
|
|
18
18
|
if (project && address) {
|
|
@@ -41,7 +41,7 @@ function getEnvProject() {
|
|
|
41
41
|
*/
|
|
42
42
|
function resolveFromEnv() {
|
|
43
43
|
const project = getEnvProject();
|
|
44
|
-
const address = (0, address_js_1.
|
|
44
|
+
const address = (0, address_js_1.fromEnv)();
|
|
45
45
|
if (project && address) {
|
|
46
46
|
throw new address_js_1.EnvAddressError("LANGSMITH_AGENT_* and a project are both set in the environment.");
|
|
47
47
|
}
|
|
@@ -64,9 +64,8 @@ function warnOnEnv() {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
68
|
-
* naming no project takes the env address.
|
|
69
|
-
* re-prepared when batched) are left alone.
|
|
67
|
+
* Put the run's address in its payload field, as one lowercase string.
|
|
68
|
+
* Without one, a create naming no project takes the env address.
|
|
70
69
|
*
|
|
71
70
|
* @throws {EnvAddressError} If the env names half an address.
|
|
72
71
|
*/
|
|
@@ -75,16 +74,15 @@ function applyToPayload(run, { update = false } = {}) {
|
|
|
75
74
|
let address = checkAddress(payload.address);
|
|
76
75
|
delete payload.address;
|
|
77
76
|
const namedProject = payload.session_id != null || payload.session_name != null;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
address = (0, address_js_1.addressFromEnv)();
|
|
77
|
+
if (!address && !update && !namedProject) {
|
|
78
|
+
address = (0, address_js_1.fromEnv)();
|
|
81
79
|
}
|
|
82
80
|
if (!address) {
|
|
83
81
|
return;
|
|
84
82
|
}
|
|
85
83
|
(0, warn_js_1.warnOnce)("Sending runs to an `address` is in beta and enabled per workspace; a " +
|
|
86
84
|
"workspace without it rejects the runs.");
|
|
87
|
-
|
|
85
|
+
payload.address = address;
|
|
88
86
|
if (!namedProject) {
|
|
89
87
|
delete payload.session_name;
|
|
90
88
|
delete payload.session_id;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { type Address, EnvAddressError } from "../address.js";
|
|
2
2
|
/** One precedence level: the `[project, address]` it names. */
|
|
3
3
|
export type Tier = [string | undefined, Address | undefined];
|
|
4
|
-
/** Validate an address at an entry point; the SDK carries the
|
|
5
|
-
export declare function checkAddress(address: unknown):
|
|
4
|
+
/** Validate and normalise an address at an entry point; the SDK carries the result. */
|
|
5
|
+
export declare function checkAddress(address: unknown): Address | undefined;
|
|
6
6
|
export declare function rejectConflicting(project: unknown, address: unknown): void;
|
|
7
7
|
/** The highest level naming a project or an address, whichever it names. */
|
|
8
8
|
export declare function firstNamed(...tiers: Tier[]): Tier;
|
|
@@ -15,9 +15,8 @@ export declare function logUntraced(error: EnvAddressError): void;
|
|
|
15
15
|
/** Warn once, at client construction, if the env can't address runs. */
|
|
16
16
|
export declare function warnOnEnv(): void;
|
|
17
17
|
/**
|
|
18
|
-
*
|
|
19
|
-
* naming no project takes the env address.
|
|
20
|
-
* re-prepared when batched) are left alone.
|
|
18
|
+
* Put the run's address in its payload field, as one lowercase string.
|
|
19
|
+
* Without one, a create naming no project takes the env address.
|
|
21
20
|
*
|
|
22
21
|
* @throws {EnvAddressError} If the env names half an address.
|
|
23
22
|
*/
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { EnvAddressError,
|
|
1
|
+
import { EnvAddressError, envNames, fromEnv as addressFromEnv, parse, } from "../address.js";
|
|
2
2
|
import { getEnvironmentVariable, getLangSmithEnvironmentVariable, } from "./env.js";
|
|
3
3
|
import { warnOnce } from "./warn.js";
|
|
4
|
-
/** Validate an address at an entry point; the SDK carries the
|
|
4
|
+
/** Validate and normalise an address at an entry point; the SDK carries the result. */
|
|
5
5
|
export function checkAddress(address) {
|
|
6
|
-
return address == null ? undefined :
|
|
6
|
+
return address == null ? undefined : parse(address);
|
|
7
7
|
}
|
|
8
8
|
export function rejectConflicting(project, address) {
|
|
9
9
|
if (project && address) {
|
|
@@ -55,9 +55,8 @@ export function warnOnEnv() {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
58
|
-
*
|
|
59
|
-
* naming no project takes the env address.
|
|
60
|
-
* re-prepared when batched) are left alone.
|
|
58
|
+
* Put the run's address in its payload field, as one lowercase string.
|
|
59
|
+
* Without one, a create naming no project takes the env address.
|
|
61
60
|
*
|
|
62
61
|
* @throws {EnvAddressError} If the env names half an address.
|
|
63
62
|
*/
|
|
@@ -66,8 +65,7 @@ export function applyToPayload(run, { update = false } = {}) {
|
|
|
66
65
|
let address = checkAddress(payload.address);
|
|
67
66
|
delete payload.address;
|
|
68
67
|
const namedProject = payload.session_id != null || payload.session_name != null;
|
|
69
|
-
|
|
70
|
-
if (!address && !update && !namedProject && !rendered) {
|
|
68
|
+
if (!address && !update && !namedProject) {
|
|
71
69
|
address = addressFromEnv();
|
|
72
70
|
}
|
|
73
71
|
if (!address) {
|
|
@@ -75,7 +73,7 @@ export function applyToPayload(run, { update = false } = {}) {
|
|
|
75
73
|
}
|
|
76
74
|
warnOnce("Sending runs to an `address` is in beta and enabled per workspace; a " +
|
|
77
75
|
"workspace without it rejects the runs.");
|
|
78
|
-
|
|
76
|
+
payload.address = address;
|
|
79
77
|
if (!namedProject) {
|
|
80
78
|
delete payload.session_name;
|
|
81
79
|
delete payload.session_id;
|