langsmith 0.10.3 → 0.10.5
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 +19 -4
- package/dist/client.d.ts +2 -1
- package/dist/client.js +19 -4
- package/dist/evaluation/_runner.cjs +47 -5
- package/dist/evaluation/_runner.d.ts +12 -0
- package/dist/evaluation/_runner.js +47 -5
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- 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/helpers.cjs +129 -0
- package/dist/sandbox/helpers.d.ts +29 -0
- package/dist/sandbox/helpers.js +123 -0
- package/dist/sandbox/index.cjs +7 -1
- package/dist/sandbox/index.d.ts +5 -1
- package/dist/sandbox/index.js +2 -0
- 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/ws_execute.cjs +31 -1
- package/dist/sandbox/ws_execute.d.ts +9 -0
- package/dist/sandbox/ws_execute.js +31 -1
- package/dist/utils/error.cjs +17 -22
- package/dist/utils/error.js +17 -22
- package/dist/wrappers/openai_agents.cjs +37 -28
- package/dist/wrappers/openai_agents.d.ts +0 -1
- package/dist/wrappers/openai_agents.js +37 -28
- package/package.json +2 -2
|
@@ -136,10 +136,20 @@ class WSStreamControl {
|
|
|
136
136
|
writable: true,
|
|
137
137
|
value: false
|
|
138
138
|
});
|
|
139
|
+
Object.defineProperty(this, "_closeStdinPending", {
|
|
140
|
+
enumerable: true,
|
|
141
|
+
configurable: true,
|
|
142
|
+
writable: true,
|
|
143
|
+
value: false
|
|
144
|
+
});
|
|
139
145
|
}
|
|
140
146
|
/** Bind to the active WebSocket. Called inside the generator. */
|
|
141
147
|
_bind(ws) {
|
|
142
148
|
this._ws = ws;
|
|
149
|
+
if (this._closeStdinPending) {
|
|
150
|
+
this._closeStdinPending = false;
|
|
151
|
+
this.sendCloseStdin();
|
|
152
|
+
}
|
|
143
153
|
}
|
|
144
154
|
/** Mark as closed. Called when the generator exits. */
|
|
145
155
|
_unbind() {
|
|
@@ -163,6 +173,22 @@ class WSStreamControl {
|
|
|
163
173
|
this._ws.send(JSON.stringify({ type: "input", data }));
|
|
164
174
|
}
|
|
165
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* Half-close the command's stdin so it reads EOF.
|
|
178
|
+
*
|
|
179
|
+
* A reconnected stream binds its socket only once iteration starts, so a
|
|
180
|
+
* close arriving before that is queued and sent on bind — dropping it would
|
|
181
|
+
* leave the command waiting for an EOF that never comes.
|
|
182
|
+
*/
|
|
183
|
+
sendCloseStdin() {
|
|
184
|
+
if (this._closed)
|
|
185
|
+
return;
|
|
186
|
+
if (this._ws && this._ws.readyState === 1) {
|
|
187
|
+
this._ws.send(JSON.stringify({ type: "close_stdin" }));
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
this._closeStdinPending = true;
|
|
191
|
+
}
|
|
166
192
|
}
|
|
167
193
|
exports.WSStreamControl = WSStreamControl;
|
|
168
194
|
// =============================================================================
|
|
@@ -330,7 +356,7 @@ async function* readWsMessages(ws) {
|
|
|
330
356
|
* data arrives in addition to yielding the messages.
|
|
331
357
|
*/
|
|
332
358
|
async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
|
|
333
|
-
const { timeout = 60, env, cwd, shell = "/bin/bash", onStdout, onStderr, commandId, idleTimeout = 300, killOnDisconnect = false, ttlSeconds = 600, pty, headers: extraHeaders, openTimeout = exports.WS_OPEN_TIMEOUT, } = options;
|
|
359
|
+
const { timeout = 60, env, cwd, shell = "/bin/bash", onStdout, onStderr, commandId, idleTimeout = 300, killOnDisconnect = false, ttlSeconds = 600, pty, runConfig, closeStdin, headers: extraHeaders, openTimeout = exports.WS_OPEN_TIMEOUT, } = options;
|
|
334
360
|
const wsUrl = buildWsUrl(dataplaneUrl);
|
|
335
361
|
const headers = buildAuthHeaders(apiKey, extraHeaders);
|
|
336
362
|
const control = new WSStreamControl();
|
|
@@ -353,6 +379,10 @@ async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
|
|
|
353
379
|
payload.env = env;
|
|
354
380
|
if (cwd)
|
|
355
381
|
payload.cwd = cwd;
|
|
382
|
+
if (runConfig)
|
|
383
|
+
payload.run_config = runConfig;
|
|
384
|
+
if (closeStdin)
|
|
385
|
+
payload.close_stdin = true;
|
|
356
386
|
if (commandId)
|
|
357
387
|
payload.command_id = commandId;
|
|
358
388
|
if (pty)
|
|
@@ -35,6 +35,7 @@ export declare class WSStreamControl {
|
|
|
35
35
|
private _ws;
|
|
36
36
|
private _closed;
|
|
37
37
|
private _killed;
|
|
38
|
+
private _closeStdinPending;
|
|
38
39
|
/** Bind to the active WebSocket. Called inside the generator. */
|
|
39
40
|
_bind(ws: WsWebSocket): void;
|
|
40
41
|
/** Mark as closed. Called when the generator exits. */
|
|
@@ -45,6 +46,14 @@ export declare class WSStreamControl {
|
|
|
45
46
|
sendKill(): void;
|
|
46
47
|
/** Send stdin data to the running command. */
|
|
47
48
|
sendInput(data: string): void;
|
|
49
|
+
/**
|
|
50
|
+
* Half-close the command's stdin so it reads EOF.
|
|
51
|
+
*
|
|
52
|
+
* A reconnected stream binds its socket only once iteration starts, so a
|
|
53
|
+
* close arriving before that is queued and sent on bind — dropping it would
|
|
54
|
+
* leave the command waiting for an EOF that never comes.
|
|
55
|
+
*/
|
|
56
|
+
sendCloseStdin(): void;
|
|
48
57
|
}
|
|
49
58
|
/**
|
|
50
59
|
* Raise the appropriate exception from a server error message.
|
|
@@ -124,10 +124,20 @@ export class WSStreamControl {
|
|
|
124
124
|
writable: true,
|
|
125
125
|
value: false
|
|
126
126
|
});
|
|
127
|
+
Object.defineProperty(this, "_closeStdinPending", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
configurable: true,
|
|
130
|
+
writable: true,
|
|
131
|
+
value: false
|
|
132
|
+
});
|
|
127
133
|
}
|
|
128
134
|
/** Bind to the active WebSocket. Called inside the generator. */
|
|
129
135
|
_bind(ws) {
|
|
130
136
|
this._ws = ws;
|
|
137
|
+
if (this._closeStdinPending) {
|
|
138
|
+
this._closeStdinPending = false;
|
|
139
|
+
this.sendCloseStdin();
|
|
140
|
+
}
|
|
131
141
|
}
|
|
132
142
|
/** Mark as closed. Called when the generator exits. */
|
|
133
143
|
_unbind() {
|
|
@@ -151,6 +161,22 @@ export class WSStreamControl {
|
|
|
151
161
|
this._ws.send(JSON.stringify({ type: "input", data }));
|
|
152
162
|
}
|
|
153
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* Half-close the command's stdin so it reads EOF.
|
|
166
|
+
*
|
|
167
|
+
* A reconnected stream binds its socket only once iteration starts, so a
|
|
168
|
+
* close arriving before that is queued and sent on bind — dropping it would
|
|
169
|
+
* leave the command waiting for an EOF that never comes.
|
|
170
|
+
*/
|
|
171
|
+
sendCloseStdin() {
|
|
172
|
+
if (this._closed)
|
|
173
|
+
return;
|
|
174
|
+
if (this._ws && this._ws.readyState === 1) {
|
|
175
|
+
this._ws.send(JSON.stringify({ type: "close_stdin" }));
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
this._closeStdinPending = true;
|
|
179
|
+
}
|
|
154
180
|
}
|
|
155
181
|
// =============================================================================
|
|
156
182
|
// Error Handling
|
|
@@ -317,7 +343,7 @@ async function* readWsMessages(ws) {
|
|
|
317
343
|
* data arrives in addition to yielding the messages.
|
|
318
344
|
*/
|
|
319
345
|
export async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
|
|
320
|
-
const { timeout = 60, env, cwd, shell = "/bin/bash", onStdout, onStderr, commandId, idleTimeout = 300, killOnDisconnect = false, ttlSeconds = 600, pty, headers: extraHeaders, openTimeout = WS_OPEN_TIMEOUT, } = options;
|
|
346
|
+
const { timeout = 60, env, cwd, shell = "/bin/bash", onStdout, onStderr, commandId, idleTimeout = 300, killOnDisconnect = false, ttlSeconds = 600, pty, runConfig, closeStdin, headers: extraHeaders, openTimeout = WS_OPEN_TIMEOUT, } = options;
|
|
321
347
|
const wsUrl = buildWsUrl(dataplaneUrl);
|
|
322
348
|
const headers = buildAuthHeaders(apiKey, extraHeaders);
|
|
323
349
|
const control = new WSStreamControl();
|
|
@@ -340,6 +366,10 @@ export async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
|
|
|
340
366
|
payload.env = env;
|
|
341
367
|
if (cwd)
|
|
342
368
|
payload.cwd = cwd;
|
|
369
|
+
if (runConfig)
|
|
370
|
+
payload.run_config = runConfig;
|
|
371
|
+
if (closeStdin)
|
|
372
|
+
payload.close_stdin = true;
|
|
343
373
|
if (commandId)
|
|
344
374
|
payload.command_id = commandId;
|
|
345
375
|
if (pty)
|
package/dist/utils/error.cjs
CHANGED
|
@@ -140,32 +140,27 @@ async function raiseForStatus(response, context, consumeOnSuccess) {
|
|
|
140
140
|
}
|
|
141
141
|
return;
|
|
142
142
|
}
|
|
143
|
+
try {
|
|
144
|
+
errorBody = await response.text();
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
146
|
+
}
|
|
147
|
+
catch (_e) {
|
|
148
|
+
errorBody = "";
|
|
149
|
+
}
|
|
143
150
|
if (response.status === 403) {
|
|
151
|
+
let errorData;
|
|
144
152
|
try {
|
|
145
|
-
|
|
146
|
-
const errorCode = errorData?.error;
|
|
147
|
-
if (errorCode === "org_scoped_key_requires_workspace") {
|
|
148
|
-
errorBody =
|
|
149
|
-
"This API key is org-scoped and requires workspace specification. " +
|
|
150
|
-
"Please provide 'workspaceId' parameter, " +
|
|
151
|
-
"or set LANGSMITH_WORKSPACE_ID environment variable.";
|
|
152
|
-
}
|
|
153
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
154
|
-
}
|
|
155
|
-
catch (_e) {
|
|
156
|
-
const errorWithStatus = new Error(`${response.status} ${response.statusText}`);
|
|
157
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
158
|
-
errorWithStatus.status = response?.status;
|
|
159
|
-
throw errorWithStatus;
|
|
153
|
+
errorData = JSON.parse(errorBody);
|
|
160
154
|
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
errorBody = await response.text();
|
|
165
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
155
|
+
catch {
|
|
156
|
+
// Non-JSON body (e.g. a proxy in front of a self-hosted instance):
|
|
157
|
+
// fall through and surface the raw body like every other status.
|
|
166
158
|
}
|
|
167
|
-
|
|
168
|
-
errorBody =
|
|
159
|
+
if (errorData?.error === "org_scoped_key_requires_workspace") {
|
|
160
|
+
errorBody =
|
|
161
|
+
"This API key is org-scoped and requires workspace specification. " +
|
|
162
|
+
"Please provide 'workspaceId' parameter, " +
|
|
163
|
+
"or set LANGSMITH_WORKSPACE_ID environment variable.";
|
|
169
164
|
}
|
|
170
165
|
}
|
|
171
166
|
const fullMessage = `Failed to ${context}. Received status [${response.status}]: ${response.statusText}. Message: ${errorBody}`;
|
package/dist/utils/error.js
CHANGED
|
@@ -129,32 +129,27 @@ export async function raiseForStatus(response, context, consumeOnSuccess) {
|
|
|
129
129
|
}
|
|
130
130
|
return;
|
|
131
131
|
}
|
|
132
|
+
try {
|
|
133
|
+
errorBody = await response.text();
|
|
134
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
135
|
+
}
|
|
136
|
+
catch (_e) {
|
|
137
|
+
errorBody = "";
|
|
138
|
+
}
|
|
132
139
|
if (response.status === 403) {
|
|
140
|
+
let errorData;
|
|
133
141
|
try {
|
|
134
|
-
|
|
135
|
-
const errorCode = errorData?.error;
|
|
136
|
-
if (errorCode === "org_scoped_key_requires_workspace") {
|
|
137
|
-
errorBody =
|
|
138
|
-
"This API key is org-scoped and requires workspace specification. " +
|
|
139
|
-
"Please provide 'workspaceId' parameter, " +
|
|
140
|
-
"or set LANGSMITH_WORKSPACE_ID environment variable.";
|
|
141
|
-
}
|
|
142
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
143
|
-
}
|
|
144
|
-
catch (_e) {
|
|
145
|
-
const errorWithStatus = new Error(`${response.status} ${response.statusText}`);
|
|
146
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
147
|
-
errorWithStatus.status = response?.status;
|
|
148
|
-
throw errorWithStatus;
|
|
142
|
+
errorData = JSON.parse(errorBody);
|
|
149
143
|
}
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
errorBody = await response.text();
|
|
154
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
+
catch {
|
|
145
|
+
// Non-JSON body (e.g. a proxy in front of a self-hosted instance):
|
|
146
|
+
// fall through and surface the raw body like every other status.
|
|
155
147
|
}
|
|
156
|
-
|
|
157
|
-
errorBody =
|
|
148
|
+
if (errorData?.error === "org_scoped_key_requires_workspace") {
|
|
149
|
+
errorBody =
|
|
150
|
+
"This API key is org-scoped and requires workspace specification. " +
|
|
151
|
+
"Please provide 'workspaceId' parameter, " +
|
|
152
|
+
"or set LANGSMITH_WORKSPACE_ID environment variable.";
|
|
158
153
|
}
|
|
159
154
|
}
|
|
160
155
|
const fullMessage = `Failed to ${context}. Received status [${response.status}]: ${response.statusText}. Message: ${errorBody}`;
|
|
@@ -369,6 +369,33 @@ function createResponsesUsageMetadata(usage) {
|
|
|
369
369
|
}
|
|
370
370
|
return result;
|
|
371
371
|
}
|
|
372
|
+
/**
|
|
373
|
+
* Return an ls_agent_type for the span, or undefined to leave it alone.
|
|
374
|
+
*
|
|
375
|
+
* If the run already has middleware/subagent/compaction, keep it. Otherwise
|
|
376
|
+
* guardrails become middleware and agents under any tool become subagents.
|
|
377
|
+
*
|
|
378
|
+
* Openai-agents structural counterpart to resolveVercelLsAgentType.
|
|
379
|
+
*/
|
|
380
|
+
function _resolveOpenAIAgentsLsAgentType(spanData, parentRun, existingTag) {
|
|
381
|
+
if (typeof existingTag === "string" &&
|
|
382
|
+
ls_agent_type_js_1.NON_ROOT_LS_AGENT_TYPES.has(existingTag)) {
|
|
383
|
+
return undefined;
|
|
384
|
+
}
|
|
385
|
+
if (spanData.type === "guardrail")
|
|
386
|
+
return "middleware";
|
|
387
|
+
// Walk the full parent chain, not just the direct parent: asTool inserts
|
|
388
|
+
// a chain run between the tool and the inner agent span.
|
|
389
|
+
if (spanData.type === "agent") {
|
|
390
|
+
let cursor = parentRun;
|
|
391
|
+
while (cursor !== undefined) {
|
|
392
|
+
if (cursor.run_type === "tool")
|
|
393
|
+
return "subagent";
|
|
394
|
+
cursor = cursor.parent_run;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
return undefined;
|
|
398
|
+
}
|
|
372
399
|
/**
|
|
373
400
|
* Tracing processor for the [OpenAI Agents SDK](https://openai.github.io/openai-agents-js/).
|
|
374
401
|
*
|
|
@@ -463,12 +490,6 @@ class OpenAIAgentsTracingProcessor {
|
|
|
463
490
|
writable: true,
|
|
464
491
|
value: new Map()
|
|
465
492
|
});
|
|
466
|
-
Object.defineProperty(this, "_spanDataTypes", {
|
|
467
|
-
enumerable: true,
|
|
468
|
-
configurable: true,
|
|
469
|
-
writable: true,
|
|
470
|
-
value: new Map()
|
|
471
|
-
});
|
|
472
493
|
Object.defineProperty(this, "_unpostedTraces", {
|
|
473
494
|
enumerable: true,
|
|
474
495
|
configurable: true,
|
|
@@ -684,28 +705,17 @@ class OpenAIAgentsTracingProcessor {
|
|
|
684
705
|
console.error("Error creating span run:", e);
|
|
685
706
|
return;
|
|
686
707
|
}
|
|
687
|
-
//
|
|
688
|
-
//
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
}
|
|
698
|
-
if (!childRun.extra.metadata) {
|
|
699
|
-
childRun.extra.metadata = {};
|
|
700
|
-
}
|
|
701
|
-
const meta = childRun.extra.metadata;
|
|
702
|
-
if (!ls_agent_type_js_1.NON_ROOT_LS_AGENT_TYPES.has(meta.ls_agent_type)) {
|
|
703
|
-
meta.ls_agent_type = "subagent";
|
|
704
|
-
}
|
|
705
|
-
}
|
|
708
|
+
// Handoffs replace the caller rather than run as a tool, so a handoff
|
|
709
|
+
// agent has no tool ancestor and correctly stays untagged here.
|
|
710
|
+
if (!childRun.extra)
|
|
711
|
+
childRun.extra = {};
|
|
712
|
+
if (!childRun.extra.metadata)
|
|
713
|
+
childRun.extra.metadata = {};
|
|
714
|
+
const meta = childRun.extra.metadata;
|
|
715
|
+
const structuralTag = _resolveOpenAIAgentsLsAgentType(spanData, parentRun, meta.ls_agent_type);
|
|
716
|
+
if (structuralTag !== undefined) {
|
|
717
|
+
meta.ls_agent_type = structuralTag;
|
|
706
718
|
}
|
|
707
|
-
// Track span data type for parent lookups
|
|
708
|
-
this._spanDataTypes.set(span.spanId, spanData.type);
|
|
709
719
|
this._runs.set(span.spanId, childRun);
|
|
710
720
|
// Enter AsyncLocalStorage context synchronously so nested traceable()
|
|
711
721
|
// calls inside the span's body nest under this run. Remember the
|
|
@@ -741,7 +751,6 @@ class OpenAIAgentsTracingProcessor {
|
|
|
741
751
|
enterRunTreeContext(previousStore);
|
|
742
752
|
}
|
|
743
753
|
const run = this._runs.get(span.spanId);
|
|
744
|
-
this._spanDataTypes.delete(span.spanId);
|
|
745
754
|
if (!run) {
|
|
746
755
|
return;
|
|
747
756
|
}
|
|
@@ -69,7 +69,6 @@ export declare class OpenAIAgentsTracingProcessor implements TracingProcessor {
|
|
|
69
69
|
private _firstResponseInputs;
|
|
70
70
|
private _lastResponseOutputs;
|
|
71
71
|
private _runs;
|
|
72
|
-
private _spanDataTypes;
|
|
73
72
|
private _unpostedTraces;
|
|
74
73
|
private _unpostedSpans;
|
|
75
74
|
private _previousStoreByTrace;
|
|
@@ -366,6 +366,33 @@ function createResponsesUsageMetadata(usage) {
|
|
|
366
366
|
}
|
|
367
367
|
return result;
|
|
368
368
|
}
|
|
369
|
+
/**
|
|
370
|
+
* Return an ls_agent_type for the span, or undefined to leave it alone.
|
|
371
|
+
*
|
|
372
|
+
* If the run already has middleware/subagent/compaction, keep it. Otherwise
|
|
373
|
+
* guardrails become middleware and agents under any tool become subagents.
|
|
374
|
+
*
|
|
375
|
+
* Openai-agents structural counterpart to resolveVercelLsAgentType.
|
|
376
|
+
*/
|
|
377
|
+
function _resolveOpenAIAgentsLsAgentType(spanData, parentRun, existingTag) {
|
|
378
|
+
if (typeof existingTag === "string" &&
|
|
379
|
+
NON_ROOT_LS_AGENT_TYPES.has(existingTag)) {
|
|
380
|
+
return undefined;
|
|
381
|
+
}
|
|
382
|
+
if (spanData.type === "guardrail")
|
|
383
|
+
return "middleware";
|
|
384
|
+
// Walk the full parent chain, not just the direct parent: asTool inserts
|
|
385
|
+
// a chain run between the tool and the inner agent span.
|
|
386
|
+
if (spanData.type === "agent") {
|
|
387
|
+
let cursor = parentRun;
|
|
388
|
+
while (cursor !== undefined) {
|
|
389
|
+
if (cursor.run_type === "tool")
|
|
390
|
+
return "subagent";
|
|
391
|
+
cursor = cursor.parent_run;
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
return undefined;
|
|
395
|
+
}
|
|
369
396
|
/**
|
|
370
397
|
* Tracing processor for the [OpenAI Agents SDK](https://openai.github.io/openai-agents-js/).
|
|
371
398
|
*
|
|
@@ -460,12 +487,6 @@ export class OpenAIAgentsTracingProcessor {
|
|
|
460
487
|
writable: true,
|
|
461
488
|
value: new Map()
|
|
462
489
|
});
|
|
463
|
-
Object.defineProperty(this, "_spanDataTypes", {
|
|
464
|
-
enumerable: true,
|
|
465
|
-
configurable: true,
|
|
466
|
-
writable: true,
|
|
467
|
-
value: new Map()
|
|
468
|
-
});
|
|
469
490
|
Object.defineProperty(this, "_unpostedTraces", {
|
|
470
491
|
enumerable: true,
|
|
471
492
|
configurable: true,
|
|
@@ -681,28 +702,17 @@ export class OpenAIAgentsTracingProcessor {
|
|
|
681
702
|
console.error("Error creating span run:", e);
|
|
682
703
|
return;
|
|
683
704
|
}
|
|
684
|
-
//
|
|
685
|
-
//
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
}
|
|
695
|
-
if (!childRun.extra.metadata) {
|
|
696
|
-
childRun.extra.metadata = {};
|
|
697
|
-
}
|
|
698
|
-
const meta = childRun.extra.metadata;
|
|
699
|
-
if (!NON_ROOT_LS_AGENT_TYPES.has(meta.ls_agent_type)) {
|
|
700
|
-
meta.ls_agent_type = "subagent";
|
|
701
|
-
}
|
|
702
|
-
}
|
|
705
|
+
// Handoffs replace the caller rather than run as a tool, so a handoff
|
|
706
|
+
// agent has no tool ancestor and correctly stays untagged here.
|
|
707
|
+
if (!childRun.extra)
|
|
708
|
+
childRun.extra = {};
|
|
709
|
+
if (!childRun.extra.metadata)
|
|
710
|
+
childRun.extra.metadata = {};
|
|
711
|
+
const meta = childRun.extra.metadata;
|
|
712
|
+
const structuralTag = _resolveOpenAIAgentsLsAgentType(spanData, parentRun, meta.ls_agent_type);
|
|
713
|
+
if (structuralTag !== undefined) {
|
|
714
|
+
meta.ls_agent_type = structuralTag;
|
|
703
715
|
}
|
|
704
|
-
// Track span data type for parent lookups
|
|
705
|
-
this._spanDataTypes.set(span.spanId, spanData.type);
|
|
706
716
|
this._runs.set(span.spanId, childRun);
|
|
707
717
|
// Enter AsyncLocalStorage context synchronously so nested traceable()
|
|
708
718
|
// calls inside the span's body nest under this run. Remember the
|
|
@@ -738,7 +748,6 @@ export class OpenAIAgentsTracingProcessor {
|
|
|
738
748
|
enterRunTreeContext(previousStore);
|
|
739
749
|
}
|
|
740
750
|
const run = this._runs.get(span.spanId);
|
|
741
|
-
this._spanDataTypes.delete(span.spanId);
|
|
742
751
|
if (!run) {
|
|
743
752
|
return;
|
|
744
753
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "langsmith",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.5",
|
|
4
4
|
"description": "Client library to connect to the LangSmith Observability and Evaluation Platform.",
|
|
5
5
|
"packageManager": "pnpm@10.33.0",
|
|
6
6
|
"files": [
|
|
@@ -488,7 +488,7 @@
|
|
|
488
488
|
"brace-expansion@>=3.0.0 <5.0.7": "5.0.7",
|
|
489
489
|
"fast-uri": "3.1.6",
|
|
490
490
|
"postcss": "8.5.23",
|
|
491
|
-
"js-yaml": "4.3.
|
|
491
|
+
"js-yaml": "4.3.2",
|
|
492
492
|
"hono": "4.13.5",
|
|
493
493
|
"ip-address": "10.3.1",
|
|
494
494
|
"undici@>=7.0.0 <8.0.0": "7.29.0",
|