deepline 0.1.301 → 0.1.302

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 (35) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +8 -0
  2. package/dist/bundling-sources/sdk/src/errors.ts +57 -15
  3. package/dist/bundling-sources/sdk/src/http.ts +82 -5
  4. package/dist/bundling-sources/sdk/src/index.ts +4 -0
  5. package/dist/bundling-sources/sdk/src/play.ts +29 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +5 -3
  7. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +120 -14
  8. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +10 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +59 -11
  10. package/dist/bundling-sources/shared_libs/play-runtime/execution-ledger-store.ts +3 -3
  11. package/dist/bundling-sources/shared_libs/play-runtime/execution-plan.ts +0 -15
  12. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +3 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +3 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +136 -36
  15. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +17 -12
  16. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +210 -5
  17. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +4 -0
  18. package/dist/bundling-sources/shared_libs/plays/artifact-contract-version.ts +6 -0
  19. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +4 -0
  20. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +159 -12
  21. package/dist/bundling-sources/shared_libs/plays/contracts.ts +69 -1
  22. package/dist/bundling-sources/shared_libs/tool-execution-error.ts +428 -0
  23. package/dist/cli/index.js +501 -179
  24. package/dist/cli/index.mjs +501 -179
  25. package/dist/index.d.mts +39 -18
  26. package/dist/index.d.ts +39 -18
  27. package/dist/index.js +394 -59
  28. package/dist/index.mjs +391 -59
  29. package/dist/plays/bundle-play-file.d.mts +4 -2
  30. package/dist/plays/bundle-play-file.d.ts +4 -2
  31. package/dist/plays/bundle-play-file.mjs +116 -19
  32. package/dist/{compiler-manifest-BjopNIqx.d.mts → tool-execution-error-9mH4i-mJ.d.mts} +79 -1
  33. package/dist/{compiler-manifest-BjopNIqx.d.ts → tool-execution-error-9mH4i-mJ.d.ts} +79 -1
  34. package/package.json +1 -1
  35. package/dist/bundling-sources/shared_libs/play-runtime/completed-receipt-cache.ts +0 -166
package/dist/index.js CHANGED
@@ -52,10 +52,13 @@ __export(src_exports, {
52
52
  PLAY_BOOTSTRAP_STAGE_KINDS: () => PLAY_BOOTSTRAP_STAGE_KINDS,
53
53
  PLAY_BOOTSTRAP_TEMPLATES: () => PLAY_BOOTSTRAP_TEMPLATES,
54
54
  PROD_URL: () => PROD_URL,
55
+ ProviderTransientError: () => ProviderTransientError,
55
56
  RateLimitError: () => RateLimitError,
56
57
  RunObserveTransportUnavailableError: () => RunObserveTransportUnavailableError,
57
58
  SDK_API_CONTRACT: () => SDK_API_CONTRACT,
58
59
  SDK_VERSION: () => SDK_VERSION,
60
+ ToolExecutionError: () => ToolExecutionError,
61
+ ToolRateLimitError: () => ToolRateLimitError,
59
62
  defineInput: () => defineInput,
60
63
  defineMonitor: () => defineMonitor,
61
64
  definePlay: () => definePlay,
@@ -82,19 +85,252 @@ var import_node_fs = require("fs");
82
85
  var import_node_os = require("os");
83
86
  var import_node_path = require("path");
84
87
 
85
- // src/errors.ts
86
- var DeeplineError = class extends Error {
88
+ // ../shared_libs/tool-execution-error.ts
89
+ var DEEPLINE_ERROR_BRAND = /* @__PURE__ */ Symbol.for("deepline.error.v1");
90
+ var TOOL_EXECUTION_ERROR_BRAND = /* @__PURE__ */ Symbol.for(
91
+ "deepline.tool-execution-error.v1"
92
+ );
93
+ var PROVIDER_TRANSIENT_ERROR_BRAND = /* @__PURE__ */ Symbol.for(
94
+ "deepline.provider-transient-error.v1"
95
+ );
96
+ var LEGACY_TOOL_EXECUTION_ERROR_SCHEMA_VERSION = 0;
97
+ var TOOL_EXECUTION_ERROR_SCHEMA_VERSION = 1;
98
+ var TOOL_EXECUTION_ERROR_SCHEMA_HEADER = "x-deepline-tool-error-schema";
99
+ var MAX_IDENTIFIER_LENGTH = 200;
100
+ var MAX_CODE_LENGTH = 160;
101
+ function nativeInstanceOf(constructor, value) {
102
+ return Reflect.apply(Function.prototype[Symbol.hasInstance], constructor, [
103
+ value
104
+ ]);
105
+ }
106
+ function hasBrand(value, brand) {
107
+ return typeof value === "object" && value !== null && value[brand] === true;
108
+ }
109
+ function applyBrand(value, brand) {
110
+ if (hasBrand(value, brand)) return;
111
+ Object.defineProperty(value, brand, {
112
+ configurable: false,
113
+ enumerable: false,
114
+ writable: false,
115
+ value: true
116
+ });
117
+ }
118
+ var DeeplineError = class _DeeplineError extends Error {
87
119
  constructor(message, statusCode, code, details) {
88
120
  super(message);
89
121
  this.statusCode = statusCode;
90
122
  this.code = code;
91
123
  this.details = details;
92
124
  this.name = "DeeplineError";
125
+ applyBrand(this, DEEPLINE_ERROR_BRAND);
93
126
  }
94
127
  statusCode;
95
128
  code;
96
129
  details;
130
+ static [Symbol.hasInstance](value) {
131
+ if (this !== _DeeplineError) return nativeInstanceOf(this, value);
132
+ return hasBrand(value, DEEPLINE_ERROR_BRAND);
133
+ }
97
134
  };
135
+ var ToolExecutionError = class _ToolExecutionError extends DeeplineError {
136
+ toolId;
137
+ provider;
138
+ operation;
139
+ origin;
140
+ category;
141
+ retryable;
142
+ requestId;
143
+ retryAfterMs;
144
+ networkKind;
145
+ networkScope;
146
+ constructor(message, options) {
147
+ super(
148
+ message,
149
+ options.statusCode ?? void 0,
150
+ options.code ?? void 0,
151
+ options.details
152
+ );
153
+ this.name = "ToolExecutionError";
154
+ this.toolId = options.toolId;
155
+ this.provider = options.provider;
156
+ this.operation = options.operation;
157
+ this.origin = options.origin;
158
+ this.category = options.category;
159
+ this.retryable = options.retryable;
160
+ this.requestId = options.requestId;
161
+ this.retryAfterMs = options.retryAfterMs;
162
+ this.networkKind = options.networkKind;
163
+ this.networkScope = options.networkScope;
164
+ applyBrand(this, TOOL_EXECUTION_ERROR_BRAND);
165
+ if (isProviderTransientFailure(options)) {
166
+ applyBrand(this, PROVIDER_TRANSIENT_ERROR_BRAND);
167
+ }
168
+ }
169
+ static [Symbol.hasInstance](value) {
170
+ if (this !== _ToolExecutionError) return nativeInstanceOf(this, value);
171
+ return hasBrand(value, TOOL_EXECUTION_ERROR_BRAND);
172
+ }
173
+ };
174
+ function brandAsToolExecutionError(value) {
175
+ applyBrand(value, TOOL_EXECUTION_ERROR_BRAND);
176
+ }
177
+ function isProviderTransientFailure(input) {
178
+ return input.origin === "provider" && (input.category === "rate_limit" || input.category === "network" || input.category === "upstream");
179
+ }
180
+ var ProviderTransientError = class _ProviderTransientError extends ToolExecutionError {
181
+ origin = "provider";
182
+ constructor(message, options) {
183
+ super(message, {
184
+ ...options,
185
+ origin: "provider",
186
+ category: options.category
187
+ });
188
+ this.name = "ProviderTransientError";
189
+ this.category = options.category;
190
+ applyBrand(this, PROVIDER_TRANSIENT_ERROR_BRAND);
191
+ }
192
+ static [Symbol.hasInstance](value) {
193
+ if (this !== _ProviderTransientError) return nativeInstanceOf(this, value);
194
+ return hasBrand(value, PROVIDER_TRANSIENT_ERROR_BRAND);
195
+ }
196
+ };
197
+ function brandAsProviderTransientError(value) {
198
+ applyBrand(value, PROVIDER_TRANSIENT_ERROR_BRAND);
199
+ }
200
+ function boundedString(value, maxLength = MAX_IDENTIFIER_LENGTH) {
201
+ if (typeof value !== "string") return null;
202
+ const normalized = value.trim();
203
+ return normalized ? normalized.slice(0, maxLength) : null;
204
+ }
205
+ function finiteNonNegativeInteger(value) {
206
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && Number.isInteger(value) ? value : null;
207
+ }
208
+ function normalizeToolExecutionOrigin(value, input) {
209
+ const normalized = boundedString(value)?.toLowerCase();
210
+ if (normalized === "caller") return "caller";
211
+ if (normalized === "provider" || normalized === "provider_network") {
212
+ return "provider";
213
+ }
214
+ if (normalized === "upstream" && boundedString(input?.provider) && boundedString(input?.operation)) {
215
+ return "provider";
216
+ }
217
+ if (normalized === "deepline" || normalized === "deepline_billing" || normalized === "deepline_rate_limit" || normalized === "internal" || normalized === "server") {
218
+ return "deepline";
219
+ }
220
+ if (normalized === "provider_account") return "provider";
221
+ return "unknown";
222
+ }
223
+ function normalizeToolExecutionCategory(value) {
224
+ switch (boundedString(value)?.toLowerCase()) {
225
+ case "validation":
226
+ case "authorization":
227
+ case "rate_limit":
228
+ case "network":
229
+ case "upstream":
230
+ case "billing":
231
+ case "conflict":
232
+ case "internal":
233
+ return boundedString(value).toLowerCase();
234
+ case "authentication":
235
+ case "provider_auth":
236
+ case "provider_account":
237
+ return "authentication";
238
+ case "execution":
239
+ case "parse":
240
+ case "stub":
241
+ case "internal_native_search_performance":
242
+ return "internal";
243
+ default:
244
+ return "unknown";
245
+ }
246
+ }
247
+ function normalizeNetworkKind(value) {
248
+ switch (boundedString(value)?.toLowerCase()) {
249
+ case "timeout":
250
+ case "dns":
251
+ case "connect":
252
+ case "reset":
253
+ case "unavailable":
254
+ case "unknown":
255
+ return boundedString(value).toLowerCase();
256
+ default:
257
+ return null;
258
+ }
259
+ }
260
+ function normalizeNetworkScope(value) {
261
+ switch (boundedString(value)?.toLowerCase()) {
262
+ case "client_to_deepline":
263
+ case "runtime_to_deepline":
264
+ case "deepline_to_provider":
265
+ return boundedString(value).toLowerCase();
266
+ default:
267
+ return null;
268
+ }
269
+ }
270
+ function isRecord(value) {
271
+ return value !== null && typeof value === "object" && !Array.isArray(value);
272
+ }
273
+ function normalizeToolExecutionFailure(value) {
274
+ if (!isRecord(value) || value.schemaVersion !== TOOL_EXECUTION_ERROR_SCHEMA_VERSION) {
275
+ return null;
276
+ }
277
+ const toolId = boundedString(value.toolId);
278
+ if (!toolId) return null;
279
+ const provider = boundedString(value.provider);
280
+ const operation = boundedString(value.operation);
281
+ const origin = normalizeToolExecutionOrigin(value.origin, {
282
+ provider,
283
+ operation
284
+ });
285
+ const category = normalizeToolExecutionCategory(value.category);
286
+ const trustworthy = origin !== "unknown" && category !== "unknown" && typeof value.retryable === "boolean";
287
+ return {
288
+ schemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
289
+ toolId,
290
+ provider,
291
+ operation,
292
+ code: boundedString(value.code, MAX_CODE_LENGTH),
293
+ origin,
294
+ category,
295
+ retryable: trustworthy ? value.retryable === true : false,
296
+ statusCode: finiteNonNegativeInteger(value.statusCode),
297
+ requestId: boundedString(value.requestId),
298
+ retryAfterMs: finiteNonNegativeInteger(value.retryAfterMs),
299
+ networkKind: normalizeNetworkKind(value.networkKind),
300
+ networkScope: normalizeNetworkScope(value.networkScope)
301
+ };
302
+ }
303
+ function serializeToolExecutionFailure(error) {
304
+ if (!(error instanceof ToolExecutionError)) return null;
305
+ return normalizeToolExecutionFailure({
306
+ schemaVersion: TOOL_EXECUTION_ERROR_SCHEMA_VERSION,
307
+ toolId: error.toolId,
308
+ provider: error.provider,
309
+ operation: error.operation,
310
+ code: error.code ?? null,
311
+ origin: error.origin,
312
+ category: error.category,
313
+ retryable: error.retryable,
314
+ statusCode: error.statusCode ?? null,
315
+ requestId: error.requestId,
316
+ retryAfterMs: error.retryAfterMs,
317
+ networkKind: error.networkKind,
318
+ networkScope: error.networkScope
319
+ });
320
+ }
321
+ function deserializeToolExecutionFailure(message, value, acceptedSchemaVersion) {
322
+ if (acceptedSchemaVersion === LEGACY_TOOL_EXECUTION_ERROR_SCHEMA_VERSION) {
323
+ return null;
324
+ }
325
+ const failure = normalizeToolExecutionFailure(value);
326
+ if (!failure) return null;
327
+ if (isProviderTransientFailure(failure)) {
328
+ return new ProviderTransientError(message, failure);
329
+ }
330
+ return new ToolExecutionError(message, failure);
331
+ }
332
+
333
+ // src/errors.ts
98
334
  var AuthError = class extends DeeplineError {
99
335
  constructor(message = "Authentication failed. Check your DEEPLINE_API_KEY.") {
100
336
  super(message, 401, "AUTH_ERROR");
@@ -114,6 +350,38 @@ var RateLimitError = class extends DeeplineError {
114
350
  this.retryAfterMs = retryAfterMs;
115
351
  }
116
352
  };
353
+ var ToolRateLimitError = class extends RateLimitError {
354
+ toolId;
355
+ provider;
356
+ operation;
357
+ code;
358
+ origin;
359
+ category;
360
+ retryable;
361
+ requestId;
362
+ networkKind;
363
+ networkScope;
364
+ constructor(message, options) {
365
+ super(options.retryAfterMs ?? 5e3, message);
366
+ this.name = "ToolRateLimitError";
367
+ this.statusCode = options.statusCode ?? 429;
368
+ this.code = options.code ?? void 0;
369
+ this.toolId = options.toolId;
370
+ this.provider = options.provider;
371
+ this.operation = options.operation;
372
+ this.origin = options.origin;
373
+ this.category = options.category;
374
+ this.retryable = options.retryable;
375
+ this.requestId = options.requestId;
376
+ this.networkKind = options.networkKind;
377
+ this.networkScope = options.networkScope;
378
+ this.details = options.details;
379
+ brandAsToolExecutionError(this);
380
+ if (isProviderTransientFailure(this)) {
381
+ brandAsProviderTransientError(this);
382
+ }
383
+ }
384
+ };
117
385
  var ConfigError = class extends DeeplineError {
118
386
  constructor(message) {
119
387
  super(message, void 0, "CONFIG_ERROR");
@@ -399,6 +667,9 @@ var import_node_fs2 = require("fs");
399
667
  var import_node_os3 = require("os");
400
668
  var import_node_path2 = require("path");
401
669
 
670
+ // ../shared_libs/plays/artifact-contract-version.ts
671
+ var CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION = 2;
672
+
402
673
  // src/release.ts
403
674
  var SDK_RELEASE = {
404
675
  // 0.1.94 is claimed by PR #1527 — this watch-render fix ships as 0.1.95.
@@ -438,7 +709,7 @@ var SDK_RELEASE = {
438
709
  // 0.1.253 makes play-page browser opening opt-in and retires --no-open.
439
710
  // 0.1.254 removes the internal operations tree from the published SDK CLI.
440
711
  // Operators use the checkout-local deepline-admin binary instead.
441
- version: "0.1.301",
712
+ version: "0.1.302",
442
713
  contracts: {
443
714
  api: {
444
715
  name: "sdk-http-api",
@@ -454,8 +725,8 @@ var SDK_RELEASE = {
454
725
  },
455
726
  playArtifact: {
456
727
  name: "play-artifact-runtime",
457
- currentVersion: 2,
458
- supportedVersions: [1, 2]
728
+ currentVersion: CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION,
729
+ supportedVersions: [1, CURRENT_PLAY_ARTIFACT_CONTRACT_VERSION]
459
730
  },
460
731
  release: {
461
732
  name: "production-sdk-release",
@@ -687,6 +958,9 @@ function providerLabelFromToolId(toolId) {
687
958
  const provider = normalized.split(/[_:./-]+/)[0];
688
959
  return provider || normalized || "provider";
689
960
  }
961
+ function isRecord2(value) {
962
+ return value !== null && typeof value === "object" && !Array.isArray(value);
963
+ }
690
964
  var HttpClient = class {
691
965
  constructor(config) {
692
966
  this.config = config;
@@ -822,6 +1096,29 @@ var HttpClient = class {
822
1096
  signal: controller.signal
823
1097
  });
824
1098
  clearTimeout(timeoutId);
1099
+ const body = await response.text();
1100
+ const parsed = parseResponseBody(body);
1101
+ const structuredToolError = options?.toolId && !response.ok ? deserializeToolExecutionFailure(
1102
+ apiErrorMessage(parsed, response.status),
1103
+ isRecord2(parsed) ? parsed.tool_error : null,
1104
+ TOOL_EXECUTION_ERROR_SCHEMA_VERSION
1105
+ ) : null;
1106
+ if (structuredToolError) {
1107
+ if (response.status === 429) {
1108
+ const retryAfter = parseRetryAfter(response);
1109
+ const failure = serializeToolExecutionFailure(structuredToolError);
1110
+ lastError = failure === null ? structuredToolError : new ToolRateLimitError(structuredToolError.message, {
1111
+ ...failure,
1112
+ retryAfterMs: failure.retryAfterMs ?? Math.max(0, retryAfter)
1113
+ });
1114
+ if (attempt < maxRetries) {
1115
+ retryAfterDelayMs = retryAfter;
1116
+ break;
1117
+ }
1118
+ throw lastError;
1119
+ }
1120
+ throw structuredToolError;
1121
+ }
825
1122
  if (response.status === 429) {
826
1123
  const retryAfter = parseRetryAfter(response);
827
1124
  lastError = new RateLimitError(retryAfter);
@@ -831,8 +1128,6 @@ var HttpClient = class {
831
1128
  }
832
1129
  throw lastError;
833
1130
  }
834
- const body = await response.text();
835
- const parsed = parseResponseBody(body);
836
1131
  if (response.status === 401 && !isProviderOriginatedHttpError(parsed) || response.status === 403 && !options?.forbiddenAsApiError) {
837
1132
  throw new AuthError();
838
1133
  }
@@ -897,6 +1192,29 @@ var HttpClient = class {
897
1192
  lastError,
898
1193
  describeRequestTarget(path)
899
1194
  );
1195
+ if (options?.toolId) {
1196
+ const code = mappedNetworkError.code;
1197
+ throw new ToolExecutionError(
1198
+ withCoworkNetworkHint(mappedNetworkError.message),
1199
+ {
1200
+ toolId: options.toolId,
1201
+ provider: providerLabelFromToolId(options.toolId),
1202
+ operation: options.toolId,
1203
+ code,
1204
+ origin: "deepline",
1205
+ category: "network",
1206
+ // A direct client timeout has ambiguous delivery. Fail closed unless
1207
+ // the server returns the authoritative action delivery contract.
1208
+ retryable: false,
1209
+ statusCode: null,
1210
+ requestId: null,
1211
+ retryAfterMs: null,
1212
+ networkKind: code === "NETWORK_TIMEOUT" ? "timeout" : code === "NETWORK_ABORTED" ? "unknown" : "unavailable",
1213
+ networkScope: "client_to_deepline",
1214
+ details: mappedNetworkError.details
1215
+ }
1216
+ );
1217
+ }
900
1218
  throw new DeeplineError(
901
1219
  withCoworkNetworkHint(mappedNetworkError.message),
902
1220
  void 0,
@@ -1338,11 +1656,11 @@ var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
1338
1656
  var ledgerIngressRedactor = createSecretRedactionContext();
1339
1657
 
1340
1658
  // ../shared_libs/play-runtime/activity-observation.ts
1341
- function isRecord(value) {
1659
+ function isRecord3(value) {
1342
1660
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1343
1661
  }
1344
1662
  function isPlayActivityObservation(value) {
1345
- if (!isRecord(value) || value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord(value.target) || !isRecord(value.state)) {
1663
+ if (!isRecord3(value) || value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord3(value.target) || !isRecord3(value.state)) {
1346
1664
  return false;
1347
1665
  }
1348
1666
  const targetKinds = /* @__PURE__ */ new Set([
@@ -1607,7 +1925,7 @@ function projectPlayRunActivity(input) {
1607
1925
 
1608
1926
  // ../shared_libs/play-runtime/run-ledger.ts
1609
1927
  var LOG_TAIL_LIMIT = 100;
1610
- function isRecord2(value) {
1928
+ function isRecord4(value) {
1611
1929
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1612
1930
  }
1613
1931
  function finiteNumber(value) {
@@ -1703,21 +2021,21 @@ function createEmptyPlayRunLedgerSnapshot(input) {
1703
2021
  };
1704
2022
  }
1705
2023
  function normalizePlayRunLedgerSnapshot(value, fallback) {
1706
- if (!isRecord2(value)) {
2024
+ if (!isRecord4(value)) {
1707
2025
  return createEmptyPlayRunLedgerSnapshot(fallback);
1708
2026
  }
1709
2027
  const orderedStepIds = Array.isArray(value.orderedStepIds) ? value.orderedStepIds.filter(
1710
2028
  (entry) => typeof entry === "string" && Boolean(entry.trim())
1711
2029
  ) : [];
1712
- const rawSteps = isRecord2(value.stepsById) ? value.stepsById : {};
2030
+ const rawSteps = isRecord4(value.stepsById) ? value.stepsById : {};
1713
2031
  const stepsById = {};
1714
2032
  for (const [stepId, rawStep] of Object.entries(rawSteps)) {
1715
- if (!stepId.trim() || !isRecord2(rawStep)) continue;
2033
+ if (!stepId.trim() || !isRecord4(rawStep)) continue;
1716
2034
  const rawStatus = normalizeStepStatus(rawStep.status);
1717
2035
  if (!rawStatus) continue;
1718
2036
  const completedAt = finiteNumber(rawStep.completedAt);
1719
2037
  const status = rawStatus === "running" && completedAt !== null ? "completed" : rawStatus;
1720
- const rawProgress = isRecord2(rawStep.progress) ? rawStep.progress : null;
2038
+ const rawProgress = isRecord4(rawStep.progress) ? rawStep.progress : null;
1721
2039
  stepsById[stepId] = {
1722
2040
  stepId,
1723
2041
  label: optionalString(rawStep.label),
@@ -1733,10 +2051,10 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1733
2051
  progress: rawProgress ? normalizeStepProgress(rawProgress) : null
1734
2052
  };
1735
2053
  }
1736
- const rawDatasets = isRecord2(value.datasetsById) ? value.datasetsById : {};
2054
+ const rawDatasets = isRecord4(value.datasetsById) ? value.datasetsById : {};
1737
2055
  const datasetsById = {};
1738
2056
  for (const [datasetId, rawDataset] of Object.entries(rawDatasets)) {
1739
- if (!datasetId.trim() || !isRecord2(rawDataset)) continue;
2057
+ if (!datasetId.trim() || !isRecord4(rawDataset)) continue;
1740
2058
  const phase = rawDataset.phase === "available" || rawDataset.phase === "failed" ? rawDataset.phase : "registered";
1741
2059
  datasetsById[datasetId] = {
1742
2060
  datasetId,
@@ -1750,7 +2068,7 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
1750
2068
  updatedAt: finiteNumber(rawDataset.updatedAt) ?? 0
1751
2069
  };
1752
2070
  }
1753
- const rawActivities = isRecord2(value.activitiesById) ? value.activitiesById : {};
2071
+ const rawActivities = isRecord4(value.activitiesById) ? value.activitiesById : {};
1754
2072
  const activitiesById = {};
1755
2073
  for (const [activityId, rawActivity] of Object.entries(rawActivities)) {
1756
2074
  if (activityId.trim() && isPlayActivityObservation(rawActivity) && rawActivity.activityId === activityId) {
@@ -1899,18 +2217,18 @@ function normalizePlayRunLiveStatus(value) {
1899
2217
  function isTerminalPlayRunLiveStatus(status) {
1900
2218
  return isTerminalPlayRunLifecycleStatus(status);
1901
2219
  }
1902
- function isRecord3(value) {
2220
+ function isRecord5(value) {
1903
2221
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
1904
2222
  }
1905
2223
  function finiteNumber2(value) {
1906
2224
  return typeof value === "number" && Number.isFinite(value) ? value : null;
1907
2225
  }
1908
2226
  function extractTerminalRunLogTail(result) {
1909
- if (!isRecord3(result) || !isRecord3(result._metadata)) {
2227
+ if (!isRecord5(result) || !isRecord5(result._metadata)) {
1910
2228
  return null;
1911
2229
  }
1912
2230
  const runLogTail = result._metadata.runLogTail;
1913
- if (!isRecord3(runLogTail) || !Array.isArray(runLogTail.tail)) {
2231
+ if (!isRecord5(runLogTail) || !Array.isArray(runLogTail.tail)) {
1914
2232
  return null;
1915
2233
  }
1916
2234
  const logTail = runLogTail.tail.filter(
@@ -2804,7 +3122,7 @@ function resolveToolExecuteTimeoutMs(toolId, input) {
2804
3122
  }
2805
3123
  var RUNS_FAILED_LOG_LIMIT = 20;
2806
3124
  var RUN_LOGS_PAGE_LIMIT = 1e3;
2807
- function isRecord4(value) {
3125
+ function isRecord6(value) {
2808
3126
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
2809
3127
  }
2810
3128
  function isPrebuiltPlayDescription(play) {
@@ -2967,7 +3285,7 @@ function updatePlayLiveStatusState(state, event) {
2967
3285
  }
2968
3286
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
2969
3287
  const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
2970
- const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
3288
+ const progressPayload = isRecord6(payload.progress) ? payload.progress : {};
2971
3289
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
2972
3290
  const payloadLogs = readStringArray(payload.logs);
2973
3291
  const progressLogs = readStringArray(progressPayload.logs);
@@ -3101,9 +3419,9 @@ var DeeplineClient = class {
3101
3419
  return fields.length > 0 ? { fields } : schema;
3102
3420
  }
3103
3421
  schemaMetadata(schema, key) {
3104
- if (!isRecord4(schema)) return null;
3422
+ if (!isRecord6(schema)) return null;
3105
3423
  const value = schema[key];
3106
- return isRecord4(value) ? value : null;
3424
+ return isRecord6(value) ? value : null;
3107
3425
  }
3108
3426
  playRunCommand(play, options) {
3109
3427
  const target = play.reference || play.name;
@@ -3152,7 +3470,7 @@ var DeeplineClient = class {
3152
3470
  aliases,
3153
3471
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
3154
3472
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
3155
- staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3473
+ staticPipeline: isRecord6(play.staticPipeline) ? play.staticPipeline : isRecord6(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord6(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
3156
3474
  ...csvInput ? { csvInput } : {},
3157
3475
  ...rowOutputSchema ? { rowOutputSchema } : {},
3158
3476
  runCommand,
@@ -3323,6 +3641,9 @@ var DeeplineClient = class {
3323
3641
  async executeTool(toolId, input, options) {
3324
3642
  const headers = {
3325
3643
  [EXECUTE_RESPONSE_CONTRACT_HEADER]: V2_EXECUTE_RESPONSE_CONTRACT,
3644
+ [TOOL_EXECUTION_ERROR_SCHEMA_HEADER]: String(
3645
+ TOOL_EXECUTION_ERROR_SCHEMA_VERSION
3646
+ ),
3326
3647
  ...options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : {},
3327
3648
  [EXECUTE_RESPONSE_INTENT_HEADER]: options?.responseIntent ?? "raw"
3328
3649
  };
@@ -3337,7 +3658,8 @@ var DeeplineClient = class {
3337
3658
  forbiddenAsApiError: true,
3338
3659
  timeout: options?.timeout ?? resolveToolExecuteTimeoutMs(toolId, input),
3339
3660
  maxRetries: options?.maxRetries ?? 0,
3340
- exactUrlOnly: true
3661
+ exactUrlOnly: true,
3662
+ toolId
3341
3663
  }
3342
3664
  );
3343
3665
  }
@@ -5844,7 +6166,7 @@ var TARGET_FALLBACK_KEYS = {
5844
6166
  status: [/^email_status$/i, /^status$/i],
5845
6167
  email_status: [/^email_status$/i, /^status$/i]
5846
6168
  };
5847
- function isRecord5(value) {
6169
+ function isRecord7(value) {
5848
6170
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
5849
6171
  }
5850
6172
  function toV2RawToolOutputPath(path) {
@@ -5904,7 +6226,7 @@ function valuesAtSegments(current, segments, path = []) {
5904
6226
  if (!Array.isArray(current)) return [];
5905
6227
  return valuesAtSegments(current[segment], rest, [...path, segment]);
5906
6228
  }
5907
- if (!isRecord5(current)) return [];
6229
+ if (!isRecord7(current)) return [];
5908
6230
  const directMatches = valuesAtSegments(current[segment], rest, [
5909
6231
  ...path,
5910
6232
  segment
@@ -5934,7 +6256,7 @@ function getValuesAtPath(root, path) {
5934
6256
  return valuesAtSegments(root, parsePath(path)).map((entry) => entry.value);
5935
6257
  }
5936
6258
  function toResultEnvelope(value) {
5937
- if (isRecord5(value) && "data" in value) {
6259
+ if (isRecord7(value) && "data" in value) {
5938
6260
  const envelope = { data: value.data };
5939
6261
  if ("meta" in value) envelope.meta = value.meta;
5940
6262
  return envelope;
@@ -5987,7 +6309,7 @@ function getAtPath(root, path) {
5987
6309
  current = current[segment];
5988
6310
  continue;
5989
6311
  }
5990
- if (!isRecord5(current)) return void 0;
6312
+ if (!isRecord7(current)) return void 0;
5991
6313
  current = current[segment];
5992
6314
  }
5993
6315
  return current;
@@ -6004,7 +6326,7 @@ function normalizeString(value) {
6004
6326
  }
6005
6327
  function normalizeRows(value) {
6006
6328
  if (!Array.isArray(value)) return null;
6007
- return value.map((entry) => isRecord5(entry) ? entry : { value: entry });
6329
+ return value.map((entry) => isRecord7(entry) ? entry : { value: entry });
6008
6330
  }
6009
6331
  function findFirstTargetByPath(result, paths) {
6010
6332
  for (const path of paths ?? []) {
@@ -6063,7 +6385,7 @@ function findFirstTargetByKey(result, target, depth = 0, path = []) {
6063
6385
  }
6064
6386
  return null;
6065
6387
  }
6066
- if (!isRecord5(result)) return null;
6388
+ if (!isRecord7(result)) return null;
6067
6389
  const patterns = TARGET_FALLBACK_KEYS[target] ?? [
6068
6390
  new RegExp(`^${target}$`, "i")
6069
6391
  ];
@@ -6123,7 +6445,7 @@ function normalizeJobChangeStatus(value) {
6123
6445
  function firstExperienceDate(value) {
6124
6446
  if (!Array.isArray(value)) return null;
6125
6447
  for (const entry of value) {
6126
- if (!isRecord5(entry)) continue;
6448
+ if (!isRecord7(entry)) continue;
6127
6449
  const date = normalizeString(
6128
6450
  entry.start_date ?? entry.started_at ?? entry.startDate
6129
6451
  );
@@ -6132,10 +6454,10 @@ function firstExperienceDate(value) {
6132
6454
  return null;
6133
6455
  }
6134
6456
  function normalizeJobChange(value) {
6135
- const record = isRecord5(value) ? value : {};
6136
- const nested = isRecord5(record.job_change) ? record.job_change : record;
6137
- const output = isRecord5(nested.output) ? nested.output : nested;
6138
- const person = isRecord5(output.person) ? output.person : {};
6457
+ const record = isRecord7(value) ? value : {};
6458
+ const nested = isRecord7(record.job_change) ? record.job_change : record;
6459
+ const output = isRecord7(nested.output) ? nested.output : nested;
6460
+ const person = isRecord7(output.person) ? output.person : {};
6139
6461
  const status = normalizeJobChangeStatus(
6140
6462
  output.status ?? output.job_change_status ?? output.job_changed ?? output.changed
6141
6463
  );
@@ -6500,7 +6822,7 @@ function attachToolResultListDataset(result, input) {
6500
6822
  root = replaceAtPath(root, candidate, serialized.preview);
6501
6823
  break;
6502
6824
  }
6503
- if (isRecord5(root) && isRecord5(root.toolResponse) && Object.prototype.hasOwnProperty.call(root.toolResponse, "raw")) {
6825
+ if (isRecord7(root) && isRecord7(root.toolResponse) && Object.prototype.hasOwnProperty.call(root.toolResponse, "raw")) {
6504
6826
  result.toolResponse.raw = root.toolResponse.raw;
6505
6827
  result.toolOutput.raw = root.toolResponse.raw;
6506
6828
  }
@@ -6518,7 +6840,7 @@ function replaceAtPath(root, path, replacement) {
6518
6840
  copy[segment] = replace(copy[segment], index + 1);
6519
6841
  return copy;
6520
6842
  }
6521
- if (!isRecord5(current)) return current;
6843
+ if (!isRecord7(current)) return current;
6522
6844
  return {
6523
6845
  ...current,
6524
6846
  [segment]: replace(current[segment], index + 1)
@@ -6839,11 +7161,11 @@ var Deepline = class {
6839
7161
  return new DeeplineContext(options);
6840
7162
  }
6841
7163
  };
6842
- function isRecord6(value) {
7164
+ function isRecord8(value) {
6843
7165
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
6844
7166
  }
6845
7167
  function stringArrayRecord(value) {
6846
- if (!isRecord6(value)) return {};
7168
+ if (!isRecord8(value)) return {};
6847
7169
  return Object.fromEntries(
6848
7170
  Object.entries(value).map(([key, paths]) => [
6849
7171
  key,
@@ -6855,7 +7177,7 @@ function stringArray(value) {
6855
7177
  return Array.isArray(value) ? value.map(String) : [];
6856
7178
  }
6857
7179
  function emailStatusExtractorConfig(value) {
6858
- if (!isRecord6(value)) return void 0;
7180
+ if (!isRecord8(value)) return void 0;
6859
7181
  const readPaths = (key) => {
6860
7182
  const paths = stringArray(value[key]).map((path) => path.trim()).filter(Boolean);
6861
7183
  return paths.length > 0 ? paths : void 0;
@@ -6882,7 +7204,7 @@ function emailStatusExtractorConfig(value) {
6882
7204
  const paths = readPaths(key);
6883
7205
  if (paths) config[key] = paths;
6884
7206
  }
6885
- if (isRecord6(value.statusMap)) {
7207
+ if (isRecord8(value.statusMap)) {
6886
7208
  config.statusMap = value.statusMap;
6887
7209
  }
6888
7210
  if (Array.isArray(value.rules)) {
@@ -6891,10 +7213,10 @@ function emailStatusExtractorConfig(value) {
6891
7213
  return config;
6892
7214
  }
6893
7215
  function extractorDescriptorRecord(value) {
6894
- if (!isRecord6(value)) return {};
7216
+ if (!isRecord8(value)) return {};
6895
7217
  return Object.fromEntries(
6896
7218
  Object.entries(value).flatMap(([key, descriptor]) => {
6897
- if (!isRecord6(descriptor)) return [];
7219
+ if (!isRecord8(descriptor)) return [];
6898
7220
  const paths = stringArray(descriptor.paths).map((path) => path.trim()).filter(Boolean);
6899
7221
  if (paths.length === 0) return [];
6900
7222
  const transforms = stringArray(descriptor.transforms).map((transform) => transform.trim()).filter(Boolean);
@@ -6916,16 +7238,16 @@ function extractorDescriptorRecord(value) {
6916
7238
  }
6917
7239
  function rowsFromUnknown(value) {
6918
7240
  if (!Array.isArray(value)) return [];
6919
- return value.map((row) => isRecord6(row) ? row : { value: row });
7241
+ return value.map((row) => isRecord8(row) ? row : { value: row });
6920
7242
  }
6921
- function finiteNonNegativeInteger(value) {
7243
+ function finiteNonNegativeInteger2(value) {
6922
7244
  if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
6923
7245
  return null;
6924
7246
  }
6925
7247
  return Math.floor(value);
6926
7248
  }
6927
7249
  function finitePositiveInteger(value) {
6928
- const integer = finiteNonNegativeInteger(value);
7250
+ const integer = finiteNonNegativeInteger2(value);
6929
7251
  return integer !== null && integer > 0 ? integer : null;
6930
7252
  }
6931
7253
  function stableHash(value) {
@@ -6938,9 +7260,9 @@ function stableHash(value) {
6938
7260
  }
6939
7261
  function attachSdkQueryResultDatasetResult(toolId, result, options) {
6940
7262
  if (!options || !isQueryResultDatasetTool(toolId)) return result;
6941
- const raw = isRecord6(result.toolResponse.raw) ? result.toolResponse.raw : null;
6942
- const dataset = isRecord6(raw?.dataset) ? raw.dataset : null;
6943
- const totalRows = finiteNonNegativeInteger(dataset?.total_rows);
7263
+ const raw = isRecord8(result.toolResponse.raw) ? result.toolResponse.raw : null;
7264
+ const dataset = isRecord8(raw?.dataset) ? raw.dataset : null;
7265
+ const totalRows = finiteNonNegativeInteger2(dataset?.total_rows);
6944
7266
  const sql = typeof options.input.sql === "string" ? options.input.sql : typeof options.input.query === "string" ? options.input.query : typeof raw?.sql === "string" ? raw.sql : null;
6945
7267
  if (!dataset || totalRows === null || !sql) {
6946
7268
  return result;
@@ -6969,7 +7291,7 @@ function attachSdkQueryResultDatasetResult(toolId, result, options) {
6969
7291
  } : {}
6970
7292
  }
6971
7293
  });
6972
- const pageRaw = isRecord6(response.toolResponse?.raw) ? response.toolResponse.raw : null;
7294
+ const pageRaw = isRecord8(response.toolResponse?.raw) ? response.toolResponse.raw : null;
6973
7295
  return rowsFromUnknown(pageRaw?.rows);
6974
7296
  };
6975
7297
  const collectRows = async (limit) => {
@@ -7022,8 +7344,8 @@ function attachSdkQueryResultDatasetResult(toolId, result, options) {
7022
7344
  function toolExecutionEnvelopeToResult(fallbackToolId, response, options) {
7023
7345
  const raw = response.toolResponse?.raw ?? null;
7024
7346
  const meta = response.toolResponse?.meta;
7025
- const metadata = isRecord6(response._metadata) ? response._metadata.tool : null;
7026
- const toolMetadata = isRecord6(metadata) ? metadata : {};
7347
+ const metadata = isRecord8(response._metadata) ? response._metadata.tool : null;
7348
+ const toolMetadata = isRecord8(metadata) ? metadata : {};
7027
7349
  return attachSdkQueryResultDatasetResult(
7028
7350
  fallbackToolId,
7029
7351
  createToolExecuteResult({
@@ -7031,7 +7353,7 @@ function toolExecutionEnvelopeToResult(fallbackToolId, response, options) {
7031
7353
  jobId: typeof response.job_id === "string" ? response.job_id : void 0,
7032
7354
  result: {
7033
7355
  data: raw,
7034
- ...isRecord6(meta) ? { meta } : {}
7356
+ ...isRecord8(meta) ? { meta } : {}
7035
7357
  },
7036
7358
  metadata: {
7037
7359
  toolId: typeof toolMetadata.toolId === "string" ? toolMetadata.toolId : fallbackToolId,
@@ -7047,7 +7369,7 @@ function toolExecutionEnvelopeToResult(fallbackToolId, response, options) {
7047
7369
  cached: false,
7048
7370
  source: "live"
7049
7371
  },
7050
- meta: isRecord6(response.meta) ? response.meta : void 0
7372
+ meta: isRecord8(response.meta) ? response.meta : void 0
7051
7373
  }),
7052
7374
  options
7053
7375
  );
@@ -7067,14 +7389,16 @@ function definePlay(nameOrConfig, maybeFn, maybeBindings) {
7067
7389
  bindings: maybeBindings,
7068
7390
  description: maybeBindings?.description,
7069
7391
  inputSchema: void 0,
7070
- billing: maybeBindings?.billing
7392
+ billing: maybeBindings?.billing,
7393
+ compatibility: maybeBindings?.compatibility
7071
7394
  } : {
7072
7395
  name: nameOrConfig.id,
7073
7396
  fn: nameOrConfig.run,
7074
7397
  bindings: nameOrConfig.bindings,
7075
7398
  description: nameOrConfig.description,
7076
7399
  inputSchema: nameOrConfig.input.schema,
7077
- billing: nameOrConfig.billing
7400
+ billing: nameOrConfig.billing,
7401
+ compatibility: nameOrConfig.compatibility ?? nameOrConfig.bindings?.compatibility
7078
7402
  };
7079
7403
  const name = config.name;
7080
7404
  const fn = config.fn;
@@ -7082,6 +7406,7 @@ function definePlay(nameOrConfig, maybeFn, maybeBindings) {
7082
7406
  const description = config.description?.trim();
7083
7407
  const billing = config.billing;
7084
7408
  const inputSchema = config.inputSchema;
7409
+ const compatibility = config.compatibility;
7085
7410
  if (typeof fn !== "function") {
7086
7411
  throw new Error("definePlay(...) requires an async run function.");
7087
7412
  }
@@ -7106,7 +7431,8 @@ function definePlay(nameOrConfig, maybeFn, maybeBindings) {
7106
7431
  ...description ? { description } : {},
7107
7432
  ...bindings ? { bindings } : {},
7108
7433
  ...inputSchema ? { inputSchema } : {},
7109
- ...billing ? { billing } : {}
7434
+ ...billing ? { billing } : {},
7435
+ ...compatibility ? { compatibility } : {}
7110
7436
  };
7111
7437
  const play = fn;
7112
7438
  Object.defineProperty(play, PLAY_METADATA_SYMBOL, {
@@ -7127,6 +7453,12 @@ function definePlay(nameOrConfig, maybeFn, maybeBindings) {
7127
7453
  configurable: false,
7128
7454
  writable: false
7129
7455
  });
7456
+ Object.defineProperty(play, "compatibility", {
7457
+ value: compatibility,
7458
+ enumerable: true,
7459
+ configurable: false,
7460
+ writable: false
7461
+ });
7130
7462
  const handle = createNamedPlayHandle(
7131
7463
  () => new DeeplineClient(),
7132
7464
  name
@@ -7373,10 +7705,13 @@ function extractSummaryFields(payload) {
7373
7705
  PLAY_BOOTSTRAP_STAGE_KINDS,
7374
7706
  PLAY_BOOTSTRAP_TEMPLATES,
7375
7707
  PROD_URL,
7708
+ ProviderTransientError,
7376
7709
  RateLimitError,
7377
7710
  RunObserveTransportUnavailableError,
7378
7711
  SDK_API_CONTRACT,
7379
7712
  SDK_VERSION,
7713
+ ToolExecutionError,
7714
+ ToolRateLimitError,
7380
7715
  defineInput,
7381
7716
  defineMonitor,
7382
7717
  definePlay,