langsmith 0.8.8 → 0.8.10

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.
Files changed (65) hide show
  1. package/dist/_openapi_client/resources/annotation-queues/annotation-queues.cjs +10 -0
  2. package/dist/_openapi_client/resources/annotation-queues/annotation-queues.d.ts +10 -0
  3. package/dist/_openapi_client/resources/annotation-queues/annotation-queues.js +10 -0
  4. package/dist/_openapi_client/resources/annotation-queues/runs.cjs +13 -1
  5. package/dist/_openapi_client/resources/annotation-queues/runs.d.ts +13 -1
  6. package/dist/_openapi_client/resources/annotation-queues/runs.js +13 -1
  7. package/dist/_openapi_client/resources/datasets/experiment-runs.cjs +2 -0
  8. package/dist/_openapi_client/resources/datasets/experiment-runs.d.ts +2 -0
  9. package/dist/_openapi_client/resources/datasets/experiment-runs.js +2 -0
  10. package/dist/_openapi_client/resources/issues.d.ts +1 -1
  11. package/dist/_openapi_client/resources/public/runs.cjs +9 -7
  12. package/dist/_openapi_client/resources/public/runs.d.ts +8 -6
  13. package/dist/_openapi_client/resources/public/runs.js +9 -7
  14. package/dist/_openapi_client/resources/runs/runs.cjs +11 -6
  15. package/dist/_openapi_client/resources/runs/runs.d.ts +11 -6
  16. package/dist/_openapi_client/resources/runs/runs.js +11 -6
  17. package/dist/_openapi_client/resources/runs/share.cjs +4 -0
  18. package/dist/_openapi_client/resources/runs/share.d.ts +4 -0
  19. package/dist/_openapi_client/resources/runs/share.js +4 -0
  20. package/dist/_openapi_client/resources/threads.cjs +11 -8
  21. package/dist/_openapi_client/resources/threads.d.ts +11 -8
  22. package/dist/_openapi_client/resources/threads.js +11 -8
  23. package/dist/_openapi_client/resources/traces.cjs +6 -3
  24. package/dist/_openapi_client/resources/traces.d.ts +6 -3
  25. package/dist/_openapi_client/resources/traces.js +6 -3
  26. package/dist/client.cjs +295 -24
  27. package/dist/client.d.ts +63 -9
  28. package/dist/client.js +295 -24
  29. package/dist/evaluation/evaluate_comparative.cjs +7 -4
  30. package/dist/evaluation/evaluate_comparative.js +7 -4
  31. package/dist/experimental/vercel/_agent_type.cjs +30 -0
  32. package/dist/experimental/vercel/_agent_type.d.ts +5 -0
  33. package/dist/experimental/vercel/_agent_type.js +26 -0
  34. package/dist/experimental/vercel/telemetry.cjs +2 -7
  35. package/dist/experimental/vercel/telemetry.js +2 -7
  36. package/dist/experimental/vercel/wrap.cjs +5 -11
  37. package/dist/experimental/vercel/wrap.js +6 -12
  38. package/dist/index.cjs +1 -1
  39. package/dist/index.d.ts +1 -1
  40. package/dist/index.js +1 -1
  41. package/dist/sandbox/command_handle.cjs +34 -7
  42. package/dist/sandbox/command_handle.d.ts +1 -0
  43. package/dist/sandbox/command_handle.js +34 -7
  44. package/dist/sandbox/ws_execute.cjs +7 -3
  45. package/dist/sandbox/ws_execute.d.ts +4 -2
  46. package/dist/sandbox/ws_execute.js +7 -3
  47. package/dist/utils/_git.cjs +28 -1
  48. package/dist/utils/_git.js +28 -1
  49. package/dist/utils/ls_agent_type.cjs +31 -0
  50. package/dist/utils/ls_agent_type.d.ts +9 -0
  51. package/dist/utils/ls_agent_type.js +25 -0
  52. package/dist/utils/profiles.cjs +125 -1
  53. package/dist/utils/profiles.d.ts +6 -0
  54. package/dist/utils/profiles.js +124 -1
  55. package/dist/utils/v2_migration.cjs +18 -0
  56. package/dist/utils/v2_migration.d.ts +8 -0
  57. package/dist/utils/v2_migration.js +16 -0
  58. package/dist/utils/warn.cjs +30 -4
  59. package/dist/utils/warn.d.ts +4 -1
  60. package/dist/utils/warn.js +29 -4
  61. package/dist/wrappers/openai.cjs +4 -0
  62. package/dist/wrappers/openai.js +4 -0
  63. package/dist/wrappers/openai_agents.cjs +15 -12
  64. package/dist/wrappers/openai_agents.js +15 -12
  65. package/package.json +1 -1
@@ -7,6 +7,7 @@ const env_js_1 = require("../../env.cjs");
7
7
  const utils_js_1 = require("./utils.cjs");
8
8
  const utils_js_2 = require("./utils.cjs");
9
9
  const types_js_1 = require("../../utils/types.cjs");
10
+ const _agent_type_js_1 = require("./_agent_type.cjs");
10
11
  function _formatMessages(messages) {
11
12
  if (!Array.isArray(messages))
12
13
  return messages;
@@ -52,12 +53,6 @@ event, traceRawHttp) {
52
53
  }
53
54
  return (0, utils_js_1.convertMessageToTracedFormat)(output);
54
55
  }
55
- function _getLsAgentType(parentRunTree) {
56
- if ((0, run_trees_js_1.isRunTree)(parentRunTree) && parentRunTree.run_type === "tool") {
57
- return "subagent";
58
- }
59
- return "root";
60
- }
61
56
  function _hasNonzeroUsageMetadata(runTree) {
62
57
  const usageMetadata = runTree.extra?.metadata?.usage_metadata;
63
58
  if (!(0, types_js_1.isRecord)(usageMetadata))
@@ -200,7 +195,7 @@ function LangSmithTelemetry(config) {
200
195
  metadata: {
201
196
  ...customMetadata,
202
197
  ai_sdk_method: event.operationId,
203
- ls_agent_type: _getLsAgentType(parentRunTree),
198
+ ...(0, _agent_type_js_1.vercelLsAgentTypeMetadata)(parentRunTree),
204
199
  ls_model_name: event.modelId,
205
200
  ls_integration: "vercel-ai-sdk-telemetry",
206
201
  },
@@ -4,6 +4,7 @@ import { isEnvTracingEnabled } from "../../env.js";
4
4
  import { convertMessageToTracedFormat } from "./utils.js";
5
5
  import { setUsageMetadataOnRunTree } from "./utils.js";
6
6
  import { isPrimitive, isRecord } from "../../utils/types.js";
7
+ import { vercelLsAgentTypeMetadata } from "./_agent_type.js";
7
8
  function _formatMessages(messages) {
8
9
  if (!Array.isArray(messages))
9
10
  return messages;
@@ -49,12 +50,6 @@ event, traceRawHttp) {
49
50
  }
50
51
  return convertMessageToTracedFormat(output);
51
52
  }
52
- function _getLsAgentType(parentRunTree) {
53
- if (isRunTree(parentRunTree) && parentRunTree.run_type === "tool") {
54
- return "subagent";
55
- }
56
- return "root";
57
- }
58
53
  function _hasNonzeroUsageMetadata(runTree) {
59
54
  const usageMetadata = runTree.extra?.metadata?.usage_metadata;
60
55
  if (!isRecord(usageMetadata))
@@ -197,7 +192,7 @@ export function LangSmithTelemetry(config) {
197
192
  metadata: {
198
193
  ...customMetadata,
199
194
  ai_sdk_method: event.operationId,
200
- ls_agent_type: _getLsAgentType(parentRunTree),
195
+ ...vercelLsAgentTypeMetadata(parentRunTree),
201
196
  ls_model_name: event.modelId,
202
197
  ls_integration: "vercel-ai-sdk-telemetry",
203
198
  },
@@ -5,6 +5,7 @@ const middleware_js_1 = require("./middleware.cjs");
5
5
  const utils_js_1 = require("./utils.cjs");
6
6
  Object.defineProperty(exports, "convertMessageToTracedFormat", { enumerable: true, get: function () { return utils_js_1.convertMessageToTracedFormat; } });
7
7
  const traceable_js_1 = require("../../traceable.cjs");
8
+ const _agent_type_js_1 = require("./_agent_type.cjs");
8
9
  const _getModelDisplayName = (model) => {
9
10
  if (typeof model === "string") {
10
11
  return model;
@@ -118,19 +119,12 @@ const _resolveConfigs = (baseLsConfig, runtimeLsConfig) => {
118
119
  resolvedToolConfig,
119
120
  };
120
121
  };
121
- const _getLsAgentType = () => {
122
- const parentRun = (0, traceable_js_1.getCurrentRunTree)(true);
123
- if (parentRun != null && parentRun.run_type === "tool") {
124
- return "subagent";
125
- }
126
- return "root";
127
- };
128
122
  const _getGenerateTextWrapperConfig = ({ model, runName, aiSdkMethodName, resolvedLsConfig, hasExplicitOutput, hasExplicitExperimentalOutput, traceResponseMetadata, }) => {
129
123
  return {
130
124
  name: runName ?? _getModelDisplayName(model),
131
125
  ...resolvedLsConfig,
132
126
  metadata: {
133
- ls_agent_type: _getLsAgentType(),
127
+ ...(0, _agent_type_js_1.vercelLsAgentTypeMetadata)(),
134
128
  ai_sdk_method: aiSdkMethodName ?? "ai.generateText",
135
129
  ...resolvedLsConfig?.metadata,
136
130
  },
@@ -206,7 +200,7 @@ const _getStreamTextWrapperConfig = ({ model, runName, aiSdkMethodName, resolved
206
200
  name: runName ?? _getModelDisplayName(model),
207
201
  ...resolvedLsConfig,
208
202
  metadata: {
209
- ls_agent_type: _getLsAgentType(),
203
+ ...(0, _agent_type_js_1.vercelLsAgentTypeMetadata)(),
210
204
  ai_sdk_method: aiSdkMethodName ?? "ai.streamText",
211
205
  ...resolvedLsConfig?.metadata,
212
206
  },
@@ -409,7 +403,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
409
403
  name: _getModelDisplayName(params.model),
410
404
  ...resolvedLsConfig,
411
405
  metadata: {
412
- ls_agent_type: _getLsAgentType(),
406
+ ...(0, _agent_type_js_1.vercelLsAgentTypeMetadata)(),
413
407
  ai_sdk_method: "ai.generateObject",
414
408
  ...resolvedLsConfig?.metadata,
415
409
  },
@@ -531,7 +525,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
531
525
  name: _getModelDisplayName(params.model),
532
526
  ...resolvedLsConfig,
533
527
  metadata: {
534
- ls_agent_type: _getLsAgentType(),
528
+ ...(0, _agent_type_js_1.vercelLsAgentTypeMetadata)(),
535
529
  ai_sdk_method: "ai.streamObject",
536
530
  ...resolvedLsConfig?.metadata,
537
531
  },
@@ -1,6 +1,7 @@
1
1
  import { LangSmithMiddleware, } from "./middleware.js";
2
2
  import { convertMessageToTracedFormat } from "./utils.js";
3
- import { isTraceableFunction, traceable, getCurrentRunTree, } from "../../traceable.js";
3
+ import { isTraceableFunction, traceable } from "../../traceable.js";
4
+ import { vercelLsAgentTypeMetadata } from "./_agent_type.js";
4
5
  const _getModelDisplayName = (model) => {
5
6
  if (typeof model === "string") {
6
7
  return model;
@@ -114,19 +115,12 @@ const _resolveConfigs = (baseLsConfig, runtimeLsConfig) => {
114
115
  resolvedToolConfig,
115
116
  };
116
117
  };
117
- const _getLsAgentType = () => {
118
- const parentRun = getCurrentRunTree(true);
119
- if (parentRun != null && parentRun.run_type === "tool") {
120
- return "subagent";
121
- }
122
- return "root";
123
- };
124
118
  const _getGenerateTextWrapperConfig = ({ model, runName, aiSdkMethodName, resolvedLsConfig, hasExplicitOutput, hasExplicitExperimentalOutput, traceResponseMetadata, }) => {
125
119
  return {
126
120
  name: runName ?? _getModelDisplayName(model),
127
121
  ...resolvedLsConfig,
128
122
  metadata: {
129
- ls_agent_type: _getLsAgentType(),
123
+ ...vercelLsAgentTypeMetadata(),
130
124
  ai_sdk_method: aiSdkMethodName ?? "ai.generateText",
131
125
  ...resolvedLsConfig?.metadata,
132
126
  },
@@ -202,7 +196,7 @@ const _getStreamTextWrapperConfig = ({ model, runName, aiSdkMethodName, resolved
202
196
  name: runName ?? _getModelDisplayName(model),
203
197
  ...resolvedLsConfig,
204
198
  metadata: {
205
- ls_agent_type: _getLsAgentType(),
199
+ ...vercelLsAgentTypeMetadata(),
206
200
  ai_sdk_method: aiSdkMethodName ?? "ai.streamText",
207
201
  ...resolvedLsConfig?.metadata,
208
202
  },
@@ -404,7 +398,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
404
398
  name: _getModelDisplayName(params.model),
405
399
  ...resolvedLsConfig,
406
400
  metadata: {
407
- ls_agent_type: _getLsAgentType(),
401
+ ...vercelLsAgentTypeMetadata(),
408
402
  ai_sdk_method: "ai.generateObject",
409
403
  ...resolvedLsConfig?.metadata,
410
404
  },
@@ -526,7 +520,7 @@ const wrapAISDK = (ai, baseLsConfig) => {
526
520
  name: _getModelDisplayName(params.model),
527
521
  ...resolvedLsConfig,
528
522
  metadata: {
529
- ls_agent_type: _getLsAgentType(),
523
+ ...vercelLsAgentTypeMetadata(),
530
524
  ai_sdk_method: "ai.streamObject",
531
525
  ...resolvedLsConfig?.metadata,
532
526
  },
package/dist/index.cjs CHANGED
@@ -35,6 +35,6 @@ Object.defineProperty(exports, "UnprocessableEntityError", { enumerable: true, g
35
35
  Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return error_js_1.RateLimitError; } });
36
36
  Object.defineProperty(exports, "InternalServerError", { enumerable: true, get: function () { return error_js_1.InternalServerError; } });
37
37
  // Update using pnpm bump-version
38
- exports.__version__ = "0.8.8";
38
+ exports.__version__ = "0.8.10";
39
39
  // Metadata key to hide a traced run from LangSmith's Messages View.
40
40
  exports.LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
package/dist/index.d.ts CHANGED
@@ -7,5 +7,5 @@ export { computeRunIdForSecondaryReplica, uuid7, uuid7FromTime, } from "./uuid.j
7
7
  export { isTracingEnabled } from "./utils/guard.js";
8
8
  export { Cache, PromptCache, type CacheConfig, type CacheMetrics, 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
- export declare const __version__ = "0.8.8";
10
+ export declare const __version__ = "0.8.10";
11
11
  export declare const LS_MESSAGE_VIEW_EXCLUDE: "ls_message_view_exclude";
package/dist/index.js CHANGED
@@ -7,6 +7,6 @@ export { isTracingEnabled } from "./utils/guard.js";
7
7
  export { Cache, PromptCache, configureGlobalPromptCache, promptCacheSingleton, } from "./utils/prompt_cache/index.js";
8
8
  export { LangsmithError, APIError, APIUserAbortError, APIConnectionError, APIConnectionTimeoutError, BadRequestError, AuthenticationError, PermissionDeniedError, NotFoundError, ConflictError, UnprocessableEntityError, RateLimitError, InternalServerError, } from "./_openapi_client/core/error.js";
9
9
  // Update using pnpm bump-version
10
- export const __version__ = "0.8.8";
10
+ export const __version__ = "0.8.10";
11
11
  // Metadata key to hide a traced run from LangSmith's Messages View.
12
12
  export const LS_MESSAGE_VIEW_EXCLUDE = "ls_message_view_exclude";
@@ -8,6 +8,22 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.CommandHandle = void 0;
10
10
  const errors_js_1 = require("./errors.cjs");
11
+ /**
12
+ * Whether a 'started' frame proves *this* command was reattached to.
13
+ *
14
+ * A command and its WebSocket are separate things: the command keeps running on
15
+ * the server and the socket is only this client's attachment to it. The server
16
+ * acknowledges every successful reattachment with 'started', which for a command
17
+ * that produces no output is the only evidence it landed. One naming a different
18
+ * command is not evidence, and must not clear the reconnect budget.
19
+ */
20
+ function acknowledgesReconnect(msg, commandId) {
21
+ const acked = msg.command_id;
22
+ if (acked === commandId)
23
+ return true;
24
+ console.warn(`Ignoring reconnect acknowledgement for command ${String(acked)} while attached to ${String(commandId)}`);
25
+ return false;
26
+ }
11
27
  /**
12
28
  * Async handle to a running command with streaming output and auto-reconnect.
13
29
  *
@@ -107,6 +123,12 @@ class CommandHandle {
107
123
  writable: true,
108
124
  value: void 0
109
125
  });
126
+ Object.defineProperty(this, "_reconnectAttempts", {
127
+ enumerable: true,
128
+ configurable: true,
129
+ writable: true,
130
+ value: 0
131
+ });
110
132
  Object.defineProperty(this, "_onStdout", {
111
133
  enumerable: true,
112
134
  configurable: true,
@@ -192,7 +214,12 @@ class CommandHandle {
192
214
  return;
193
215
  for await (const msg of this._stream) {
194
216
  const msgType = msg.type;
195
- if (msgType === "stdout" || msgType === "stderr") {
217
+ if (msgType === "started") {
218
+ if (acknowledgesReconnect(msg, this._commandId)) {
219
+ this._reconnectAttempts = 0;
220
+ }
221
+ }
222
+ else if (msgType === "stdout" || msgType === "stderr") {
196
223
  const chunk = {
197
224
  stream: msgType,
198
225
  data: msg.data,
@@ -227,11 +254,11 @@ class CommandHandle {
227
254
  * - After kill(): no reconnect, error propagates
228
255
  */
229
256
  async *[Symbol.asyncIterator]() {
230
- let reconnectAttempts = 0;
257
+ this._reconnectAttempts = 0;
231
258
  while (true) {
232
259
  try {
233
260
  for await (const chunk of this._iterStream()) {
234
- reconnectAttempts = 0; // Reset on successful data
261
+ this._reconnectAttempts = 0; // Reset on successful data
235
262
  if (chunk.stream === "stdout") {
236
263
  this._lastStdoutOffset =
237
264
  chunk.offset + new TextEncoder().encode(chunk.data).length;
@@ -255,13 +282,13 @@ class CommandHandle {
255
282
  if (this._control && this._control.killed) {
256
283
  throw e;
257
284
  }
258
- reconnectAttempts++;
259
- if (reconnectAttempts > CommandHandle.MAX_AUTO_RECONNECTS) {
260
- throw new errors_js_1.LangSmithSandboxConnectionError(`Lost connection ${reconnectAttempts} times in succession, giving up`);
285
+ this._reconnectAttempts++;
286
+ if (this._reconnectAttempts > CommandHandle.MAX_AUTO_RECONNECTS) {
287
+ throw new errors_js_1.LangSmithSandboxConnectionError(`Failed to reattach to the command ${this._reconnectAttempts} times in succession, giving up`);
261
288
  }
262
289
  const isHotReload = e instanceof errors_js_1.LangSmithSandboxServerReloadError;
263
290
  if (!isHotReload) {
264
- const delay = Math.min(CommandHandle.BACKOFF_BASE * 2 ** (reconnectAttempts - 1), CommandHandle.BACKOFF_MAX);
291
+ const delay = Math.min(CommandHandle.BACKOFF_BASE * 2 ** (this._reconnectAttempts - 1), CommandHandle.BACKOFF_MAX);
265
292
  await new Promise((r) => setTimeout(r, delay * 1000));
266
293
  }
267
294
  if (this._commandId === null) {
@@ -45,6 +45,7 @@ export declare class CommandHandle {
45
45
  private _lastStdoutOffset;
46
46
  private _lastStderrOffset;
47
47
  private _started;
48
+ private _reconnectAttempts;
48
49
  private _onStdout?;
49
50
  private _onStderr?;
50
51
  /**
@@ -5,6 +5,22 @@
5
5
  * Port of Python's AsyncCommandHandle to TypeScript.
6
6
  */
7
7
  import { LangSmithSandboxConnectionError, LangSmithSandboxServerReloadError, LangSmithSandboxOperationError, LangSmithStreamEndedBeforeStartedError, } from "./errors.js";
8
+ /**
9
+ * Whether a 'started' frame proves *this* command was reattached to.
10
+ *
11
+ * A command and its WebSocket are separate things: the command keeps running on
12
+ * the server and the socket is only this client's attachment to it. The server
13
+ * acknowledges every successful reattachment with 'started', which for a command
14
+ * that produces no output is the only evidence it landed. One naming a different
15
+ * command is not evidence, and must not clear the reconnect budget.
16
+ */
17
+ function acknowledgesReconnect(msg, commandId) {
18
+ const acked = msg.command_id;
19
+ if (acked === commandId)
20
+ return true;
21
+ console.warn(`Ignoring reconnect acknowledgement for command ${String(acked)} while attached to ${String(commandId)}`);
22
+ return false;
23
+ }
8
24
  /**
9
25
  * Async handle to a running command with streaming output and auto-reconnect.
10
26
  *
@@ -104,6 +120,12 @@ export class CommandHandle {
104
120
  writable: true,
105
121
  value: void 0
106
122
  });
123
+ Object.defineProperty(this, "_reconnectAttempts", {
124
+ enumerable: true,
125
+ configurable: true,
126
+ writable: true,
127
+ value: 0
128
+ });
107
129
  Object.defineProperty(this, "_onStdout", {
108
130
  enumerable: true,
109
131
  configurable: true,
@@ -189,7 +211,12 @@ export class CommandHandle {
189
211
  return;
190
212
  for await (const msg of this._stream) {
191
213
  const msgType = msg.type;
192
- if (msgType === "stdout" || msgType === "stderr") {
214
+ if (msgType === "started") {
215
+ if (acknowledgesReconnect(msg, this._commandId)) {
216
+ this._reconnectAttempts = 0;
217
+ }
218
+ }
219
+ else if (msgType === "stdout" || msgType === "stderr") {
193
220
  const chunk = {
194
221
  stream: msgType,
195
222
  data: msg.data,
@@ -224,11 +251,11 @@ export class CommandHandle {
224
251
  * - After kill(): no reconnect, error propagates
225
252
  */
226
253
  async *[Symbol.asyncIterator]() {
227
- let reconnectAttempts = 0;
254
+ this._reconnectAttempts = 0;
228
255
  while (true) {
229
256
  try {
230
257
  for await (const chunk of this._iterStream()) {
231
- reconnectAttempts = 0; // Reset on successful data
258
+ this._reconnectAttempts = 0; // Reset on successful data
232
259
  if (chunk.stream === "stdout") {
233
260
  this._lastStdoutOffset =
234
261
  chunk.offset + new TextEncoder().encode(chunk.data).length;
@@ -252,13 +279,13 @@ export class CommandHandle {
252
279
  if (this._control && this._control.killed) {
253
280
  throw e;
254
281
  }
255
- reconnectAttempts++;
256
- if (reconnectAttempts > CommandHandle.MAX_AUTO_RECONNECTS) {
257
- throw new LangSmithSandboxConnectionError(`Lost connection ${reconnectAttempts} times in succession, giving up`);
282
+ this._reconnectAttempts++;
283
+ if (this._reconnectAttempts > CommandHandle.MAX_AUTO_RECONNECTS) {
284
+ throw new LangSmithSandboxConnectionError(`Failed to reattach to the command ${this._reconnectAttempts} times in succession, giving up`);
258
285
  }
259
286
  const isHotReload = e instanceof LangSmithSandboxServerReloadError;
260
287
  if (!isHotReload) {
261
- const delay = Math.min(CommandHandle.BACKOFF_BASE * 2 ** (reconnectAttempts - 1), CommandHandle.BACKOFF_MAX);
288
+ const delay = Math.min(CommandHandle.BACKOFF_BASE * 2 ** (this._reconnectAttempts - 1), CommandHandle.BACKOFF_MAX);
262
289
  await new Promise((r) => setTimeout(r, delay * 1000));
263
290
  }
264
291
  if (this._commandId === null) {
@@ -382,8 +382,10 @@ async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
382
382
  * Reconnect to an existing command over WebSocket.
383
383
  *
384
384
  * Returns a tuple of [async_message_iterator, control], same as runWsStream.
385
- * The iterator yields stdout, stderr, exit, and error messages.
386
- * No 'started' message is sent on reconnection.
385
+ * The iterator yields the server's 'started' acknowledgement, then stdout,
386
+ * stderr, exit, and error messages. That acknowledgement is the only evidence a
387
+ * reattachment landed for a command producing no output, so it is forwarded
388
+ * rather than dropped.
387
389
  */
388
390
  async function reconnectWsStream(dataplaneUrl, apiKey, commandId, options = {}) {
389
391
  const { stdoutOffset = 0, stderrOffset = 0, headers: extraHeaders } = options;
@@ -405,7 +407,9 @@ async function reconnectWsStream(dataplaneUrl, apiKey, commandId, options = {})
405
407
  // Read messages until exit or error
406
408
  for await (const msg of readWsMessages(ws)) {
407
409
  const msgType = msg.type;
408
- if (msgType === "stdout" || msgType === "stderr") {
410
+ if (msgType === "started" ||
411
+ msgType === "stdout" ||
412
+ msgType === "stderr") {
409
413
  yield msg;
410
414
  }
411
415
  else if (msgType === "exit") {
@@ -70,8 +70,10 @@ export declare function runWsStream(dataplaneUrl: string, apiKey: string | undef
70
70
  * Reconnect to an existing command over WebSocket.
71
71
  *
72
72
  * Returns a tuple of [async_message_iterator, control], same as runWsStream.
73
- * The iterator yields stdout, stderr, exit, and error messages.
74
- * No 'started' message is sent on reconnection.
73
+ * The iterator yields the server's 'started' acknowledgement, then stdout,
74
+ * stderr, exit, and error messages. That acknowledgement is the only evidence a
75
+ * reattachment landed for a command producing no output, so it is forwarded
76
+ * rather than dropped.
75
77
  */
76
78
  export declare function reconnectWsStream(dataplaneUrl: string, apiKey: string | undefined, commandId: string, options?: {
77
79
  stdoutOffset?: number;
@@ -369,8 +369,10 @@ export async function runWsStream(dataplaneUrl, apiKey, command, options = {}) {
369
369
  * Reconnect to an existing command over WebSocket.
370
370
  *
371
371
  * Returns a tuple of [async_message_iterator, control], same as runWsStream.
372
- * The iterator yields stdout, stderr, exit, and error messages.
373
- * No 'started' message is sent on reconnection.
372
+ * The iterator yields the server's 'started' acknowledgement, then stdout,
373
+ * stderr, exit, and error messages. That acknowledgement is the only evidence a
374
+ * reattachment landed for a command producing no output, so it is forwarded
375
+ * rather than dropped.
374
376
  */
375
377
  export async function reconnectWsStream(dataplaneUrl, apiKey, commandId, options = {}) {
376
378
  const { stdoutOffset = 0, stderrOffset = 0, headers: extraHeaders } = options;
@@ -392,7 +394,9 @@ export async function reconnectWsStream(dataplaneUrl, apiKey, commandId, options
392
394
  // Read messages until exit or error
393
395
  for await (const msg of readWsMessages(ws)) {
394
396
  const msgType = msg.type;
395
- if (msgType === "stdout" || msgType === "stderr") {
397
+ if (msgType === "started" ||
398
+ msgType === "stdout" ||
399
+ msgType === "stderr") {
396
400
  yield msg;
397
401
  }
398
402
  else if (msgType === "exit") {
@@ -17,6 +17,33 @@ const execGit = (command, exec) => {
17
17
  });
18
18
  });
19
19
  };
20
+ function sanitizeRemoteUrl(remoteUrl) {
21
+ if (remoteUrl == null) {
22
+ return remoteUrl;
23
+ }
24
+ const schemeSeparator = remoteUrl.indexOf("://");
25
+ if (schemeSeparator === -1) {
26
+ return remoteUrl;
27
+ }
28
+ const scheme = remoteUrl.slice(0, schemeSeparator).toLowerCase();
29
+ if (scheme !== "http" && scheme !== "https") {
30
+ return remoteUrl;
31
+ }
32
+ const authorityStart = schemeSeparator + "://".length;
33
+ let authorityEnd = remoteUrl.length;
34
+ for (const delimiter of ["/", "?", "#"]) {
35
+ const delimiterIndex = remoteUrl.indexOf(delimiter, authorityStart);
36
+ if (delimiterIndex !== -1) {
37
+ authorityEnd = Math.min(authorityEnd, delimiterIndex);
38
+ }
39
+ }
40
+ const authority = remoteUrl.slice(authorityStart, authorityEnd);
41
+ const userinfoEnd = authority.lastIndexOf("@");
42
+ if (userinfoEnd === -1) {
43
+ return remoteUrl;
44
+ }
45
+ return `${remoteUrl.slice(0, authorityStart)}${authority.slice(userinfoEnd + 1)}${remoteUrl.slice(authorityEnd)}`;
46
+ }
20
47
  const getGitInfo = async (remote = "origin") => {
21
48
  let exec;
22
49
  try {
@@ -42,7 +69,7 @@ const getGitInfo = async (remote = "origin") => {
42
69
  execGit(["log", "-1", "--format=%ae"], exec),
43
70
  ]);
44
71
  return {
45
- remoteUrl,
72
+ remoteUrl: sanitizeRemoteUrl(remoteUrl),
46
73
  commit,
47
74
  commitTime,
48
75
  branch,
@@ -14,6 +14,33 @@ const execGit = (command, exec) => {
14
14
  });
15
15
  });
16
16
  };
17
+ function sanitizeRemoteUrl(remoteUrl) {
18
+ if (remoteUrl == null) {
19
+ return remoteUrl;
20
+ }
21
+ const schemeSeparator = remoteUrl.indexOf("://");
22
+ if (schemeSeparator === -1) {
23
+ return remoteUrl;
24
+ }
25
+ const scheme = remoteUrl.slice(0, schemeSeparator).toLowerCase();
26
+ if (scheme !== "http" && scheme !== "https") {
27
+ return remoteUrl;
28
+ }
29
+ const authorityStart = schemeSeparator + "://".length;
30
+ let authorityEnd = remoteUrl.length;
31
+ for (const delimiter of ["/", "?", "#"]) {
32
+ const delimiterIndex = remoteUrl.indexOf(delimiter, authorityStart);
33
+ if (delimiterIndex !== -1) {
34
+ authorityEnd = Math.min(authorityEnd, delimiterIndex);
35
+ }
36
+ }
37
+ const authority = remoteUrl.slice(authorityStart, authorityEnd);
38
+ const userinfoEnd = authority.lastIndexOf("@");
39
+ if (userinfoEnd === -1) {
40
+ return remoteUrl;
41
+ }
42
+ return `${remoteUrl.slice(0, authorityStart)}${authority.slice(userinfoEnd + 1)}${remoteUrl.slice(authorityEnd)}`;
43
+ }
17
44
  export const getGitInfo = async (remote = "origin") => {
18
45
  let exec;
19
46
  try {
@@ -39,7 +66,7 @@ export const getGitInfo = async (remote = "origin") => {
39
66
  execGit(["log", "-1", "--format=%ae"], exec),
40
67
  ]);
41
68
  return {
42
- remoteUrl,
69
+ remoteUrl: sanitizeRemoteUrl(remoteUrl),
43
70
  commit,
44
71
  commitTime,
45
72
  branch,
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ // Shared primitives for the `ls_agent_type` metadata tag.
3
+ // Consumed by wrappers/integrations that stamp or inspect `ls_agent_type` on
4
+ // traced runs (wrap_openai, OpenAI Agents SDK, Vercel, future wrappers).
5
+ // Keep this module SDK-agnostic: the caller passes in the parent run tree.
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.NON_ROOT_LS_AGENT_TYPES = void 0;
8
+ exports.resolveDefaultLsAgentType = resolveDefaultLsAgentType;
9
+ exports.lsAgentTypeMetadata = lsAgentTypeMetadata;
10
+ exports.defaultLsAgentTypeMetadata = defaultLsAgentTypeMetadata;
11
+ const run_trees_js_1 = require("../run_trees.cjs");
12
+ // Non-root tags: preserved against default/structural stamping.
13
+ exports.NON_ROOT_LS_AGENT_TYPES = new Set([
14
+ "middleware",
15
+ "subagent",
16
+ "compaction",
17
+ ]);
18
+ // `"root"` at trace root; `undefined` when nested (rely on propagation).
19
+ function resolveDefaultLsAgentType(parentRunTree) {
20
+ return (0, run_trees_js_1.isRunTree)(parentRunTree) ? undefined : "root";
21
+ }
22
+ // Spread helper: `{ ls_agent_type: tag }` when tag is set, `{}` when undefined.
23
+ function lsAgentTypeMetadata(tag) {
24
+ return tag !== undefined ? { ls_agent_type: tag } : {};
25
+ }
26
+ // Preserves user-supplied ls_agent_type; stamps default only when key is absent.
27
+ function defaultLsAgentTypeMetadata(existingMetadata, parentRunTree) {
28
+ if ("ls_agent_type" in existingMetadata)
29
+ return {};
30
+ return lsAgentTypeMetadata(resolveDefaultLsAgentType(parentRunTree));
31
+ }
@@ -0,0 +1,9 @@
1
+ export type LsAgentType = "root" | "middleware" | "subagent" | "compaction";
2
+ export declare const NON_ROOT_LS_AGENT_TYPES: ReadonlySet<string>;
3
+ export declare function resolveDefaultLsAgentType(parentRunTree?: unknown): LsAgentType | undefined;
4
+ export declare function lsAgentTypeMetadata(tag: LsAgentType | undefined): {
5
+ ls_agent_type?: LsAgentType;
6
+ };
7
+ export declare function defaultLsAgentTypeMetadata(existingMetadata: Record<string, unknown>, parentRunTree?: unknown): {
8
+ ls_agent_type?: LsAgentType;
9
+ };
@@ -0,0 +1,25 @@
1
+ // Shared primitives for the `ls_agent_type` metadata tag.
2
+ // Consumed by wrappers/integrations that stamp or inspect `ls_agent_type` on
3
+ // traced runs (wrap_openai, OpenAI Agents SDK, Vercel, future wrappers).
4
+ // Keep this module SDK-agnostic: the caller passes in the parent run tree.
5
+ import { isRunTree } from "../run_trees.js";
6
+ // Non-root tags: preserved against default/structural stamping.
7
+ export const NON_ROOT_LS_AGENT_TYPES = new Set([
8
+ "middleware",
9
+ "subagent",
10
+ "compaction",
11
+ ]);
12
+ // `"root"` at trace root; `undefined` when nested (rely on propagation).
13
+ export function resolveDefaultLsAgentType(parentRunTree) {
14
+ return isRunTree(parentRunTree) ? undefined : "root";
15
+ }
16
+ // Spread helper: `{ ls_agent_type: tag }` when tag is set, `{}` when undefined.
17
+ export function lsAgentTypeMetadata(tag) {
18
+ return tag !== undefined ? { ls_agent_type: tag } : {};
19
+ }
20
+ // Preserves user-supplied ls_agent_type; stamps default only when key is absent.
21
+ export function defaultLsAgentTypeMetadata(existingMetadata, parentRunTree) {
22
+ if ("ls_agent_type" in existingMetadata)
23
+ return {};
24
+ return lsAgentTypeMetadata(resolveDefaultLsAgentType(parentRunTree));
25
+ }