deepline 0.3.237 → 0.3.238

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.
@@ -3449,7 +3449,7 @@ var SDK_RELEASE = {
3449
3449
  // getters keep their established compatibility behavior.
3450
3450
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3451
3451
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3452
- version: "0.3.237",
3452
+ version: "0.3.238",
3453
3453
  updateSummary: "Play grep now returns concise results with the matched fields and terms. Automatic CLI updates are enabled by default; use `deepline settings autoupdate off` to opt out, `deepline settings autoupdate on` to re-enable updates, or `deepline settings autoupdate pin <version>` to hold an exact release.",
3454
3454
  packageCapabilities: {
3455
3455
  updatePreferences: 1
@@ -4098,19 +4098,19 @@ function withErrorCause(error, cause) {
4098
4098
  }
4099
4099
  return error;
4100
4100
  }
4101
- function mapNetworkError(baseUrl, error, targetLabel2) {
4101
+ function mapNetworkError(baseUrl, error, targetLabel) {
4102
4102
  const tagged = error;
4103
4103
  const timeoutMs = tagged?.[REQUEST_TIMEOUT_MARKER];
4104
4104
  if (typeof timeoutMs === "number") {
4105
4105
  return {
4106
- message: `Request to ${targetLabel2} timed out after ${timeoutMs}ms while waiting for a response.`,
4106
+ message: `Request to ${targetLabel} timed out after ${timeoutMs}ms while waiting for a response.`,
4107
4107
  code: "NETWORK_TIMEOUT",
4108
- details: { timeoutMs, target: targetLabel2 }
4108
+ details: { timeoutMs, target: targetLabel }
4109
4109
  };
4110
4110
  }
4111
4111
  if (tagged?.[REQUEST_ABORT_MARKER]) {
4112
4112
  return {
4113
- message: `Request to ${targetLabel2} was aborted before it completed.`,
4113
+ message: `Request to ${targetLabel} was aborted before it completed.`,
4114
4114
  code: "NETWORK_ABORTED"
4115
4115
  };
4116
4116
  }
@@ -4873,30 +4873,6 @@ var DEFAULT_PRODUCT_NOTIFICATION_DELIVERY_TIMING = {
4873
4873
  windowMs: 36e5
4874
4874
  };
4875
4875
 
4876
- // src/stream-reconnect.ts
4877
- var STREAM_RECONNECT_BASE_DELAY_MS = 500;
4878
- var STREAM_RECONNECT_MAX_DELAY_MS = 15e3;
4879
- var STREAM_HEALTHY_CONNECTION_MS = 3e4;
4880
- function streamReconnectDelayMs(attempt) {
4881
- const cappedExponentialMs = Math.min(
4882
- STREAM_RECONNECT_MAX_DELAY_MS,
4883
- STREAM_RECONNECT_BASE_DELAY_MS * 2 ** Math.max(0, attempt)
4884
- );
4885
- return Math.max(1, Math.floor(Math.random() * (cappedExponentialMs + 1)));
4886
- }
4887
- function isTransientPlayStreamError(error) {
4888
- if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
4889
- return true;
4890
- }
4891
- if (error instanceof DeeplineError && typeof error.statusCode === "number") {
4892
- return error.statusCode >= 500 && error.statusCode < 600;
4893
- }
4894
- const text = error instanceof Error ? error.message : String(error);
4895
- return /auth validation backend timed out|coordinator \/submit(?:\?[^ ]*)? 5\d\d|Worker threw exception|Internal Server Error|Service Unavailable|fetch failed|eaddrnotavail|econnreset|etimedout|eai_again|socket hang up/i.test(
4896
- text
4897
- );
4898
- }
4899
-
4900
4876
  // ../play-runtime/live-events.ts
4901
4877
  function resolveTimingWindow(input2) {
4902
4878
  const startedAt = typeof input2.startedAt === "number" && Number.isFinite(input2.startedAt) ? input2.startedAt : null;
@@ -4912,19 +4888,6 @@ function resolveTimingWindow(input2) {
4912
4888
  // ../play-runtime/run-failure.ts
4913
4889
  var PUBLIC_FAILURE_TEXT_BYTE_LIMIT = 64 * 1024;
4914
4890
 
4915
- // ../play-runtime/run-terminal-source.ts
4916
- var PLAY_RUN_LEDGER_EVENT_SOURCES = [
4917
- "worker",
4918
- "convex",
4919
- "coordinator",
4920
- "system"
4921
- ];
4922
- function normalizePlayRunLedgerTerminalSource(value) {
4923
- return PLAY_RUN_LEDGER_EVENT_SOURCES.includes(
4924
- value
4925
- ) ? value : null;
4926
- }
4927
-
4928
4891
  // ../play-runtime/run-log-buffer.ts
4929
4892
  var RUNNER_LOG_MAX_BYTES = 5 * 1024 * 1024;
4930
4893
  var TERMINAL_RESERVE_BYTES = 64 * 1024;
@@ -5095,12 +5058,12 @@ function createSecretRedactionContext(initialValues = []) {
5095
5058
  }
5096
5059
  return output2;
5097
5060
  }
5098
- function redactString2(value) {
5061
+ function redactString(value) {
5099
5062
  const output2 = redactRegisteredSecrets(value);
5100
5063
  return redactSecretLikeString(output2);
5101
5064
  }
5102
5065
  function redact(value) {
5103
- if (typeof value === "string") return redactString2(value);
5066
+ if (typeof value === "string") return redactString(value);
5104
5067
  if (Array.isArray(value)) {
5105
5068
  let changed = false;
5106
5069
  const next = new Array(value.length);
@@ -5133,7 +5096,7 @@ function createSecretRedactionContext(initialValues = []) {
5133
5096
  return value;
5134
5097
  }
5135
5098
  function redactKnownSecrets(value) {
5136
- if (typeof value === "string") return redactString2(value);
5099
+ if (typeof value === "string") return redactString(value);
5137
5100
  if (Array.isArray(value)) {
5138
5101
  return value.map((entry) => redactKnownSecrets(entry));
5139
5102
  }
@@ -5152,7 +5115,7 @@ function createSecretRedactionContext(initialValues = []) {
5152
5115
  containsRegisteredSecret,
5153
5116
  matchesRegisteredSecret,
5154
5117
  redactRegisteredSecrets,
5155
- redactString: redactString2,
5118
+ redactString,
5156
5119
  redactKnownSecrets,
5157
5120
  redact
5158
5121
  };
@@ -5176,981 +5139,8 @@ var JSON_SIZE_LIMIT_REACHED = Symbol("JSON_SIZE_LIMIT_REACHED");
5176
5139
  var ledgerIngressRedactor = createSecretRedactionContext();
5177
5140
 
5178
5141
  // ../play-runtime/docflow-node-io.ts
5179
- var DOCFLOW_NODE_IO_LIMITS = {
5180
- maxPaths: 16,
5181
- maxDepth: 3,
5182
- maxObjectFields: 12,
5183
- maxArrayItems: 3,
5184
- maxStringBytes: 256,
5185
- maxPhaseBytes: 2e3,
5186
- maxErrorBytes: 512
5187
- };
5188
5142
  var utf8Encoder = new TextEncoder();
5189
5143
  var PLAY_DATASET_BRAND = Symbol.for("deepline.play.dataset");
5190
- var MAX_CONVEX_PREVIEW_KEY_LENGTH = 1024;
5191
- function ledgerSafeDocflowPreviewKey(key) {
5192
- const source = key.startsWith("$") ? key.replace(/^\$+/, "") || "output" : key || "output";
5193
- let encoded = "";
5194
- for (const character of source) {
5195
- const code = character.charCodeAt(0);
5196
- if (code >= 32 && code < 127) {
5197
- encoded += character;
5198
- continue;
5199
- }
5200
- for (const byte of utf8Encoder.encode(character)) {
5201
- encoded += `%${byte.toString(16).toUpperCase().padStart(2, "0")}`;
5202
- }
5203
- }
5204
- if (encoded.length <= MAX_CONVEX_PREVIEW_KEY_LENGTH) return encoded;
5205
- let hashA = 2166136261;
5206
- let hashB = 2654435769;
5207
- for (let index = 0; index < encoded.length; index += 1) {
5208
- const code = encoded.charCodeAt(index);
5209
- hashA = Math.imul(hashA ^ code, 16777619);
5210
- hashB = Math.imul(hashB ^ code, 16777619);
5211
- }
5212
- const suffix = `~${(hashA >>> 0).toString(16).padStart(8, "0")}${(hashB >>> 0).toString(16).padStart(8, "0")}`;
5213
- return `${encoded.slice(0, MAX_CONVEX_PREVIEW_KEY_LENGTH - suffix.length)}${suffix}`;
5214
- }
5215
- function utf8Bytes(value) {
5216
- return utf8Encoder.encode(value).byteLength;
5217
- }
5218
- function truncateUtf8(value, maxBytes) {
5219
- if (utf8Bytes(value) <= maxBytes) return value;
5220
- let output2 = "";
5221
- for (const character of value) {
5222
- if (utf8Bytes(`${output2}${character}\u2026`) > maxBytes) break;
5223
- output2 += character;
5224
- }
5225
- return `${output2}\u2026`;
5226
- }
5227
- function redactString(redactor, value, key) {
5228
- if (!key) return redactor.redactString(value);
5229
- const wrapped = redactor.redact({ [key]: value });
5230
- return typeof wrapped[key] === "string" ? wrapped[key] : redactor.redactString(value);
5231
- }
5232
- function safeString(value, redactor, key) {
5233
- if (typeof value !== "string") return void 0;
5234
- return truncateUtf8(
5235
- redactString(redactor, value, key),
5236
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5237
- );
5238
- }
5239
- function previewValue(value, input2) {
5240
- if (value === null) return { kind: "null" };
5241
- if (value === void 0) return { kind: "unavailable", reason: "undefined" };
5242
- if (typeof value === "string") {
5243
- return {
5244
- kind: "scalar",
5245
- value: safeString(value, input2.redactor, input2.key) ?? ""
5246
- };
5247
- }
5248
- if (typeof value === "number") {
5249
- return Number.isFinite(value) ? { kind: "scalar", value } : { kind: "unavailable", reason: "unsupported" };
5250
- }
5251
- if (typeof value === "boolean") return { kind: "scalar", value };
5252
- if (typeof value === "bigint") {
5253
- return { kind: "unavailable", reason: "bigint" };
5254
- }
5255
- if (typeof value === "function") {
5256
- return { kind: "unavailable", reason: "function" };
5257
- }
5258
- if (typeof value === "symbol") {
5259
- return { kind: "unavailable", reason: "symbol" };
5260
- }
5261
- if (typeof value !== "object") {
5262
- return { kind: "unavailable", reason: "unsupported" };
5263
- }
5264
- try {
5265
- const brand = readDataProperty(value, PLAY_DATASET_BRAND);
5266
- const datasetKind = readDataProperty(value, "datasetKind");
5267
- const datasetId = readDataProperty(value, "datasetId");
5268
- const tableNamespace = readDataProperty(value, "tableNamespace");
5269
- if (brand.ok && brand.value === true && datasetKind.ok && (datasetKind.value === "csv" || datasetKind.value === "map") && datasetId.ok && typeof datasetId.value === "string") {
5270
- return {
5271
- kind: "dataset",
5272
- datasetId: safeString(datasetId.value, input2.redactor, "datasetId") ?? "dataset",
5273
- datasetKind: datasetKind.value,
5274
- tableNamespace: tableNamespace.ok && tableNamespace.value === null ? null : tableNamespace.ok ? safeString(
5275
- tableNamespace.value,
5276
- input2.redactor,
5277
- "tableNamespace"
5278
- ) : void 0
5279
- };
5280
- }
5281
- const kind = readDataProperty(value, "kind");
5282
- const count = readDataProperty(value, "count");
5283
- const preview = readDataProperty(value, "preview");
5284
- if (kind.ok && kind.value === "dataset" && datasetKind.ok && (datasetKind.value === "csv" || datasetKind.value === "map") && datasetId.ok && typeof datasetId.value === "string" && count.ok && typeof count.value === "number" && preview.ok && Array.isArray(preview.value)) {
5285
- return {
5286
- kind: "dataset",
5287
- datasetId: safeString(datasetId.value, input2.redactor, "datasetId") ?? "dataset",
5288
- datasetKind: datasetKind.value,
5289
- tableNamespace: tableNamespace.ok && tableNamespace.value === null ? null : tableNamespace.ok ? safeString(
5290
- tableNamespace.value,
5291
- input2.redactor,
5292
- "tableNamespace"
5293
- ) : void 0,
5294
- rowCount: Math.max(0, Math.floor(count.value))
5295
- };
5296
- }
5297
- } catch {
5298
- return { kind: "unavailable", reason: "access_error" };
5299
- }
5300
- if (input2.ancestors.has(value)) {
5301
- return { kind: "unavailable", reason: "cycle" };
5302
- }
5303
- if (input2.depth >= DOCFLOW_NODE_IO_LIMITS.maxDepth) {
5304
- return { kind: "unavailable", reason: "depth" };
5305
- }
5306
- input2.ancestors.add(value);
5307
- try {
5308
- if (Array.isArray(value)) {
5309
- const items = [];
5310
- for (let index = 0; index < Math.min(value.length, DOCFLOW_NODE_IO_LIMITS.maxArrayItems); index += 1) {
5311
- const descriptor = Object.getOwnPropertyDescriptor(
5312
- value,
5313
- String(index)
5314
- );
5315
- items.push(
5316
- descriptor && "value" in descriptor ? previewValue(descriptor.value, {
5317
- ...input2,
5318
- depth: input2.depth + 1
5319
- }) : { kind: "unavailable", reason: "access_error" }
5320
- );
5321
- }
5322
- return {
5323
- kind: "array",
5324
- items,
5325
- totalItems: value.length,
5326
- ...value.length > items.length ? { truncated: true } : {}
5327
- };
5328
- }
5329
- let descriptors;
5330
- try {
5331
- descriptors = Object.getOwnPropertyDescriptors(value);
5332
- } catch {
5333
- return { kind: "unavailable", reason: "access_error" };
5334
- }
5335
- const entries = Object.entries(descriptors).filter(
5336
- ([, descriptor]) => descriptor.enumerable
5337
- );
5338
- const selected = entries.slice(0, DOCFLOW_NODE_IO_LIMITS.maxObjectFields);
5339
- const fields2 = {};
5340
- for (const [key, descriptor] of selected) {
5341
- const safeKey = truncateUtf8(
5342
- ledgerSafeDocflowPreviewKey(input2.redactor.redactString(key)),
5343
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5344
- );
5345
- fields2[safeKey] = "value" in descriptor ? previewValue(descriptor.value, {
5346
- ...input2,
5347
- depth: input2.depth + 1,
5348
- key
5349
- }) : { kind: "unavailable", reason: "access_error" };
5350
- }
5351
- return {
5352
- kind: "object",
5353
- fields: fields2,
5354
- totalFields: entries.length,
5355
- ...entries.length > selected.length ? { truncated: true } : {}
5356
- };
5357
- } catch {
5358
- return { kind: "unavailable", reason: "access_error" };
5359
- } finally {
5360
- input2.ancestors.delete(value);
5361
- }
5362
- }
5363
- function readDataProperty(value, property) {
5364
- if ((typeof value !== "object" || value === null) && typeof value !== "function") {
5365
- return { ok: false };
5366
- }
5367
- try {
5368
- let owner = value;
5369
- while (owner) {
5370
- const descriptor = Object.getOwnPropertyDescriptor(owner, property);
5371
- if (descriptor) {
5372
- return "value" in descriptor ? { ok: true, value: descriptor.value } : { ok: false };
5373
- }
5374
- owner = Object.getPrototypeOf(owner);
5375
- }
5376
- } catch {
5377
- return { ok: false };
5378
- }
5379
- return { ok: false };
5380
- }
5381
- function buildPlayDocflowNodeErrorPreview(error, redactor = createSecretRedactionContext()) {
5382
- try {
5383
- const message = error instanceof Error ? error.message : String(error);
5384
- return truncateUtf8(
5385
- redactor.redactString(message),
5386
- DOCFLOW_NODE_IO_LIMITS.maxErrorBytes
5387
- );
5388
- } catch {
5389
- return "Non-Error value thrown (message unavailable)";
5390
- }
5391
- }
5392
- function isRecord4(value) {
5393
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5394
- }
5395
- function normalizePreview(value, depth) {
5396
- if (!isRecord4(value) || typeof value.kind !== "string") return null;
5397
- if (value.kind === "null") return { kind: "null" };
5398
- if (value.kind === "scalar") {
5399
- if (typeof value.value === "string" || typeof value.value === "boolean" || typeof value.value === "number" && Number.isFinite(value.value)) {
5400
- return previewValue(value.value, {
5401
- depth: 0,
5402
- ancestors: /* @__PURE__ */ new WeakSet(),
5403
- redactor: createSecretRedactionContext()
5404
- });
5405
- }
5406
- return null;
5407
- }
5408
- if (value.kind === "unavailable") {
5409
- const reason = value.reason;
5410
- return typeof reason === "string" && [
5411
- "undefined",
5412
- "function",
5413
- "symbol",
5414
- "bigint",
5415
- "cycle",
5416
- "depth",
5417
- "access_error",
5418
- "limit",
5419
- "unsupported"
5420
- ].includes(reason) ? {
5421
- kind: "unavailable",
5422
- reason
5423
- } : null;
5424
- }
5425
- if (value.kind === "dataset") {
5426
- const datasetId = safeString(
5427
- value.datasetId,
5428
- createSecretRedactionContext(),
5429
- "datasetId"
5430
- );
5431
- if (!datasetId || value.datasetKind !== "csv" && value.datasetKind !== "map") {
5432
- return null;
5433
- }
5434
- return {
5435
- kind: "dataset",
5436
- datasetId,
5437
- datasetKind: value.datasetKind,
5438
- ...value.tableNamespace === null ? { tableNamespace: null } : typeof value.tableNamespace === "string" ? {
5439
- tableNamespace: safeString(
5440
- value.tableNamespace,
5441
- createSecretRedactionContext(),
5442
- "tableNamespace"
5443
- )
5444
- } : {},
5445
- ...typeof value.rowCount === "number" && Number.isFinite(value.rowCount) ? { rowCount: Math.max(0, Math.floor(value.rowCount)) } : {}
5446
- };
5447
- }
5448
- if (depth >= DOCFLOW_NODE_IO_LIMITS.maxDepth) {
5449
- return { kind: "unavailable", reason: "depth" };
5450
- }
5451
- if (value.kind === "array" && Array.isArray(value.items)) {
5452
- const items = value.items.slice(0, DOCFLOW_NODE_IO_LIMITS.maxArrayItems).map((item) => normalizePreview(item, depth + 1)).filter((item) => item !== null);
5453
- const totalItems = typeof value.totalItems === "number" && Number.isFinite(value.totalItems) ? Math.max(items.length, Math.floor(value.totalItems)) : items.length;
5454
- return {
5455
- kind: "array",
5456
- items,
5457
- totalItems,
5458
- ...value.truncated === true || totalItems > items.length ? { truncated: true } : {}
5459
- };
5460
- }
5461
- if (value.kind === "object" && isRecord4(value.fields)) {
5462
- const fields2 = {};
5463
- for (const [key, field] of Object.entries(value.fields).slice(
5464
- 0,
5465
- DOCFLOW_NODE_IO_LIMITS.maxObjectFields
5466
- )) {
5467
- const normalized = normalizePreview(field, depth + 1);
5468
- if (normalized) fields2[ledgerSafeDocflowPreviewKey(key)] = normalized;
5469
- }
5470
- const totalFields = typeof value.totalFields === "number" && Number.isFinite(value.totalFields) ? Math.max(Object.keys(fields2).length, Math.floor(value.totalFields)) : Object.keys(fields2).length;
5471
- return {
5472
- kind: "object",
5473
- fields: fields2,
5474
- totalFields,
5475
- ...value.truncated === true || totalFields > Object.keys(fields2).length ? { truncated: true } : {}
5476
- };
5477
- }
5478
- return null;
5479
- }
5480
- function normalizePlayDocflowNodeIoState(value) {
5481
- if (!isRecord4(value)) return void 0;
5482
- const attempt = typeof value.attempt === "number" && Number.isFinite(value.attempt) ? Math.max(0, Math.floor(value.attempt)) : 0;
5483
- const normalizeMap = (raw) => {
5484
- if (!isRecord4(raw)) return void 0;
5485
- const output2 = {};
5486
- for (const [path, preview] of Object.entries(raw).slice(
5487
- 0,
5488
- DOCFLOW_NODE_IO_LIMITS.maxPaths
5489
- )) {
5490
- const normalized = normalizePreview(preview, 0);
5491
- if (!normalized) continue;
5492
- const safePath = ledgerSafeDocflowPreviewKey(path);
5493
- const candidate = { ...output2, [safePath]: normalized };
5494
- if (utf8Bytes(JSON.stringify(candidate)) > DOCFLOW_NODE_IO_LIMITS.maxPhaseBytes) {
5495
- break;
5496
- }
5497
- output2[safePath] = normalized;
5498
- }
5499
- return output2;
5500
- };
5501
- const inputs = normalizeMap(value.inputs);
5502
- const outputs = normalizeMap(value.outputs);
5503
- const error = typeof value.error === "string" ? buildPlayDocflowNodeErrorPreview(value.error) : value.error === null ? null : void 0;
5504
- return {
5505
- attempt,
5506
- ...typeof value.invocationId === "string" && value.invocationId.trim() ? {
5507
- invocationId: truncateUtf8(
5508
- value.invocationId.trim(),
5509
- DOCFLOW_NODE_IO_LIMITS.maxStringBytes
5510
- )
5511
- } : {},
5512
- ...inputs ? { inputs } : {},
5513
- ...outputs ? { outputs } : {},
5514
- ...value.inputsTruncated === true ? { inputsTruncated: true } : {},
5515
- ...value.outputsTruncated === true ? { outputsTruncated: true } : {},
5516
- ...error !== void 0 ? { error } : {}
5517
- };
5518
- }
5519
-
5520
- // ../play-runtime/activity-observation.ts
5521
- function isRecord5(value) {
5522
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5523
- }
5524
- function isPlayActivityObservation(value) {
5525
- if (!isRecord5(value) || value.schemaVersion !== void 0 && value.schemaVersion !== 1 || typeof value.activityId !== "string" || !value.activityId.trim() || typeof value.observedAt !== "number" || !Number.isFinite(value.observedAt) || !isRecord5(value.target) || !isRecord5(value.state)) {
5526
- return false;
5527
- }
5528
- const targetKinds = /* @__PURE__ */ new Set([
5529
- "provider",
5530
- "dataset",
5531
- "lease",
5532
- "runner",
5533
- "step",
5534
- "capacity"
5535
- ]);
5536
- const stateKinds = /* @__PURE__ */ new Set([
5537
- "active",
5538
- "queued",
5539
- "waiting",
5540
- "retrying",
5541
- "scheduled",
5542
- "completed",
5543
- "failed"
5544
- ]);
5545
- return typeof value.target.kind === "string" && targetKinds.has(value.target.kind) && typeof value.state.kind === "string" && stateKinds.has(value.state.kind);
5546
- }
5547
- function derivePlayActivityVisibility(input2) {
5548
- const { state } = input2.observation;
5549
- if (state.kind === "failed") return "action";
5550
- if (state.kind === "waiting") {
5551
- return state.reason.kind === "external_event" ? "action" : "headline";
5552
- }
5553
- if (state.kind === "queued" || state.kind === "scheduled") return "headline";
5554
- if (state.kind === "retrying") {
5555
- if (state.reason === "rate_limit" && input2.observation.target.kind === "capacity") {
5556
- return "headline";
5557
- }
5558
- if (state.retryAt - input2.now <= 3e4) return "hidden";
5559
- return state.reason === "rate_limit" ? "headline" : "timeline";
5560
- }
5561
- if (state.kind === "active") return "headline";
5562
- return "timeline";
5563
- }
5564
- function targetLabel(target) {
5565
- switch (target.kind) {
5566
- case "provider":
5567
- return target.label ?? `${target.provider} ${target.operation}`;
5568
- case "dataset":
5569
- return target.label ?? `dataset ${target.tableNamespace}`;
5570
- case "lease":
5571
- return `${target.resourceKind} ${target.resourceLabel}`;
5572
- case "runner":
5573
- return target.label ?? `${target.backend} runner`;
5574
- case "step":
5575
- return target.label ?? target.stepId;
5576
- case "capacity":
5577
- return target.label ?? `${target.pool} capacity`;
5578
- }
5579
- }
5580
- function summarizePlayActivity(observation) {
5581
- const label = targetLabel(observation.target);
5582
- const { state } = observation;
5583
- switch (state.kind) {
5584
- case "active": {
5585
- const progress = state.progress;
5586
- const counts = typeof progress?.completed === "number" && typeof progress.total === "number" ? ` (${progress.completed}/${progress.total})` : "";
5587
- return `Active: ${label}${counts}.`;
5588
- }
5589
- case "queued":
5590
- return `Queued: waiting for ${label}.`;
5591
- case "waiting":
5592
- if (state.reason.kind === "external_event") {
5593
- const provider = state.reason.provider ? ` from ${state.reason.provider}` : "";
5594
- return `Blocked: waiting for an external event${provider}.`;
5595
- }
5596
- if (state.reason.kind === "dataset") {
5597
- return `Blocked: waiting for dataset ${state.reason.tableNamespace} to become ${state.reason.requiredPhase}.`;
5598
- }
5599
- if (state.reason.kind === "lease") {
5600
- return `Contended: waiting for ${state.reason.resourceKind} lease ${state.reason.resourceLabel}.`;
5601
- }
5602
- return `Paused: ${label}; the legacy producer did not report a typed reason.`;
5603
- case "retrying":
5604
- if (state.reason === "rate_limit") {
5605
- return `Waiting for ${label} request capacity; the run will retry automatically.`;
5606
- }
5607
- return `Delayed: ${label} will retry automatically.`;
5608
- case "scheduled":
5609
- return `Scheduled: ${label} will resume automatically.`;
5610
- case "completed":
5611
- return `Completed: ${label}.`;
5612
- case "failed":
5613
- return `Failed: ${label}.`;
5614
- }
5615
- }
5616
- function isTerminalActivityState(state) {
5617
- return state.kind === "completed" || state.kind === "failed";
5618
- }
5619
- function projection(observation, now, classified = true) {
5620
- return {
5621
- observation,
5622
- summary: summarizePlayActivity(observation),
5623
- visibility: derivePlayActivityVisibility({ observation, now }),
5624
- classified
5625
- };
5626
- }
5627
- function projectPlayRunActivity(input2) {
5628
- const now = input2.now ?? Date.now();
5629
- const observedAt = input2.updatedAt ?? now;
5630
- const normalizedStatus = input2.status.trim().toLowerCase();
5631
- if (normalizedStatus === "completed" || normalizedStatus === "failed" || normalizedStatus === "cancelled" || normalizedStatus === "terminated" || normalizedStatus === "timed_out") {
5632
- return null;
5633
- }
5634
- const latestExplicit = [...input2.explicit ?? []].filter((candidate) => !isTerminalActivityState(candidate.state)).sort((left, right) => right.observedAt - left.observedAt)[0];
5635
- const explicit = latestExplicit?.target.kind === "capacity" && latestExplicit.target.pool === "provider" && latestExplicit.state.kind === "retrying" && latestExplicit.state.retryAt < now ? null : latestExplicit;
5636
- if (explicit) return projection(explicit, now);
5637
- if (input2.waitKind === "detached_runner") {
5638
- return projection(
5639
- {
5640
- activityId: "runner:managed",
5641
- target: {
5642
- kind: "runner",
5643
- backend: input2.runtimeBackend ?? "managed",
5644
- label: "managed play runner"
5645
- },
5646
- state: { kind: "active" },
5647
- observedAt
5648
- },
5649
- now
5650
- );
5651
- }
5652
- if (input2.waitKind === "sleep") {
5653
- return projection(
5654
- {
5655
- activityId: "run:sleep",
5656
- target: {
5657
- kind: "step",
5658
- stepId: input2.activeNodeId ?? "run",
5659
- label: input2.playName ?? "play"
5660
- },
5661
- state: {
5662
- kind: "scheduled",
5663
- reason: "sleep",
5664
- resumeAt: input2.waitUntil ?? observedAt
5665
- },
5666
- observedAt
5667
- },
5668
- now
5669
- );
5670
- }
5671
- if (input2.waitKind === "integration_event" || input2.waitKind === "integration_event_batch") {
5672
- return projection(
5673
- {
5674
- activityId: `event:${input2.activeNodeId ?? "run"}`,
5675
- stepId: input2.activeNodeId ?? void 0,
5676
- target: {
5677
- kind: "step",
5678
- stepId: input2.activeNodeId ?? "run",
5679
- label: input2.playName ?? "play"
5680
- },
5681
- state: {
5682
- kind: "waiting",
5683
- reason: {
5684
- kind: "external_event",
5685
- eventKey: input2.eventKey ?? void 0,
5686
- deadlineAt: input2.waitUntil ?? void 0
5687
- }
5688
- },
5689
- observedAt
5690
- },
5691
- now
5692
- );
5693
- }
5694
- if (normalizedStatus === "waiting") {
5695
- return projection(
5696
- {
5697
- activityId: "run:legacy-wait",
5698
- target: {
5699
- kind: "step",
5700
- stepId: input2.activeNodeId ?? "run",
5701
- label: input2.playName ?? "play"
5702
- },
5703
- state: { kind: "waiting", reason: { kind: "unknown" } },
5704
- observedAt
5705
- },
5706
- now,
5707
- false
5708
- );
5709
- }
5710
- const pendingDataset = [...input2.datasets ?? []].filter(
5711
- (dataset) => dataset.phase === "registered" || dataset.complete !== true && dataset.phase !== "failed"
5712
- ).sort((left, right) => (right.updatedAt ?? 0) - (left.updatedAt ?? 0))[0];
5713
- if (pendingDataset) {
5714
- const activeDatasetStep = input2.nodeStates?.find(
5715
- (candidate) => candidate.nodeId === input2.activeNodeId && candidate.status === "running" && candidate.artifactTableNamespace === pendingDataset.tableNamespace
5716
- );
5717
- const datasetStep = activeDatasetStep ?? input2.nodeStates?.find(
5718
- (candidate) => candidate.artifactTableNamespace === pendingDataset.tableNamespace
5719
- );
5720
- const datasetProgress = datasetStep?.progress ?? null;
5721
- return projection(
5722
- {
5723
- activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
5724
- target: {
5725
- kind: "dataset",
5726
- tableNamespace: pendingDataset.tableNamespace,
5727
- operation: "materializing"
5728
- },
5729
- state: {
5730
- kind: "active",
5731
- progress: {
5732
- completed: datasetProgress?.completed ?? pendingDataset.persistedRows,
5733
- total: datasetProgress?.total ?? (typeof pendingDataset.succeededRows === "number" || typeof pendingDataset.failedRows === "number" ? (pendingDataset.succeededRows ?? 0) + (pendingDataset.failedRows ?? 0) : void 0),
5734
- failed: datasetProgress?.failed ?? pendingDataset.failedRows
5735
- }
5736
- },
5737
- observedAt: datasetStep?.updatedAt ?? pendingDataset.updatedAt ?? observedAt
5738
- },
5739
- now
5740
- );
5741
- }
5742
- const activeStep = input2.nodeStates?.find(
5743
- (candidate) => candidate.nodeId === input2.activeNodeId
5744
- ) ?? input2.nodeStates?.find((candidate) => candidate.status === "running") ?? null;
5745
- if (activeStep) {
5746
- const toolId = activeStep.nodeId.startsWith("tool:") ? activeStep.nodeId.split(":").at(-1)?.trim() || null : null;
5747
- const provider = toolId?.split(/[._]/)[0]?.trim() || null;
5748
- return projection(
5749
- {
5750
- activityId: `step:${activeStep.nodeId}`,
5751
- stepId: activeStep.nodeId,
5752
- target: toolId && provider ? {
5753
- kind: "provider",
5754
- provider,
5755
- operation: toolId,
5756
- label: activeStep.label ?? toolId
5757
- } : {
5758
- kind: "step",
5759
- stepId: activeStep.nodeId,
5760
- label: activeStep.label
5761
- },
5762
- state: {
5763
- kind: "active",
5764
- progress: activeStep.progress ?? void 0
5765
- },
5766
- observedAt: activeStep.updatedAt ?? observedAt
5767
- },
5768
- now
5769
- );
5770
- }
5771
- if (normalizedStatus === "queued") {
5772
- return projection(
5773
- {
5774
- activityId: "capacity:worker",
5775
- target: { kind: "capacity", pool: "worker" },
5776
- state: { kind: "queued", reason: "capacity" },
5777
- observedAt
5778
- },
5779
- now
5780
- );
5781
- }
5782
- const fallback = {
5783
- activityId: "run:legacy",
5784
- target: {
5785
- kind: "step",
5786
- stepId: input2.activeNodeId ?? "run",
5787
- label: input2.playName ?? "play"
5788
- },
5789
- state: normalizedStatus === "waiting" ? { kind: "waiting", reason: { kind: "unknown" } } : { kind: "active" },
5790
- observedAt
5791
- };
5792
- return projection(fallback, now, normalizedStatus !== "waiting");
5793
- }
5794
-
5795
- // ../play-runtime/cell-provenance.ts
5796
- function finiteNonNegativeInteger2(value) {
5797
- if (typeof value !== "number" || !Number.isFinite(value) || value < 0) {
5798
- return null;
5799
- }
5800
- return Math.trunc(value);
5801
- }
5802
- function nonEmptyString(value) {
5803
- if (typeof value !== "string") return null;
5804
- const trimmed = value.trim();
5805
- return trimmed ? trimmed : null;
5806
- }
5807
- function normalizeDatasetBornFrom(value) {
5808
- if (!value || typeof value !== "object" || Array.isArray(value)) return null;
5809
- const record3 = value;
5810
- const table = nonEmptyString(record3.table);
5811
- const rowCountIn = finiteNonNegativeInteger2(record3.rowCountIn);
5812
- if (!table || rowCountIn === null) return null;
5813
- return { table, rowCountIn };
5814
- }
5815
-
5816
- // ../play-runtime/run-ledger.ts
5817
- var LOG_TAIL_LIMIT = 100;
5818
- var TERMINAL_STATUSES = /* @__PURE__ */ new Set([
5819
- "completed",
5820
- "failed",
5821
- "cancelled",
5822
- "terminated",
5823
- "timed_out"
5824
- ]);
5825
- function isRecord6(value) {
5826
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
5827
- }
5828
- function finiteNumber(value) {
5829
- return typeof value === "number" && Number.isFinite(value) ? value : null;
5830
- }
5831
- function nonnegativeSafeInteger(value) {
5832
- return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
5833
- }
5834
- function isWorkCounterSegmentId(value) {
5835
- return typeof value === "string" && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(
5836
- value
5837
- );
5838
- }
5839
- function normalizePlayRunLedgerTerminalWorkCounterSegment(value) {
5840
- if (!isRecord6(value)) return void 0;
5841
- if (!nonnegativeSafeInteger(value.attempt) || !nonnegativeSafeInteger(value.invocationSeq) || value.invocationSeq === 0 || !isWorkCounterSegmentId(value.segmentId)) {
5842
- return void 0;
5843
- }
5844
- return {
5845
- attempt: value.attempt,
5846
- invocationSeq: value.invocationSeq,
5847
- segmentId: value.segmentId
5848
- };
5849
- }
5850
- function hasConfirmedPlayRunLedgerWorkCounters(snapshot) {
5851
- const counters = snapshot.workCounters;
5852
- const terminal = snapshot.terminalWorkCounterSegment;
5853
- return Boolean(
5854
- isTerminalPlayRunLedgerStatus(snapshot.status) && (snapshot.terminalSource === "worker" || snapshot.terminalSource === "system") && counters?.final && counters.completeThroughAttempt && counters.consistent && terminal && counters.attempt === terminal.attempt && counters.invocationSeq === terminal.invocationSeq && counters.segmentId === terminal.segmentId && Number.isSafeInteger(
5855
- counters.completedLogicalCalls + counters.logicalCalls
5856
- ) && Number.isSafeInteger(
5857
- counters.completedProviderRequests + counters.providerRequests
5858
- ) && Number.isSafeInteger(
5859
- counters.completedProvider429s + counters.provider429s
5860
- )
5861
- );
5862
- }
5863
- function normalizeWorkCounters(value) {
5864
- if (!isRecord6(value)) return void 0;
5865
- for (const field of [
5866
- "attempt",
5867
- "invocationSeq",
5868
- "logicalCalls",
5869
- "providerRequests",
5870
- "provider429s",
5871
- "completedLogicalCalls",
5872
- "completedProviderRequests",
5873
- "completedProvider429s"
5874
- ]) {
5875
- if (!nonnegativeSafeInteger(value[field])) return void 0;
5876
- }
5877
- if (value.invocationSeq === 0 || !isWorkCounterSegmentId(value.segmentId) || typeof value.final !== "boolean" || typeof value.completeThroughAttempt !== "boolean" || typeof value.consistent !== "boolean") {
5878
- return void 0;
5879
- }
5880
- return {
5881
- ...value,
5882
- attempt: value.attempt,
5883
- invocationSeq: value.invocationSeq,
5884
- segmentId: value.segmentId,
5885
- logicalCalls: value.logicalCalls,
5886
- providerRequests: value.providerRequests,
5887
- provider429s: value.provider429s,
5888
- final: value.final,
5889
- completedLogicalCalls: value.completedLogicalCalls,
5890
- completedProviderRequests: value.completedProviderRequests,
5891
- completedProvider429s: value.completedProvider429s,
5892
- completeThroughAttempt: value.completeThroughAttempt,
5893
- consistent: value.consistent
5894
- };
5895
- }
5896
- function optionalFiniteNumber(value) {
5897
- const normalized = finiteNumber(value);
5898
- return normalized === null ? void 0 : normalized;
5899
- }
5900
- function optionalString(value) {
5901
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
5902
- }
5903
- function optionalNullableString(value) {
5904
- if (value === null) return null;
5905
- return optionalString(value);
5906
- }
5907
- function normalizePlayRunLedgerStatus(value) {
5908
- const normalized = String(value ?? "").trim().toLowerCase();
5909
- switch (normalized) {
5910
- case "queued":
5911
- case "pending":
5912
- return "queued";
5913
- case "running":
5914
- case "started":
5915
- return "running";
5916
- case "waiting":
5917
- return "waiting";
5918
- case "completed":
5919
- case "complete":
5920
- case "succeeded":
5921
- return "completed";
5922
- case "failed":
5923
- case "error":
5924
- return "failed";
5925
- case "cancelled":
5926
- case "canceled":
5927
- return "cancelled";
5928
- case "terminated":
5929
- return "terminated";
5930
- case "timed_out":
5931
- case "timeout":
5932
- return "timed_out";
5933
- default:
5934
- return "unknown";
5935
- }
5936
- }
5937
- function isTerminalPlayRunLedgerStatus(status) {
5938
- return TERMINAL_STATUSES.has(status);
5939
- }
5940
- function summarizeRunRowOutcomes(snapshot) {
5941
- let completedRows = 0;
5942
- let failedRows = 0;
5943
- let totalRows = 0;
5944
- let supersededRows = 0;
5945
- for (const step of Object.values(snapshot.stepsById)) {
5946
- const progress = step.progress;
5947
- if (!progress) continue;
5948
- completedRows += Math.max(0, finiteNumber(progress.completed) ?? 0);
5949
- failedRows += Math.max(0, finiteNumber(progress.failed) ?? 0);
5950
- supersededRows += Math.max(0, finiteNumber(progress.supersededRows) ?? 0);
5951
- const stepTotal = finiteNumber(progress.total);
5952
- totalRows += stepTotal !== null && stepTotal >= 0 ? stepTotal : Math.max(0, finiteNumber(progress.completed) ?? 0) + Math.max(0, finiteNumber(progress.failed) ?? 0) + Math.max(0, finiteNumber(progress.supersededRows) ?? 0);
5953
- }
5954
- const resultSummary = isRecord6(snapshot.resultSummary) ? snapshot.resultSummary : null;
5955
- const resultRowOutcomes = isRecord6(resultSummary?.rowOutcomes) ? resultSummary.rowOutcomes : null;
5956
- const terminalCompletedRows = finiteNumber(resultRowOutcomes?.completedRows);
5957
- const terminalFailedRows = finiteNumber(resultRowOutcomes?.failedRows);
5958
- const terminalTotalRows = finiteNumber(resultRowOutcomes?.totalRows);
5959
- const terminalSupersededRows = finiteNumber(
5960
- resultRowOutcomes?.supersededRows
5961
- );
5962
- const settledCompletedRows = terminalCompletedRows ?? completedRows;
5963
- const settledFailedRows = terminalFailedRows ?? failedRows;
5964
- return {
5965
- completedRows: settledCompletedRows,
5966
- failedRows: settledFailedRows,
5967
- totalRows: terminalTotalRows ?? totalRows,
5968
- hasRowFailures: settledFailedRows > 0,
5969
- ...(terminalSupersededRows ?? supersededRows) > 0 ? { supersededRows: terminalSupersededRows ?? supersededRows } : {}
5970
- };
5971
- }
5972
- function createEmptyPlayRunLedgerSnapshot(input2) {
5973
- const status = normalizePlayRunLedgerStatus(input2.status ?? "unknown");
5974
- const startedAt = finiteNumber(input2.startedAt) ?? null;
5975
- const finishedAt = finiteNumber(input2.finishedAt) ?? null;
5976
- return {
5977
- runId: input2.runId,
5978
- playName: input2.playName ?? null,
5979
- status,
5980
- waitKind: null,
5981
- waitUntil: null,
5982
- error: optionalNullableString(input2.error) ?? null,
5983
- createdAt: finiteNumber(input2.createdAt) ?? null,
5984
- startedAt,
5985
- updatedAt: finiteNumber(input2.updatedAt) ?? finishedAt ?? startedAt ?? finiteNumber(input2.createdAt) ?? null,
5986
- finishedAt,
5987
- durationMs: startedAt !== null && finishedAt !== null ? Math.max(0, finishedAt - startedAt) : null,
5988
- orderedStepIds: [],
5989
- stepsById: {},
5990
- orderedDatasetIds: [],
5991
- datasetsById: {},
5992
- orderedActivityIds: [],
5993
- activitiesById: {},
5994
- logTail: [],
5995
- totalLogCount: 0,
5996
- logsTruncated: false,
5997
- activeStepId: null,
5998
- activeActivityId: null,
5999
- activeArtifactTableNamespace: null,
6000
- resultTableNamespace: null
6001
- };
6002
- }
6003
- function normalizePlayRunLedgerSnapshot(value, fallback) {
6004
- if (!isRecord6(value)) {
6005
- return createEmptyPlayRunLedgerSnapshot(fallback);
6006
- }
6007
- const orderedStepIds = Array.isArray(value.orderedStepIds) ? value.orderedStepIds.filter(
6008
- (entry) => typeof entry === "string" && Boolean(entry.trim())
6009
- ) : [];
6010
- const rawSteps = isRecord6(value.stepsById) ? value.stepsById : {};
6011
- const stepsById = {};
6012
- for (const [stepId, rawStep] of Object.entries(rawSteps)) {
6013
- if (!stepId.trim() || !isRecord6(rawStep)) continue;
6014
- const rawStatus = normalizeStepStatus(rawStep.status);
6015
- if (!rawStatus) continue;
6016
- const completedAt = finiteNumber(rawStep.completedAt);
6017
- const status = rawStatus === "running" && completedAt !== null ? "completed" : rawStatus;
6018
- const rawProgress = isRecord6(rawStep.progress) ? rawStep.progress : null;
6019
- stepsById[stepId] = {
6020
- stepId,
6021
- label: optionalString(rawStep.label),
6022
- kind: optionalString(rawStep.kind),
6023
- status,
6024
- error: optionalNullableString(rawStep.error),
6025
- artifactTableNamespace: optionalNullableString(
6026
- rawStep.artifactTableNamespace
6027
- ),
6028
- startedAt: finiteNumber(rawStep.startedAt),
6029
- completedAt,
6030
- updatedAt: finiteNumber(rawStep.updatedAt),
6031
- progress: rawProgress ? normalizeStepProgress(rawProgress) : null
6032
- };
6033
- }
6034
- const rawDatasets = isRecord6(value.datasetsById) ? value.datasetsById : {};
6035
- const datasetsById = {};
6036
- for (const [datasetId, rawDataset] of Object.entries(rawDatasets)) {
6037
- if (!datasetId.trim() || !isRecord6(rawDataset)) continue;
6038
- const phase = rawDataset.phase === "available" || rawDataset.phase === "failed" ? rawDataset.phase : "registered";
6039
- const datasetBornFrom = normalizeDatasetBornFrom(rawDataset.bornFrom);
6040
- datasetsById[datasetId] = {
6041
- datasetId,
6042
- path: optionalString(rawDataset.path) ?? `datasets.${datasetId}`,
6043
- tableNamespace: optionalString(rawDataset.tableNamespace) ?? datasetId,
6044
- phase,
6045
- persistedRows: Math.max(0, finiteNumber(rawDataset.persistedRows) ?? 0),
6046
- persistedRowsObserved: rawDataset.persistedRowsObserved === true,
6047
- succeededRows: Math.max(0, finiteNumber(rawDataset.succeededRows) ?? 0),
6048
- succeededRowsObserved: rawDataset.succeededRowsObserved === true,
6049
- failedRows: Math.max(0, finiteNumber(rawDataset.failedRows) ?? 0),
6050
- failedRowsObserved: rawDataset.failedRowsObserved === true,
6051
- complete: rawDataset.complete === true,
6052
- completeObserved: rawDataset.completeObserved === true,
6053
- // ADR 0019 birth survives the snapshot round trip. A partial record is
6054
- // dropped rather than half-admitted, so a dataset either states where its
6055
- // rows came from or says nothing.
6056
- ...datasetBornFrom ? { bornFrom: datasetBornFrom } : {},
6057
- updatedAt: finiteNumber(rawDataset.updatedAt) ?? 0
6058
- };
6059
- }
6060
- const rawActivities = isRecord6(value.activitiesById) ? value.activitiesById : {};
6061
- const activitiesById = {};
6062
- for (const [activityId, rawActivity] of Object.entries(rawActivities)) {
6063
- if (activityId.trim() && isPlayActivityObservation(rawActivity) && rawActivity.activityId === activityId) {
6064
- activitiesById[activityId] = rawActivity;
6065
- }
6066
- }
6067
- const createdAt = finiteNumber(value.createdAt) ?? fallback.createdAt ?? null;
6068
- const startedAt = finiteNumber(value.startedAt) ?? fallback.startedAt ?? null;
6069
- const finishedAt = finiteNumber(value.finishedAt) ?? fallback.finishedAt ?? null;
6070
- const updatedAt = finiteNumber(value.updatedAt) ?? fallback.updatedAt ?? finishedAt ?? startedAt ?? createdAt ?? null;
6071
- const error = Object.prototype.hasOwnProperty.call(value, "error") ? optionalNullableString(value.error) ?? null : fallback.error ?? null;
6072
- const rawTail = Array.isArray(value.logTail) ? value.logTail : value.logs;
6073
- const logTail = Array.isArray(rawTail) ? rawTail.filter((line) => typeof line === "string") : [];
6074
- const workCounters = normalizeWorkCounters(value.workCounters);
6075
- const terminalWorkCounterSegment = normalizePlayRunLedgerTerminalWorkCounterSegment(
6076
- value.terminalWorkCounterSegment
6077
- );
6078
- return {
6079
- runId: optionalString(value.runId) ?? fallback.runId,
6080
- playName: optionalNullableString(value.playName) ?? fallback.playName ?? null,
6081
- status: normalizePlayRunLedgerStatus(value.status ?? fallback.status),
6082
- waitKind: optionalNullableString(value.waitKind),
6083
- waitUntil: finiteNumber(value.waitUntil),
6084
- error,
6085
- createdAt,
6086
- startedAt,
6087
- updatedAt,
6088
- finishedAt,
6089
- durationMs: startedAt !== null && finishedAt !== null ? Math.max(0, finishedAt - startedAt) : finiteNumber(value.durationMs),
6090
- orderedStepIds: orderedStepIds.filter((stepId) => stepsById[stepId]),
6091
- stepsById,
6092
- orderedDatasetIds: (Array.isArray(value.orderedDatasetIds) ? value.orderedDatasetIds : Object.keys(datasetsById)).filter(
6093
- (datasetId) => typeof datasetId === "string" && Boolean(datasetsById[datasetId])
6094
- ),
6095
- datasetsById,
6096
- orderedActivityIds: (Array.isArray(value.orderedActivityIds) ? value.orderedActivityIds : Object.keys(activitiesById)).filter(
6097
- (activityId) => typeof activityId === "string" && Boolean(activitiesById[activityId])
6098
- ),
6099
- activitiesById,
6100
- ...workCounters ? { workCounters } : {},
6101
- ...terminalWorkCounterSegment ? { terminalWorkCounterSegment } : {},
6102
- logTail: logTail.slice(-LOG_TAIL_LIMIT),
6103
- // Snapshots persisted before totalLogCount existed only know the retained
6104
- // tail, so the best lower bound for the cumulative count is the tail size.
6105
- totalLogCount: Math.max(
6106
- finiteNumber(value.totalLogCount) ?? logTail.length,
6107
- logTail.length
6108
- ),
6109
- // A persisted snapshot carrying more lines than the tail keeps is
6110
- // truncated here, whatever the stored flag says. Reporting `false` while
6111
- // dropping lines is silent loss: a reader would take the tail for the
6112
- // whole log.
6113
- logsTruncated: value.logsTruncated === true || logTail.length > LOG_TAIL_LIMIT,
6114
- activeStepId: optionalNullableString(value.activeStepId),
6115
- activeActivityId: optionalNullableString(value.activeActivityId),
6116
- activeArtifactTableNamespace: optionalNullableString(
6117
- value.activeArtifactTableNamespace
6118
- ),
6119
- resultTableNamespace: optionalNullableString(value.resultTableNamespace),
6120
- resultSummary: value.resultSummary,
6121
- result: value.result,
6122
- terminalSource: normalizePlayRunLedgerTerminalSource(value.terminalSource)
6123
- };
6124
- }
6125
- function normalizeStepStatus(value) {
6126
- const normalized = String(value ?? "").trim().toLowerCase();
6127
- if (normalized === "running" || normalized === "completed" || normalized === "failed" || normalized === "skipped") {
6128
- return normalized;
6129
- }
6130
- return null;
6131
- }
6132
- function normalizeStepProgress(value) {
6133
- return {
6134
- ...optionalFiniteNumber(value.completed) !== void 0 ? { completed: optionalFiniteNumber(value.completed) } : {},
6135
- ...optionalFiniteNumber(value.total) !== void 0 ? { total: optionalFiniteNumber(value.total) } : {},
6136
- ...optionalFiniteNumber(value.failed) !== void 0 ? { failed: optionalFiniteNumber(value.failed) } : {},
6137
- ...optionalFiniteNumber(value.startedRows) !== void 0 ? { startedRows: optionalFiniteNumber(value.startedRows) } : {},
6138
- ...optionalFiniteNumber(value.activeRows) !== void 0 ? { activeRows: optionalFiniteNumber(value.activeRows) } : {},
6139
- ...optionalFiniteNumber(value.waitingRows) !== void 0 ? { waitingRows: optionalFiniteNumber(value.waitingRows) } : {},
6140
- ...optionalFiniteNumber(value.completedRows) !== void 0 ? { completedRows: optionalFiniteNumber(value.completedRows) } : {},
6141
- ...optionalFiniteNumber(value.supersededRows) !== void 0 ? { supersededRows: optionalFiniteNumber(value.supersededRows) } : {},
6142
- ...optionalString(value.message) ? { message: optionalString(value.message) } : {},
6143
- ...optionalNullableString(value.artifactTableNamespace) !== void 0 ? {
6144
- artifactTableNamespace: optionalNullableString(
6145
- value.artifactTableNamespace
6146
- )
6147
- } : {},
6148
- ...finiteNumber(value.startedAt) !== null ? { startedAt: finiteNumber(value.startedAt) } : {},
6149
- ...finiteNumber(value.completedAt) !== null ? { completedAt: finiteNumber(value.completedAt) } : {},
6150
- ...finiteNumber(value.updatedAt) !== null ? { updatedAt: finiteNumber(value.updatedAt) } : {},
6151
- ...normalizePlayDocflowNodeIoState(value.nodeIo) ? { nodeIo: normalizePlayDocflowNodeIoState(value.nodeIo) } : {}
6152
- };
6153
- }
6154
5144
 
6155
5145
  // ../play-runtime/run-lifecycle-policy.ts
6156
5146
  var TERMINAL_PLAY_RUN_STATUSES = /* @__PURE__ */ new Set([
@@ -6266,9 +5256,6 @@ function readProvenanceTag(line) {
6266
5256
  const provenance = LOG_PROVENANCE_CLASSES.includes(candidate) ? candidate : null;
6267
5257
  return { provenance, line: line.slice(end + 1) };
6268
5258
  }
6269
- function stripProvenanceTag(line) {
6270
- return readProvenanceTag(line).line;
6271
- }
6272
5259
  function classifyLegacyLogLine(line) {
6273
5260
  const message = stripLeadingTimestamp(line);
6274
5261
  if (/recovered (?:from checkpoint|response from checkpoint)/i.test(message)) {
@@ -6341,143 +5328,9 @@ function stripLeadingTimestamp(line) {
6341
5328
  }
6342
5329
 
6343
5330
  // ../play-runtime/run-snapshot-stream.ts
6344
- function normalizePlayRunLiveStatus(value) {
6345
- return normalizePlayRunLifecycleStatus(value);
6346
- }
6347
5331
  function isTerminalPlayRunLiveStatus(status) {
6348
5332
  return isTerminalPlayRunLifecycleStatus(status);
6349
5333
  }
6350
- function isRecord7(value) {
6351
- return Boolean(value && typeof value === "object" && !Array.isArray(value));
6352
- }
6353
- function finiteNumber2(value) {
6354
- return typeof value === "number" && Number.isFinite(value) ? value : null;
6355
- }
6356
- function extractTerminalRunLogTail(result) {
6357
- if (!isRecord7(result) || !isRecord7(result._metadata)) {
6358
- return null;
6359
- }
6360
- const runLogTail = result._metadata.runLogTail;
6361
- if (!isRecord7(runLogTail) || !Array.isArray(runLogTail.tail)) {
6362
- return null;
6363
- }
6364
- const logTail = runLogTail.tail.filter(
6365
- (line) => typeof line === "string" && line.trim().length > 0
6366
- );
6367
- if (logTail.length === 0) {
6368
- return null;
6369
- }
6370
- const totalLogCount = Math.max(
6371
- finiteNumber2(runLogTail.totalLogCount) ?? logTail.length,
6372
- logTail.length
6373
- );
6374
- return {
6375
- logTail: logTail.slice(-LOG_TAIL_LIMIT),
6376
- totalLogCount
6377
- };
6378
- }
6379
- function buildSnapshotFromLedger(snapshot) {
6380
- const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
6381
- nodeId: step.stepId,
6382
- status: step.status,
6383
- error: step.error ?? null,
6384
- artifactTableNamespace: step.artifactTableNamespace ?? null,
6385
- progress: step.progress ? {
6386
- completed: step.progress.completed,
6387
- total: step.progress.total,
6388
- failed: step.progress.failed,
6389
- startedRows: step.progress.startedRows,
6390
- activeRows: step.progress.activeRows,
6391
- waitingRows: step.progress.waitingRows,
6392
- completedRows: step.progress.completedRows,
6393
- supersededRows: step.progress.supersededRows,
6394
- message: step.progress.message,
6395
- artifactTableNamespace: step.progress.artifactTableNamespace ?? step.artifactTableNamespace ?? null,
6396
- startedAt: step.startedAt ?? null,
6397
- completedAt: step.completedAt ?? null,
6398
- updatedAt: step.progress.updatedAt ?? step.updatedAt ?? null,
6399
- nodeIo: step.progress.nodeIo
6400
- } : null,
6401
- startedAt: step.startedAt ?? null,
6402
- completedAt: step.completedAt ?? null,
6403
- updatedAt: step.updatedAt ?? null,
6404
- ...step.progress?.nodeIo ? { nodeIo: step.progress.nodeIo } : {}
6405
- }));
6406
- const liveStatus = normalizePlayRunLiveStatus(snapshot.status);
6407
- const terminalRowOutcomes = isTerminalPlayRunLiveStatus(liveStatus) ? summarizeRunRowOutcomes(snapshot) : null;
6408
- const rowOutcomes = terminalRowOutcomes && (Object.keys(snapshot.stepsById).length > 0 || terminalRowOutcomes.totalRows > 0 || (terminalRowOutcomes.supersededRows ?? 0) > 0) ? terminalRowOutcomes : null;
6409
- const workCounters = snapshot.workCounters;
6410
- const calls = workCounters ? {
6411
- logicalCalls: workCounters.completedLogicalCalls + workCounters.logicalCalls,
6412
- providerRequests: workCounters.completedProviderRequests + workCounters.providerRequests,
6413
- provider429s: workCounters.completedProvider429s + workCounters.provider429s,
6414
- confirmed: isTerminalPlayRunLiveStatus(liveStatus) && hasConfirmedPlayRunLedgerWorkCounters(snapshot)
6415
- } : null;
6416
- return {
6417
- runId: snapshot.runId,
6418
- status: liveStatus,
6419
- createdAt: snapshot.createdAt ?? null,
6420
- startedAt: snapshot.startedAt ?? null,
6421
- finishedAt: snapshot.finishedAt ?? null,
6422
- durationMs: snapshot.durationMs ?? null,
6423
- updatedAt: snapshot.updatedAt ?? snapshot.finishedAt ?? snapshot.startedAt ?? null,
6424
- // This snapshot is public SDK/API transport. Keep the historical plain
6425
- // timestamp-prefixed text while provenance remains runtime metadata.
6426
- logs: snapshot.logTail.map(stripProvenanceTag),
6427
- totalLogCount: snapshot.totalLogCount,
6428
- ...snapshot.logsTruncated ? { logsTruncated: true } : {},
6429
- activeArtifactTableNamespace: snapshot.activeArtifactTableNamespace ?? null,
6430
- resultTableNamespace: snapshot.resultTableNamespace ?? null,
6431
- datasets: snapshot.orderedDatasetIds.map((datasetId) => snapshot.datasetsById[datasetId]).filter(
6432
- (dataset) => Boolean(dataset)
6433
- ),
6434
- activities: snapshot.orderedActivityIds.map((activityId) => snapshot.activitiesById[activityId]).filter(
6435
- (activity) => Boolean(activity)
6436
- ),
6437
- activeActivity: snapshot.activeActivityId ? snapshot.activitiesById[snapshot.activeActivityId] ?? null : null,
6438
- nodeStates,
6439
- activeNodeId: snapshot.activeStepId ?? null,
6440
- ...rowOutcomes ? { rowOutcomes } : {},
6441
- ...calls && Object.values(calls).every(
6442
- (value) => typeof value === "boolean" || Number.isSafeInteger(value)
6443
- ) ? { calls } : {}
6444
- };
6445
- }
6446
- function buildPlayRunStatusSnapshot(input2) {
6447
- const ledgerSnapshot = normalizePlayRunLedgerSnapshot(input2.run.runSnapshot, {
6448
- runId: input2.run.workflowId,
6449
- playName: input2.run.name ?? null,
6450
- status: input2.run.status,
6451
- createdAt: input2.run.createdAt ?? null,
6452
- startedAt: input2.run.startedAt ?? null,
6453
- updatedAt: input2.run.updatedAt ?? null,
6454
- finishedAt: input2.run.finishedAt ?? null
6455
- });
6456
- const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
6457
- const projectedSnapshot = terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount ? buildSnapshotFromLedger({
6458
- ...ledgerSnapshot,
6459
- logTail: terminalRunLogTail.logTail,
6460
- totalLogCount: terminalRunLogTail.totalLogCount
6461
- }) : buildSnapshotFromLedger(ledgerSnapshot);
6462
- const activity = projectPlayRunActivity({
6463
- runId: input2.run.workflowId,
6464
- playName: input2.run.name,
6465
- status: projectedSnapshot.status,
6466
- updatedAt: projectedSnapshot.updatedAt,
6467
- waitKind: input2.run.waitKind ?? input2.run.wait?.kind ?? null,
6468
- waitUntil: input2.run.waitUntil,
6469
- eventKey: input2.run.wait?.eventKey ?? null,
6470
- runtimeBackend: input2.run.runtimeBackend,
6471
- activeNodeId: input2.run.activeBoundaryId ?? projectedSnapshot.activeNodeId,
6472
- nodeStates: projectedSnapshot.nodeStates,
6473
- datasets: projectedSnapshot.datasets,
6474
- explicit: projectedSnapshot.activities
6475
- });
6476
- return {
6477
- ...projectedSnapshot,
6478
- activity
6479
- };
6480
- }
6481
5334
  function makeRunStreamEvent(input2) {
6482
5335
  return {
6483
5336
  ...input2,
@@ -6560,7 +5413,7 @@ function diffLogLines(input2) {
6560
5413
  const missingCount = tailFirstSeq - 1 - input2.lastLogSeq;
6561
5414
  return {
6562
5415
  lines: [
6563
- `[stream] ${missingCount} log lines not retained in the live window; full logs via runs logs`,
5416
+ `[watch] ${missingCount} log lines not retained in the live window; full logs via runs logs`,
6564
5417
  ...logs
6565
5418
  ],
6566
5419
  lastLogSeq: totalLogCount,
@@ -6706,310 +5559,156 @@ function diffPlayRunStreamEvents(input2) {
6706
5559
  return { events, next };
6707
5560
  }
6708
5561
 
6709
- // src/runs/observe-transport.ts
6710
- var RunObserveTransportUnavailableError = class extends Error {
6711
- constructor(message, reason) {
6712
- super(message);
6713
- this.reason = reason;
6714
- this.name = "RunObserveTransportUnavailableError";
5562
+ // src/stream-reconnect.ts
5563
+ function isTransientPlayRunReadError(error) {
5564
+ if (error instanceof DeeplineError && error.code === "PLAY_STREAM_NETWORK_ABORTED") {
5565
+ return true;
6715
5566
  }
6716
- };
6717
- var OBSERVE_BOOTSTRAP_TIMEOUT_MS = 1e4;
6718
- var OBSERVE_RECONNECT_NOTICE_MS = 1e4;
6719
- var OBSERVE_STALE_WARNING_MS = 12e4;
6720
- var OBSERVE_WATCHDOG_TICK_MS = 5e3;
6721
- var GRANT_REFRESH_MARGIN_MS = 5 * 6e4;
6722
- var BACKFILL_PAGE_LIMIT = 1e3;
6723
- var BACKFILL_MAX_PAGES = 30;
6724
- var OBSERVER_SNAPSHOT_QUERY = "runObservers:getPlayRunSnapshotForObserver";
6725
- var OBSERVER_LOG_PAGE_QUERY = "runObservers:getRunLogPageForObserver";
6726
- function errorText(error) {
6727
- return error instanceof Error ? error.message : String(error);
5567
+ if (error instanceof DeeplineError && typeof error.statusCode === "number") {
5568
+ return error.statusCode >= 500 && error.statusCode < 600;
5569
+ }
5570
+ const text = error instanceof Error ? error.message : String(error);
5571
+ return /auth validation backend timed out|coordinator \/submit(?:\?[^ ]*)? 5\d\d|Worker threw exception|Internal Server Error|Service Unavailable|fetch failed|eaddrnotavail|econnreset|etimedout|eai_again|socket hang up/i.test(
5572
+ text
5573
+ );
6728
5574
  }
6729
- async function mintRunObserveGrant(http, runId) {
6730
- let response;
6731
- try {
6732
- response = await http.post(
6733
- `/api/v2/runs/${encodeURIComponent(runId)}/observe-grant`,
6734
- {}
6735
- );
6736
- } catch (error) {
6737
- if (error instanceof DeeplineError) {
6738
- if (error.statusCode === 401 || error.statusCode === 403) {
6739
- throw error;
6740
- }
6741
- throw new RunObserveTransportUnavailableError(
6742
- `observe-grant endpoint unavailable (${error.statusCode ?? "network"}): ${error.message}`,
6743
- "grant_endpoint_unavailable"
6744
- );
6745
- }
6746
- throw new RunObserveTransportUnavailableError(
6747
- `observe-grant request failed: ${errorText(error)}`,
6748
- "grant_request_failed"
6749
- );
5575
+
5576
+ // src/runs/watch-polling.ts
5577
+ var RUN_WATCH_POLL_INTERVAL_MS = 2e3;
5578
+ function waitForNextPoll(ms, signal) {
5579
+ if (signal?.aborted) {
5580
+ return Promise.resolve(false);
6750
5581
  }
6751
- const grant = response;
6752
- if (!grant || typeof grant.convexUrl !== "string" || !grant.convexUrl.trim() || typeof grant.token !== "string" || !grant.token.trim() || typeof grant.expiresAt !== "number") {
6753
- throw new RunObserveTransportUnavailableError(
6754
- "observe-grant endpoint returned an invalid grant payload.",
6755
- "grant_payload_invalid"
6756
- );
5582
+ return new Promise((resolve22) => {
5583
+ const finish = (elapsed) => {
5584
+ clearTimeout(timeout);
5585
+ signal?.removeEventListener("abort", onAbort);
5586
+ resolve22(elapsed);
5587
+ };
5588
+ const onAbort = () => finish(false);
5589
+ const timeout = setTimeout(() => finish(true), ms);
5590
+ signal?.addEventListener("abort", onAbort, { once: true });
5591
+ });
5592
+ }
5593
+ function readSnapshotResponse(response, runId) {
5594
+ if (!response || typeof response !== "object" || Array.isArray(response)) {
5595
+ throw new Error("Run watch returned an invalid snapshot response.");
5596
+ }
5597
+ const record3 = response;
5598
+ const snapshot = record3.snapshot;
5599
+ if (record3.runId !== runId || !snapshot || typeof snapshot !== "object" || Array.isArray(snapshot) || snapshot.runId !== runId || typeof snapshot.status !== "string" || !Array.isArray(snapshot.logs) || !snapshot.logs.every(
5600
+ (line) => typeof line === "string"
5601
+ ) || typeof snapshot.totalLogCount !== "number" || !Array.isArray(snapshot.nodeStates)) {
5602
+ throw new Error(`Run watch returned an invalid snapshot for ${runId}.`);
6757
5603
  }
6758
- return grant;
5604
+ return { runId, snapshot };
6759
5605
  }
6760
- async function backfillLogGap(input2) {
5606
+ async function backfillRotatedLogTail(input2) {
5607
+ if (!input2.previous.runSignature) {
5608
+ return input2.snapshot;
5609
+ }
5610
+ const gap = resolvePlayRunLogGap(input2.snapshot, input2.previous.lastLogSeq);
5611
+ if (!gap) {
5612
+ return input2.snapshot;
5613
+ }
6761
5614
  const lines = [];
6762
- let cursor = input2.lastLogSeq;
6763
- for (let page = 0; page < BACKFILL_MAX_PAGES; page += 1) {
6764
- if (cursor >= input2.tailFirstSeq - 1) {
6765
- break;
6766
- }
6767
- let logPage;
6768
- try {
6769
- logPage = await input2.queryLogPage(
6770
- cursor,
6771
- Math.min(BACKFILL_PAGE_LIMIT, input2.tailFirstSeq - 1 - cursor)
6772
- );
6773
- } catch {
6774
- return null;
6775
- }
6776
- const entries = (logPage?.entries ?? []).filter(
6777
- (entry) => entry.seq > cursor && entry.seq < input2.tailFirstSeq
5615
+ let cursor = input2.previous.lastLogSeq;
5616
+ const targetSeq = gap.tailFirstSeq - 1;
5617
+ while (cursor < targetSeq) {
5618
+ const limit = Math.min(1e3, targetSeq - cursor);
5619
+ const page = await input2.http.get(
5620
+ `/api/v2/runs/${encodeURIComponent(input2.runId)}/logs?afterSeq=${cursor}&limit=${limit}`,
5621
+ { signal: input2.signal }
6778
5622
  );
6779
- if (entries.length === 0) {
6780
- break;
5623
+ if (!page || !Array.isArray(page.entries) || page.entries.length === 0) {
5624
+ return input2.snapshot;
6781
5625
  }
6782
- for (const entry of entries) {
6783
- if (entry.seq !== cursor + 1) {
6784
- return null;
5626
+ for (const entry of page.entries) {
5627
+ if (!entry || entry.seq !== cursor + 1 || typeof entry.line !== "string") {
5628
+ return input2.snapshot;
6785
5629
  }
6786
5630
  lines.push(entry.line);
6787
5631
  cursor = entry.seq;
6788
5632
  }
6789
5633
  }
6790
- if (cursor < input2.tailFirstSeq - 1) {
6791
- return null;
5634
+ if (cursor !== targetSeq) {
5635
+ return input2.snapshot;
6792
5636
  }
6793
- return lines;
5637
+ return { ...input2.snapshot, logs: [...lines, ...input2.snapshot.logs] };
6794
5638
  }
6795
- async function* observeRunEvents(options) {
6796
- const { http, runId } = options;
6797
- let grant = await mintRunObserveGrant(http, runId);
6798
- let convexBrowser;
6799
- let convexServer;
6800
- try {
6801
- convexBrowser = await import("convex/browser");
6802
- convexServer = await import("convex/server");
6803
- } catch (error) {
6804
- throw new RunObserveTransportUnavailableError(
6805
- `convex client module unavailable: ${errorText(error)}`,
6806
- "convex_module_unavailable"
6807
- );
6808
- }
6809
- let webSocketConstructor;
6810
- if (typeof WebSocket === "undefined") {
5639
+ async function* watchRunEvents(options) {
5640
+ const { http, runId, signal } = options;
5641
+ const path = `/api/v2/runs/${encodeURIComponent(runId)}?watchSnapshot=true`;
5642
+ const streamId = `play-run-watch:${runId}`;
5643
+ const pollIntervalMs = options.pollIntervalMs ?? RUN_WATCH_POLL_INTERVAL_MS;
5644
+ let previous = EMPTY_PLAY_RUN_STREAM_DIFF_STATE;
5645
+ let consecutiveFailures = 0;
5646
+ let outageNoticeSent = false;
5647
+ while (!signal?.aborted) {
5648
+ const pollStartedAt = Date.now();
5649
+ let snapshot;
6811
5650
  try {
6812
- const wsModuleName = "ws";
6813
- const ws = await import(wsModuleName);
6814
- webSocketConstructor = ws.default;
6815
- } catch (error) {
6816
- throw new RunObserveTransportUnavailableError(
6817
- `no WebSocket implementation available: ${errorText(error)}`,
6818
- "websocket_unavailable"
6819
- );
6820
- }
6821
- }
6822
- const snapshotQuery = convexServer.makeFunctionReference(
6823
- OBSERVER_SNAPSHOT_QUERY
6824
- );
6825
- const logPageQuery = convexServer.makeFunctionReference(
6826
- OBSERVER_LOG_PAGE_QUERY
6827
- );
6828
- const client2 = new convexBrowser.ConvexClient(grant.convexUrl, {
6829
- ...webSocketConstructor ? { webSocketConstructor } : {},
6830
- unsavedChangesWarning: false
6831
- });
6832
- const queue = [];
6833
- let wake = null;
6834
- const push = (item) => {
6835
- queue.push(item);
6836
- wake?.();
6837
- wake = null;
6838
- };
6839
- let lastForcedRefreshAt = 0;
6840
- client2.setAuth(async ({ forceRefreshToken }) => {
6841
- const now = Date.now();
6842
- if (!forceRefreshToken && grant.expiresAt - now > GRANT_REFRESH_MARGIN_MS) {
6843
- return grant.token;
6844
- }
6845
- if (forceRefreshToken && now - lastForcedRefreshAt < 5e3) {
6846
- push({
6847
- kind: "error",
6848
- error: new DeeplineError(
6849
- `Run observe grant for ${runId} was rejected after a re-mint. The server and Convex deployment disagree on the grant issuer/JWKS.`,
6850
- 401,
6851
- "RUN_OBSERVE_GRANT_REJECTED"
6852
- )
5651
+ const response = await http.get(path, { signal });
5652
+ snapshot = await backfillRotatedLogTail({
5653
+ http,
5654
+ runId,
5655
+ snapshot: readSnapshotResponse(response, runId).snapshot,
5656
+ previous,
5657
+ signal
6853
5658
  });
6854
- return null;
6855
- }
6856
- if (forceRefreshToken) {
6857
- lastForcedRefreshAt = now;
6858
- }
6859
- try {
6860
- grant = await mintRunObserveGrant(http, runId);
6861
- return grant.token;
6862
5659
  } catch (error) {
6863
- push({ kind: "error", error });
6864
- return null;
6865
- }
6866
- });
6867
- const unsubscribe = client2.onUpdate(
6868
- snapshotQuery,
6869
- { workflowId: runId },
6870
- (run) => push({ kind: "run", run: run ?? null }),
6871
- (error) => push({ kind: "error", error })
6872
- );
6873
- let lastUpdateAt = Date.now();
6874
- let lastStatusTerminal = false;
6875
- let disconnectedSince = null;
6876
- let warnedReconnecting = false;
6877
- let warnedStale = false;
6878
- const watchdog = setInterval(() => {
6879
- const now = Date.now();
6880
- try {
6881
- const connectionState = client2.connectionState();
6882
- if (connectionState.isWebSocketConnected) {
6883
- disconnectedSince = null;
6884
- warnedReconnecting = false;
6885
- } else {
6886
- disconnectedSince ??= now;
6887
- if (!warnedReconnecting && now - disconnectedSince >= OBSERVE_RECONNECT_NOTICE_MS) {
6888
- warnedReconnecting = true;
6889
- options.onNotice?.(
6890
- `[observe] connection lost; reconnecting to live run ${runId}\u2026`
6891
- );
6892
- }
6893
- }
6894
- } catch {
6895
- }
6896
- if (!lastStatusTerminal && !warnedStale && now - lastUpdateAt >= OBSERVE_STALE_WARNING_MS) {
6897
- warnedStale = true;
6898
- options.onNotice?.(
6899
- `[observe] no live updates for ${Math.round((now - lastUpdateAt) / 1e3)}s; run ${runId} may be stalled (status checks continue)`
6900
- );
6901
- }
6902
- }, OBSERVE_WATCHDOG_TICK_MS);
6903
- watchdog.unref?.();
6904
- const abortListener = () => push({
6905
- kind: "error",
6906
- error: new DeeplineError(
6907
- "Run observation aborted.",
6908
- void 0,
6909
- "ABORTED"
6910
- )
6911
- });
6912
- options.signal?.addEventListener("abort", abortListener, { once: true });
6913
- let diffState = EMPTY_PLAY_RUN_STREAM_DIFF_STATE;
6914
- const streamId = ["observe", runId].join(":");
6915
- let sawFirstSnapshot = false;
6916
- try {
6917
- for (; ; ) {
6918
- if (queue.length === 0) {
6919
- const waitForItem = new Promise((resolve22) => {
6920
- wake = resolve22;
6921
- });
6922
- if (!sawFirstSnapshot) {
6923
- const timedOut = await Promise.race([
6924
- waitForItem.then(() => false),
6925
- new Promise(
6926
- (resolve22) => setTimeout(() => resolve22(true), OBSERVE_BOOTSTRAP_TIMEOUT_MS)
6927
- )
6928
- ]);
6929
- if (timedOut && queue.length === 0) {
6930
- throw new RunObserveTransportUnavailableError(
6931
- `no snapshot from Convex at ${grant.convexUrl} within ${OBSERVE_BOOTSTRAP_TIMEOUT_MS}ms`,
6932
- "convex_unreachable"
6933
- );
6934
- }
6935
- } else {
6936
- await waitForItem;
6937
- }
6938
- continue;
6939
- }
6940
- const item = queue.shift();
6941
- if (item.kind === "error") {
6942
- if (options.signal?.aborted) {
6943
- return;
6944
- }
6945
- throw item.error;
5660
+ if (signal?.aborted) {
5661
+ return;
6946
5662
  }
6947
- sawFirstSnapshot = true;
6948
- lastUpdateAt = Date.now();
6949
- warnedStale = false;
6950
- if (item.run === null) {
6951
- throw new DeeplineError(
6952
- `Run ${runId} was not found (or is not visible to this grant).`,
6953
- 404,
6954
- "RUN_NOT_FOUND"
6955
- );
5663
+ if (!isTransientPlayRunReadError(error)) {
5664
+ throw error;
6956
5665
  }
6957
- const snapshot = buildPlayRunStatusSnapshot({ run: item.run });
6958
- lastStatusTerminal = isTerminalPlayRunLiveStatus(snapshot.status);
6959
- const gap = resolvePlayRunLogGap(snapshot, diffState.lastLogSeq);
6960
- if (gap && diffState.lastLogSeq > 0) {
6961
- const backfilled = await backfillLogGap({
6962
- queryLogPage: (afterSeq, limit) => client2.query(logPageQuery, {
6963
- workflowId: runId,
6964
- afterSeq,
6965
- limit
6966
- }),
6967
- lastLogSeq: diffState.lastLogSeq,
6968
- tailFirstSeq: gap.tailFirstSeq
5666
+ consecutiveFailures += 1;
5667
+ const reason = error instanceof Error ? error.message : String(error);
5668
+ if (!outageNoticeSent) {
5669
+ options.onRetry?.({
5670
+ attempt: consecutiveFailures,
5671
+ delayMs: pollIntervalMs,
5672
+ reason
6969
5673
  });
6970
- if (backfilled && backfilled.length > 0) {
6971
- yield {
6972
- cursor: String(snapshot.updatedAt ?? Date.now()),
6973
- streamId,
6974
- scope: "play",
6975
- type: "play.run.log",
6976
- at: (/* @__PURE__ */ new Date()).toISOString(),
6977
- payload: {
6978
- runId: snapshot.runId,
6979
- lines: backfilled,
6980
- source: "worker",
6981
- firstSeq: diffState.lastLogSeq + 1,
6982
- totalLogCount: snapshot.totalLogCount
6983
- }
6984
- };
6985
- diffState = { ...diffState, lastLogSeq: gap.tailFirstSeq - 1 };
6986
- }
6987
- }
6988
- const { events, next } = diffPlayRunStreamEvents({
6989
- streamId,
6990
- snapshot,
6991
- previous: diffState
6992
- });
6993
- diffState = next;
6994
- const ordered = [
6995
- ...events.filter((event) => event.type === "play.run.snapshot"),
6996
- ...events.filter((event) => event.type !== "play.run.snapshot")
6997
- ];
6998
- for (const event of ordered) {
6999
- yield event;
5674
+ options.onNotice?.(
5675
+ `[watch] run snapshot request failed; retrying every ${pollIntervalMs / 1e3}s (${reason})`
5676
+ );
5677
+ outageNoticeSent = true;
7000
5678
  }
7001
- if (lastStatusTerminal) {
5679
+ const remaining2 = Math.max(
5680
+ 0,
5681
+ pollIntervalMs - (Date.now() - pollStartedAt)
5682
+ );
5683
+ if (!await waitForNextPoll(remaining2, signal)) {
7002
5684
  return;
7003
5685
  }
5686
+ continue;
7004
5687
  }
7005
- } finally {
7006
- clearInterval(watchdog);
7007
- options.signal?.removeEventListener("abort", abortListener);
7008
- try {
7009
- unsubscribe();
7010
- } catch {
5688
+ if (outageNoticeSent) {
5689
+ options.onNotice?.("[watch] run snapshot polling recovered");
5690
+ outageNoticeSent = false;
5691
+ }
5692
+ consecutiveFailures = 0;
5693
+ const diff = diffPlayRunStreamEvents({
5694
+ streamId,
5695
+ snapshot,
5696
+ previous
5697
+ });
5698
+ previous = diff.next;
5699
+ for (const event of diff.events) {
5700
+ yield event;
5701
+ }
5702
+ if (isTerminalPlayRunLiveStatus(snapshot.status)) {
5703
+ return;
5704
+ }
5705
+ const remaining = Math.max(
5706
+ 0,
5707
+ pollIntervalMs - (Date.now() - pollStartedAt)
5708
+ );
5709
+ if (!await waitForNextPoll(remaining, signal)) {
5710
+ return;
7011
5711
  }
7012
- await client2.close().catch(() => void 0);
7013
5712
  }
7014
5713
  }
7015
5714
 
@@ -7340,7 +6039,7 @@ function requireTargetBillingIdempotencyKey(value) {
7340
6039
  }
7341
6040
  return normalized;
7342
6041
  }
7343
- function isRecord8(value) {
6042
+ function isRecord4(value) {
7344
6043
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
7345
6044
  }
7346
6045
  function isPrebuiltPlayDescription(play) {
@@ -7372,10 +6071,10 @@ function normalizePlayStatus(raw) {
7372
6071
  return {
7373
6072
  ...raw,
7374
6073
  runId,
7375
- ...isRecord8(legacyOverview) ? {
6074
+ ...isRecord4(legacyOverview) ? {
7376
6075
  overview: legacyOverview
7377
6076
  } : {},
7378
- ...isRecord8(runStatus) ? { runStatus } : {},
6077
+ ...isRecord4(runStatus) ? { runStatus } : {},
7379
6078
  ...runPackage ? {
7380
6079
  package: runPackage,
7381
6080
  outputs: runPackage.outputs
@@ -7514,7 +6213,7 @@ function updatePlayLiveStatusState(state, event) {
7514
6213
  }
7515
6214
  const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
7516
6215
  const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
7517
- const progressPayload = isRecord8(payload.progress) ? payload.progress : {};
6216
+ const progressPayload = isRecord4(payload.progress) ? payload.progress : {};
7518
6217
  if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
7519
6218
  const payloadLogs = readStringArray(payload.logs);
7520
6219
  const progressLogs = readStringArray(progressPayload.logs);
@@ -7593,6 +6292,7 @@ var DeeplineClient = class _DeeplineClient {
7593
6292
  status: (runId) => this.getRunLifecycleStatus(runId),
7594
6293
  list: (options2) => this.listRuns(options2),
7595
6294
  listPage: (options2) => this.listRunsPage(options2),
6295
+ watch: (runId, options2) => this.watchRunToTerminal(runId, options2),
7596
6296
  tail: (runId, options2) => this.tailRun(runId, options2),
7597
6297
  logs: (runId, options2) => this.getRunLogs(runId, options2),
7598
6298
  input: (runId) => this.getRunInput(runId),
@@ -7715,9 +6415,9 @@ var DeeplineClient = class _DeeplineClient {
7715
6415
  return fields2.length > 0 ? { fields: fields2 } : schema;
7716
6416
  }
7717
6417
  schemaMetadata(schema, key) {
7718
- if (!isRecord8(schema)) return null;
6418
+ if (!isRecord4(schema)) return null;
7719
6419
  const value = schema[key];
7720
- return isRecord8(value) ? value : null;
6420
+ return isRecord4(value) ? value : null;
7721
6421
  }
7722
6422
  playRunCommand(play, options) {
7723
6423
  const target = play.reference || play.name;
@@ -7772,7 +6472,7 @@ var DeeplineClient = class _DeeplineClient {
7772
6472
  aliases,
7773
6473
  inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
7774
6474
  outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
7775
- staticPipeline: isRecord8(play.staticPipeline) ? play.staticPipeline : isRecord8(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord8(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
6475
+ staticPipeline: isRecord4(play.staticPipeline) ? play.staticPipeline : isRecord4(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord4(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
7776
6476
  ...csvInput ? { csvInput } : {},
7777
6477
  ...rowOutputSchema ? { rowOutputSchema } : {},
7778
6478
  runCommand: runCommand2,
@@ -8132,15 +6832,17 @@ var DeeplineClient = class _DeeplineClient {
8132
6832
  return normalizePlayRunStart(response);
8133
6833
  }
8134
6834
  /**
8135
- * Start a play run and stream live runtime events from the same request.
6835
+ * Submit a play run through the legacy event response.
8136
6836
  *
8137
- * Use this when a caller wants low-level event handling instead of submitting
8138
- * first and then connecting to `streamPlayRunEvents(runId)`.
6837
+ * This reports admission from the start request; it does not watch an
6838
+ * existing run. Use `startPlayRun()` and `watchRunEvents(runId)` separately.
6839
+ *
6840
+ * @deprecated Use the separate start and watch methods.
8139
6841
  *
8140
6842
  * @param request - Play run configuration.
8141
- * @param options - Optional streaming options.
8142
- * @param options.signal - Optional abort signal for the streaming request.
8143
- * @returns Async stream of play-scoped live events.
6843
+ * @param options - Optional compatibility response options.
6844
+ * @param options.signal - Abort the start response.
6845
+ * @returns Async generator of play-scoped live events.
8144
6846
  */
8145
6847
  async *startPlayRunStream(request, options) {
8146
6848
  const integrationMode = resolvePlayRunIntegrationMode(request);
@@ -8622,11 +7324,23 @@ var DeeplineClient = class _DeeplineClient {
8622
7324
  );
8623
7325
  return normalizePlayStatus(response);
8624
7326
  }
7327
+ /** Poll authenticated run snapshots every two seconds and emit changed events. */
7328
+ async *watchRunEvents(workflowId, options) {
7329
+ for await (const event of watchRunEvents({
7330
+ http: this.http,
7331
+ runId: workflowId,
7332
+ signal: options?.signal,
7333
+ onNotice: options?.onNotice,
7334
+ onRetry: options?.onRetry
7335
+ })) {
7336
+ yield event;
7337
+ }
7338
+ }
8625
7339
  /**
8626
- * Stream semantic play-run events using the same SSE feed as the dashboard.
7340
+ * Read raw legacy SSE events for callers that explicitly require that
7341
+ * compatibility endpoint. Ordinary run watching uses REST snapshot polling.
8627
7342
  *
8628
- * The server emits a canonical `play.run.snapshot` event first for every
8629
- * connection, then incremental live events until terminal state or reconnect.
7343
+ * @deprecated Use `watchRunEvents` for ordinary run watching.
8630
7344
  */
8631
7345
  async *streamPlayRunEvents(workflowId, options) {
8632
7346
  const headers = options?.lastEventId && options.lastEventId.trim() ? { "Last-Event-ID": options.lastEventId.trim() } : void 0;
@@ -8641,6 +7355,68 @@ var DeeplineClient = class _DeeplineClient {
8641
7355
  }
8642
7356
  }
8643
7357
  }
7358
+ /**
7359
+ * Compatibility alias for polling canonical run snapshots and emitting
7360
+ * their changed events.
7361
+ *
7362
+ * @deprecated Use `watchRunEvents`; kept as a source-compatible alias.
7363
+ * The `fallback` option is ignored because watching uses REST polling.
7364
+ */
7365
+ async *observeRunEvents(runId, options) {
7366
+ yield* this.watchRunEvents(runId, {
7367
+ signal: options?.signal,
7368
+ onNotice: options?.onNotice
7369
+ });
7370
+ }
7371
+ /** Poll snapshots to terminal status and return the durable package. */
7372
+ async watchRunToTerminal(runId, options) {
7373
+ const state = {
7374
+ runId,
7375
+ status: "running",
7376
+ logs: [],
7377
+ lastLogSeq: 0,
7378
+ latest: null
7379
+ };
7380
+ let terminalObserved = false;
7381
+ for await (const event of this.watchRunEvents(runId, {
7382
+ signal: options?.signal,
7383
+ onNotice: options?.onNotice,
7384
+ onRetry: options?.onRetry ?? options?.onReconnect
7385
+ })) {
7386
+ options?.onEvent?.(event);
7387
+ const status = updatePlayLiveStatusState(state, event);
7388
+ if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
7389
+ terminalObserved = true;
7390
+ }
7391
+ }
7392
+ if (options?.signal?.aborted) {
7393
+ throw new DeeplineError("Run watch aborted.", void 0, "ABORTED");
7394
+ }
7395
+ if (terminalObserved) {
7396
+ return await this.getRunStatus(runId);
7397
+ }
7398
+ const refreshed = await this.getRunStatus(runId);
7399
+ if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) return refreshed;
7400
+ throw new DeeplineError(
7401
+ `Run watch for ${runId} ended before a terminal status.`,
7402
+ void 0,
7403
+ "PLAY_WATCH_ENDED"
7404
+ );
7405
+ }
7406
+ /**
7407
+ * Wait for a run and return its terminal status.
7408
+ *
7409
+ * This source-compatible alias uses the same authenticated two-second REST
7410
+ * snapshot polling as `client.runs.watch`.
7411
+ *
7412
+ * @deprecated Use `client.runs.watch`; retained for SDK compatibility.
7413
+ * @param runId - Public Deepline play-run id.
7414
+ * @param options - Optional callbacks and cancellation signal.
7415
+ * @returns The final durable run status.
7416
+ */
7417
+ async tailRun(runId, options) {
7418
+ return this.watchRunToTerminal(runId, options);
7419
+ }
8644
7420
  /**
8645
7421
  * Cancel a running play execution.
8646
7422
  *
@@ -8804,10 +7580,10 @@ var DeeplineClient = class _DeeplineClient {
8804
7580
  const responseRunStatus = isPlayRunPackage(response) ? response.runStatus : isPlayRunPackage(response.package) ? response.package.runStatus : response.runStatus;
8805
7581
  const responseOverview = isPlayRunPackage(response) ? response.overview : isPlayRunPackage(response.package) ? response.package.overview : response.overview;
8806
7582
  const status = normalizePlayStatus(response);
8807
- if (isRecord8(responseRunStatus)) {
7583
+ if (isRecord4(responseRunStatus)) {
8808
7584
  status.runStatus = responseRunStatus;
8809
7585
  }
8810
- if (isRecord8(responseOverview)) {
7586
+ if (isRecord4(responseOverview)) {
8811
7587
  status.overview = responseOverview;
8812
7588
  }
8813
7589
  if (options?.failedLogs !== true || status.status !== "failed") {
@@ -8906,222 +7682,6 @@ var DeeplineClient = class _DeeplineClient {
8906
7682
  );
8907
7683
  return { ...response, runs: response.runs ?? [] };
8908
7684
  }
8909
- /**
8910
- * Observe one run's live events. Uses the Convex Run Snapshot subscription
8911
- * transport first (ADR-0008), then falls back to the canonical SSE stream
8912
- * when the subscription transport or its optional client modules are not
8913
- * available. Pass `fallback: 'none'` to receive
8914
- * {@link RunObserveTransportUnavailableError} instead.
8915
- */
8916
- async *observeRunEvents(runId, options) {
8917
- let yieldedObserveEvent = false;
8918
- try {
8919
- for await (const event of observeRunEvents({
8920
- http: this.http,
8921
- runId,
8922
- signal: options?.signal,
8923
- onNotice: options?.onNotice
8924
- })) {
8925
- yieldedObserveEvent = true;
8926
- yield event;
8927
- }
8928
- } catch (error) {
8929
- if (!(error instanceof RunObserveTransportUnavailableError) || yieldedObserveEvent || options?.fallback === "none") {
8930
- throw error;
8931
- }
8932
- options?.onNotice?.(
8933
- `[observe] live subscription unavailable (${error.reason}); falling back to SSE tail (support window, ADR-0008)`
8934
- );
8935
- yield* this.streamPlayRunEventsUntilTerminal(runId, options);
8936
- }
8937
- }
8938
- async *streamPlayRunEventsUntilTerminal(runId, options) {
8939
- const state = {
8940
- runId,
8941
- status: "running",
8942
- logs: [],
8943
- lastLogSeq: 0,
8944
- latest: null
8945
- };
8946
- let lastEventId;
8947
- let reconnectAttempt = 0;
8948
- for (; ; ) {
8949
- if (options?.signal?.aborted) {
8950
- return;
8951
- }
8952
- const connectedAt = Date.now();
8953
- let sawEvent = false;
8954
- let endedReason = "stream window ended before a terminal event";
8955
- try {
8956
- for await (const event of this.streamPlayRunEvents(runId, {
8957
- mode: "cli",
8958
- signal: options?.signal,
8959
- ...lastEventId ? { lastEventId } : {}
8960
- })) {
8961
- sawEvent = true;
8962
- if (event.cursor?.trim()) {
8963
- lastEventId = event.cursor;
8964
- }
8965
- yield event;
8966
- const status = updatePlayLiveStatusState(state, event);
8967
- if (status && TERMINAL_PLAY_STATUSES.has(status.status)) {
8968
- return;
8969
- }
8970
- }
8971
- } catch (error) {
8972
- if (options?.signal?.aborted) {
8973
- return;
8974
- }
8975
- if (!isTransientPlayStreamError(error)) {
8976
- throw error;
8977
- }
8978
- endedReason = error instanceof Error ? error.message : String(error);
8979
- }
8980
- let refreshed = null;
8981
- try {
8982
- refreshed = await this.getRunStatus(runId);
8983
- } catch (error) {
8984
- if (!isTransientPlayStreamError(error)) {
8985
- throw error;
8986
- }
8987
- }
8988
- if (refreshed && TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
8989
- yield {
8990
- cursor: String(Date.now()),
8991
- streamId: `sse-fallback:${runId}`,
8992
- scope: "play",
8993
- type: "play.run.status",
8994
- at: (/* @__PURE__ */ new Date()).toISOString(),
8995
- payload: refreshed
8996
- };
8997
- return;
8998
- }
8999
- if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
9000
- reconnectAttempt = 0;
9001
- }
9002
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
9003
- reconnectAttempt += 1;
9004
- options?.onNotice?.(
9005
- `[observe] SSE tail window ended before terminal status (${endedReason}); reconnecting to run ${runId}`
9006
- );
9007
- await sleep2(delayMs);
9008
- }
9009
- }
9010
- /**
9011
- * Tail one run through the subscription transport until terminal, then
9012
- * return one durable REST status read (the final Run Response Package).
9013
- */
9014
- async tailRunViaObserveTransport(runId, options) {
9015
- const state = {
9016
- runId,
9017
- status: "running",
9018
- logs: [],
9019
- lastLogSeq: 0,
9020
- latest: null
9021
- };
9022
- for await (const event of this.observeRunEvents(runId, {
9023
- signal: options?.signal,
9024
- onNotice: options?.onNotice,
9025
- fallback: "none"
9026
- })) {
9027
- options?.onEvent?.(event);
9028
- const status = updatePlayLiveStatusState(state, event);
9029
- if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
9030
- continue;
9031
- }
9032
- return await this.getRunStatus(status.runId || runId);
9033
- }
9034
- if (options?.signal?.aborted) {
9035
- throw new DeeplineError("Run observation aborted.", void 0, "ABORTED");
9036
- }
9037
- const refreshed = await this.getRunStatus(runId);
9038
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
9039
- return refreshed;
9040
- }
9041
- throw new DeeplineError(
9042
- `Run observation for ${runId} ended before a terminal status.`,
9043
- void 0,
9044
- "PLAY_LIVE_STREAM_ENDED"
9045
- );
9046
- }
9047
- /**
9048
- * Read the canonical run stream until a terminal run status is observed.
9049
- *
9050
- * Tries the Convex Run Snapshot subscription transport first (ADR-0008);
9051
- * when the server cannot serve it (grant endpoint missing/unconfigured or
9052
- * Convex unreachable) it falls back — with one `onNotice` message — to the
9053
- * support-window SSE stream below.
9054
- *
9055
- * Server stream windows are finite: they end cleanly at the function
9056
- * ceiling even while the run keeps executing. A window that ends (cleanly
9057
- * or via transient network error) without a terminal event triggers one
9058
- * durable-status re-check followed by a backed-off reconnect, so long runs
9059
- * tail to completion. Abort via `options.signal` to stop waiting.
9060
- */
9061
- async tailRun(runId, options) {
9062
- try {
9063
- return await this.tailRunViaObserveTransport(runId, options);
9064
- } catch (error) {
9065
- if (!(error instanceof RunObserveTransportUnavailableError)) {
9066
- throw error;
9067
- }
9068
- options?.onNotice?.(
9069
- `[observe] live subscription unavailable (${error.reason}); falling back to SSE tail (support window, ADR-0008)`
9070
- );
9071
- }
9072
- const state = {
9073
- runId,
9074
- status: "running",
9075
- logs: [],
9076
- lastLogSeq: 0,
9077
- latest: null
9078
- };
9079
- let reconnectAttempt = 0;
9080
- for (; ; ) {
9081
- const connectedAt = Date.now();
9082
- let sawEvent = false;
9083
- let terminalRunId = null;
9084
- let endedReason = "stream window ended before a terminal event";
9085
- try {
9086
- for await (const event of this.streamPlayRunEvents(runId, {
9087
- mode: "cli",
9088
- signal: options?.signal
9089
- })) {
9090
- options?.onEvent?.(event);
9091
- sawEvent = true;
9092
- const status = updatePlayLiveStatusState(state, event);
9093
- if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
9094
- continue;
9095
- }
9096
- terminalRunId = status.runId || runId;
9097
- break;
9098
- }
9099
- } catch (error) {
9100
- if (options?.signal?.aborted || !isTransientPlayStreamError(error)) {
9101
- throw error;
9102
- }
9103
- endedReason = error instanceof Error ? error.message : String(error);
9104
- }
9105
- if (terminalRunId) {
9106
- return await this.getRunStatus(terminalRunId);
9107
- }
9108
- const refreshed = await this.getRunStatus(runId);
9109
- if (TERMINAL_PLAY_STATUSES.has(refreshed.status)) {
9110
- return refreshed;
9111
- }
9112
- if (sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
9113
- reconnectAttempt = 0;
9114
- }
9115
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
9116
- reconnectAttempt += 1;
9117
- options?.onReconnect?.({
9118
- attempt: reconnectAttempt,
9119
- delayMs,
9120
- reason: endedReason
9121
- });
9122
- await sleep2(delayMs);
9123
- }
9124
- }
9125
7685
  /** Get the exact original input retained for a run. This is intentionally separate from status. */
9126
7686
  async getRunInput(runId) {
9127
7687
  return this.http.get(`/api/v2/runs/${encodeURIComponent(runId)}/input`);
@@ -9912,10 +8472,10 @@ var DeeplineClient = class _DeeplineClient {
9912
8472
  // Plays — high-level orchestration
9913
8473
  // ——————————————————————————————————————————————————————————
9914
8474
  /**
9915
- * Run a play end-to-end: submit, stream until terminal, return result.
8475
+ * Run a play end-to-end: submit, poll progress until terminal, return result.
9916
8476
  *
9917
8477
  * This is the highest-level play execution method. It submits the play,
9918
- * reads the canonical run stream for status updates, and returns a structured
8478
+ * reads the canonical run snapshot for status updates, and returns a structured
9919
8479
  * result with logs and timing. Supports cancellation via `AbortSignal`.
9920
8480
  *
9921
8481
  * @param code - Source string fallback; pass the bundled artifact in `options.artifact`
@@ -9971,6 +8531,7 @@ var DeeplineClient = class _DeeplineClient {
9971
8531
  lastLogSeq: 0,
9972
8532
  latest: null
9973
8533
  };
8534
+ let terminalObserved = null;
9974
8535
  if (options?.signal?.aborted) {
9975
8536
  await this.cancelPlay(workflowId);
9976
8537
  return {
@@ -9981,8 +8542,7 @@ var DeeplineClient = class _DeeplineClient {
9981
8542
  error: "Cancelled by user"
9982
8543
  };
9983
8544
  }
9984
- for await (const event of this.streamPlayRunEvents(workflowId, {
9985
- mode: "cli",
8545
+ for await (const event of this.watchRunEvents(workflowId, {
9986
8546
  signal: options?.signal
9987
8547
  })) {
9988
8548
  if (options?.signal?.aborted) {
@@ -9995,20 +8555,36 @@ var DeeplineClient = class _DeeplineClient {
9995
8555
  error: "Cancelled by user"
9996
8556
  };
9997
8557
  }
8558
+ const previousStatus = state.latest?.status;
9998
8559
  const status = updatePlayLiveStatusState(state, event);
9999
8560
  if (!status) {
10000
8561
  continue;
10001
8562
  }
10002
- options?.onProgress?.(status);
8563
+ if (event.type !== "play.run.status" || status.status !== previousStatus) {
8564
+ options?.onProgress?.(status);
8565
+ }
10003
8566
  if (TERMINAL_PLAY_STATUSES.has(status.status)) {
10004
- const finalStatus = await this.getPlayStatus(
10005
- status.runId || workflowId
10006
- ).catch(() => status);
10007
- return playRunResultFromStatus(finalStatus, start, workflowId);
8567
+ terminalObserved = status;
10008
8568
  }
10009
8569
  }
8570
+ if (options?.signal?.aborted) {
8571
+ await this.cancelPlay(workflowId);
8572
+ return {
8573
+ success: false,
8574
+ runId: workflowId,
8575
+ logs: state.logs,
8576
+ durationMs: Date.now() - start,
8577
+ error: "Cancelled by user"
8578
+ };
8579
+ }
8580
+ if (terminalObserved) {
8581
+ const finalStatus = await this.getPlayStatus(
8582
+ terminalObserved.runId || workflowId
8583
+ ).catch(() => terminalObserved);
8584
+ return playRunResultFromStatus(finalStatus, start, workflowId);
8585
+ }
10010
8586
  throw new DeeplineError(
10011
- `Run stream for ${workflowId} ended before the run reached a terminal state.`,
8587
+ `Run watch for ${workflowId} ended before the run reached a terminal state.`,
10012
8588
  void 0,
10013
8589
  "PLAY_RUN_STREAM_ENDED",
10014
8590
  { runId: workflowId, workflowId }
@@ -14660,24 +13236,24 @@ function sanitizeCsvProjectionInfo(input2) {
14660
13236
  const rows = input2.rows.map(stripCsvProjectionFields);
14661
13237
  return { rows, columns };
14662
13238
  }
14663
- function isRecord9(value) {
13239
+ function isRecord5(value) {
14664
13240
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
14665
13241
  }
14666
13242
  function isSerializedDataset(value) {
14667
- return isRecord9(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
13243
+ return isRecord5(value) && value.kind === "dataset" && typeof value.count === "number" && (Array.isArray(value.preview) || typeof value.tableNamespace === "string");
14668
13244
  }
14669
13245
  function isPackagedDatasetOutput(value) {
14670
- return isRecord9(value) && value.kind === "dataset" && isRecord9(value.preview) && Array.isArray(value.preview.rows);
13246
+ return isRecord5(value) && value.kind === "dataset" && isRecord5(value.preview) && Array.isArray(value.preview.rows);
14671
13247
  }
14672
13248
  function hasCurrentTableExport(value) {
14673
- if (!isRecord9(value) || !isRecord9(value.actions)) return false;
13249
+ if (!isRecord5(value) || !isRecord5(value.actions)) return false;
14674
13250
  const exportCsv = value.actions.exportCsv;
14675
- return isRecord9(exportCsv) && isRecord9(exportCsv.scope) && exportCsv.scope.kind === "database" && exportCsv.scope.mutability === "current";
13251
+ return isRecord5(exportCsv) && isRecord5(exportCsv.scope) && exportCsv.scope.kind === "database" && exportCsv.scope.mutability === "current";
14676
13252
  }
14677
13253
  function currentTableQueryCommand(value) {
14678
- if (!isRecord9(value) || !isRecord9(value.actions)) return void 0;
13254
+ if (!isRecord5(value) || !isRecord5(value.actions)) return void 0;
14679
13255
  const query = value.actions.queryCurrentTable;
14680
- const command = isRecord9(query) ? query.command : void 0;
13256
+ const command = isRecord5(query) ? query.command : void 0;
14681
13257
  return typeof command === "string" && command.trim() ? command.trim() : void 0;
14682
13258
  }
14683
13259
  function recoveredReturnPaths(value) {
@@ -14696,7 +13272,7 @@ function pathParts(path) {
14696
13272
  function valueAtPath(root, path) {
14697
13273
  let cursor = root;
14698
13274
  for (const part of pathParts(path)) {
14699
- if (!isRecord9(cursor)) {
13275
+ if (!isRecord5(cursor)) {
14700
13276
  return void 0;
14701
13277
  }
14702
13278
  cursor = cursor[part];
@@ -14704,17 +13280,17 @@ function valueAtPath(root, path) {
14704
13280
  return cursor;
14705
13281
  }
14706
13282
  function totalRowsForDataset(result, datasetPath) {
14707
- const metadata = isRecord9(result._metadata) ? result._metadata : null;
13283
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
14708
13284
  const parentPath = datasetPath.split(".").slice(0, -1).join(".");
14709
13285
  const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
14710
- return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord9(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
13286
+ return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord5(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
14711
13287
  }
14712
13288
  function rowArray(value) {
14713
13289
  if (!Array.isArray(value)) {
14714
13290
  return null;
14715
13291
  }
14716
13292
  const rows = value.filter(
14717
- (row) => isRecord9(row)
13293
+ (row) => isRecord5(row)
14718
13294
  );
14719
13295
  return rows.length === value.length ? rows : null;
14720
13296
  }
@@ -14738,7 +13314,7 @@ function inferColumns(rows) {
14738
13314
  return columns;
14739
13315
  }
14740
13316
  function columnsFromDatasetSummary(summary) {
14741
- if (!isRecord9(summary) || !isRecord9(summary.columnStats)) {
13317
+ if (!isRecord5(summary) || !isRecord5(summary.columnStats)) {
14742
13318
  return [];
14743
13319
  }
14744
13320
  return Object.keys(summary.columnStats).filter((column) => column);
@@ -14795,7 +13371,7 @@ function canonicalRowsInfoFromCandidate(input2) {
14795
13371
  candidate.value.recoveredReturnPaths
14796
13372
  )
14797
13373
  } : {},
14798
- ...isRecord9(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace" || candidate.value.exportUnavailable.reason === "returned_dataset_not_persisted") ? {
13374
+ ...isRecord5(candidate.value.exportUnavailable) && (candidate.value.exportUnavailable.reason === "empty_dataset" || candidate.value.exportUnavailable.reason === "shared_table_namespace" || candidate.value.exportUnavailable.reason === "returned_dataset_not_persisted") ? {
14799
13375
  exportUnavailableReason: candidate.value.exportUnavailable.reason,
14800
13376
  ...typeof candidate.value.exportUnavailable.message === "string" ? {
14801
13377
  exportUnavailableMessage: candidate.value.exportUnavailable.message
@@ -14843,7 +13419,7 @@ function collectDatasetCandidates(input2) {
14843
13419
  });
14844
13420
  return;
14845
13421
  }
14846
- if (!isRecord9(input2.value)) {
13422
+ if (!isRecord5(input2.value)) {
14847
13423
  return;
14848
13424
  }
14849
13425
  for (const [key, child] of Object.entries(input2.value)) {
@@ -14860,12 +13436,12 @@ function collectDatasetCandidates(input2) {
14860
13436
  }
14861
13437
  }
14862
13438
  function collectCanonicalRowsInfos(statusOrResult) {
14863
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
14864
- const result = isRecord9(root?.result) ? root.result : root;
13439
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
13440
+ const result = isRecord5(root?.result) ? root.result : root;
14865
13441
  if (!result) {
14866
13442
  return [];
14867
13443
  }
14868
- const metadata = isRecord9(result._metadata) ? result._metadata : null;
13444
+ const metadata = isRecord5(result._metadata) ? result._metadata : null;
14869
13445
  const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
14870
13446
  const candidates = [
14871
13447
  {
@@ -14889,8 +13465,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
14889
13465
  total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
14890
13466
  }
14891
13467
  ];
14892
- if (isRecord9(result.output)) {
14893
- const outputMetadata = isRecord9(result.output._metadata) ? result.output._metadata : null;
13468
+ if (isRecord5(result.output)) {
13469
+ const outputMetadata = isRecord5(result.output._metadata) ? result.output._metadata : null;
14894
13470
  const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
14895
13471
  candidates.push(
14896
13472
  {
@@ -14917,14 +13493,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
14917
13493
  }
14918
13494
  if (Array.isArray(result.steps)) {
14919
13495
  result.steps.forEach((step, index) => {
14920
- if (!isRecord9(step) || !isRecord9(step.output)) {
13496
+ if (!isRecord5(step) || !isRecord5(step.output)) {
14921
13497
  return;
14922
13498
  }
14923
13499
  const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
14924
13500
  candidates.push({
14925
13501
  source,
14926
13502
  value: step.output,
14927
- total: step.output.rowCount ?? (isRecord9(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord9(step.progress) ? step.progress.total : void 0)
13503
+ total: step.output.rowCount ?? (isRecord5(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord5(step.progress) ? step.progress.total : void 0)
14928
13504
  });
14929
13505
  });
14930
13506
  }
@@ -14952,15 +13528,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
14952
13528
  return infos;
14953
13529
  }
14954
13530
  function collectPackagedDatasetCandidates(statusOrResult) {
14955
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
13531
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
14956
13532
  if (!root) {
14957
13533
  return [];
14958
13534
  }
14959
- const pkg = isRecord9(root.package) ? root.package : root;
13535
+ const pkg = isRecord5(root.package) ? root.package : root;
14960
13536
  const datasets = Array.isArray(pkg.datasets) ? pkg.datasets : [];
14961
13537
  const candidates = [];
14962
13538
  for (const output2 of datasets) {
14963
- if (!isRecord9(output2) || !isPackagedDatasetOutput(output2)) {
13539
+ if (!isRecord5(output2) || !isPackagedDatasetOutput(output2)) {
14964
13540
  continue;
14965
13541
  }
14966
13542
  const source = typeof output2.path === "string" && output2.path.trim() ? output2.path.trim() : null;
@@ -14970,18 +13546,18 @@ function collectPackagedDatasetCandidates(statusOrResult) {
14970
13546
  candidates.push({
14971
13547
  source,
14972
13548
  value: output2,
14973
- total: output2.rowCount ?? (isRecord9(output2.preview) ? output2.preview.totalRows : void 0)
13549
+ total: output2.rowCount ?? (isRecord5(output2.preview) ? output2.preview.totalRows : void 0)
14974
13550
  });
14975
13551
  }
14976
13552
  return candidates;
14977
13553
  }
14978
13554
  function collectPackagedStepDatasetCandidates(statusOrResult) {
14979
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
13555
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
14980
13556
  if (!root) return [];
14981
- const pkg = isRecord9(root.package) ? root.package : root;
13557
+ const pkg = isRecord5(root.package) ? root.package : root;
14982
13558
  const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
14983
13559
  return steps.flatMap((step) => {
14984
- if (!isRecord9(step) || !isPackagedDatasetOutput(step.output)) return [];
13560
+ if (!isRecord5(step) || !isPackagedDatasetOutput(step.output)) return [];
14985
13561
  const source = typeof step.output.path === "string" && step.output.path.trim() ? step.output.path.trim() : null;
14986
13562
  return source ? [
14987
13563
  {
@@ -14993,8 +13569,8 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
14993
13569
  });
14994
13570
  }
14995
13571
  function collectSerializedDatasetRowsInfos(statusOrResult) {
14996
- const root = isRecord9(statusOrResult) ? statusOrResult : null;
14997
- const result = isRecord9(root?.result) ? root.result : root;
13572
+ const root = isRecord5(statusOrResult) ? statusOrResult : null;
13573
+ const result = isRecord5(root?.result) ? root.result : root;
14998
13574
  const candidates = [];
14999
13575
  if (result) {
15000
13576
  collectDatasetCandidates({
@@ -15002,7 +13578,7 @@ function collectSerializedDatasetRowsInfos(statusOrResult) {
15002
13578
  path: "result",
15003
13579
  output: candidates
15004
13580
  });
15005
- if (isRecord9(result.output)) {
13581
+ if (isRecord5(result.output)) {
15006
13582
  collectDatasetCandidates({
15007
13583
  value: result.output,
15008
13584
  path: "result",
@@ -15085,13 +13661,13 @@ function summarizeSampleValue(value, depth = 0) {
15085
13661
  if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
15086
13662
  if (depth >= 3) {
15087
13663
  if (Array.isArray(parsed)) return [];
15088
- if (isRecord9(parsed)) return {};
13664
+ if (isRecord5(parsed)) return {};
15089
13665
  return compactScalar(parsed);
15090
13666
  }
15091
13667
  if (Array.isArray(parsed)) {
15092
13668
  return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
15093
13669
  }
15094
- if (isRecord9(parsed)) {
13670
+ if (isRecord5(parsed)) {
15095
13671
  const out = {};
15096
13672
  for (const [key, nested] of Object.entries(parsed)) {
15097
13673
  if (["__dl", "meta", "metadata"].includes(key)) {
@@ -15122,7 +13698,7 @@ function compactCell(value) {
15122
13698
  }
15123
13699
  return `[${parsed.length} items]`;
15124
13700
  }
15125
- if (isRecord9(parsed)) {
13701
+ if (isRecord5(parsed)) {
15126
13702
  for (const key of ["matched_result", "output"]) {
15127
13703
  if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
15128
13704
  return compactCell(parsed[key]);
@@ -16556,17 +15132,17 @@ function parsePositiveInteger2(value, flagName) {
16556
15132
  }
16557
15133
  return parsed;
16558
15134
  }
16559
- function isRecord10(value) {
15135
+ function isRecord6(value) {
16560
15136
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
16561
15137
  }
16562
15138
  function stringValue(value) {
16563
15139
  return typeof value === "string" ? value.trim() : "";
16564
15140
  }
16565
15141
  function extractionEntries(value) {
16566
- if (Array.isArray(value)) return value.filter(isRecord10);
16567
- if (!isRecord10(value)) return [];
15142
+ if (Array.isArray(value)) return value.filter(isRecord6);
15143
+ if (!isRecord6(value)) return [];
16568
15144
  return Object.entries(value).map(
16569
- ([name, entry]) => isRecord10(entry) ? { name, ...entry } : { name }
15145
+ ([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
16570
15146
  );
16571
15147
  }
16572
15148
  var PlayBootstrapError = class extends Error {
@@ -17127,7 +15703,7 @@ function readCsvSampleRows(sample) {
17127
15703
  relax_column_count: true,
17128
15704
  trim: true
17129
15705
  });
17130
- return Array.isArray(parsedRows) ? parsedRows.filter(isRecord10) : [];
15706
+ return Array.isArray(parsedRows) ? parsedRows.filter(isRecord6) : [];
17131
15707
  }
17132
15708
  function readSourceCsvColumnSpecs(csvPath) {
17133
15709
  const sample = readCsvSample(csvPath);
@@ -17160,16 +15736,16 @@ function packagedCsvPathForPlay(csvPath) {
17160
15736
  return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
17161
15737
  }
17162
15738
  function getterNamesFromTool(tool, kind) {
17163
- const usageGuidance = isRecord10(tool?.usageGuidance) ? tool.usageGuidance : {};
17164
- const resultGuidance = isRecord10(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord10(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
15739
+ const usageGuidance = isRecord6(tool?.usageGuidance) ? tool.usageGuidance : {};
15740
+ const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
17165
15741
  const key = kind === "list" ? "extractedLists" : "extractedValues";
17166
15742
  const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
17167
15743
  return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
17168
15744
  }
17169
15745
  function targetGettersFromTool(tool) {
17170
- const record3 = isRecord10(tool) ? tool : {};
15746
+ const record3 = isRecord6(tool) ? tool : {};
17171
15747
  const raw = record3.targetGetters ?? record3.target_getters;
17172
- if (!isRecord10(raw)) return {};
15748
+ if (!isRecord6(raw)) return {};
17173
15749
  const entries = [];
17174
15750
  for (const [target, value] of Object.entries(raw)) {
17175
15751
  const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
@@ -17190,10 +15766,10 @@ function listRowCandidateKeysFromTool(tool) {
17190
15766
  return [...keys].sort();
17191
15767
  }
17192
15768
  function inputPropertyNames(schema) {
17193
- if (!isRecord10(schema)) return [];
17194
- if (isRecord10(schema.properties)) return Object.keys(schema.properties);
15769
+ if (!isRecord6(schema)) return [];
15770
+ if (isRecord6(schema.properties)) return Object.keys(schema.properties);
17195
15771
  if (Array.isArray(schema.fields)) {
17196
- return schema.fields.filter(isRecord10).map((field) => stringValue(field.name)).filter(Boolean);
15772
+ return schema.fields.filter(isRecord6).map((field) => stringValue(field.name)).filter(Boolean);
17197
15773
  }
17198
15774
  return [];
17199
15775
  }
@@ -17207,7 +15783,7 @@ function schemaFieldDetails(schema) {
17207
15783
  return { required, optional };
17208
15784
  }
17209
15785
  function jsonSchemaTypeExpression(schema) {
17210
- if (!isRecord10(schema)) return "unknown";
15786
+ if (!isRecord6(schema)) return "unknown";
17211
15787
  const type = schema.type;
17212
15788
  if (Array.isArray(type)) {
17213
15789
  return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
@@ -17237,7 +15813,7 @@ function jsonSchemaTypeExpression(schema) {
17237
15813
  }
17238
15814
  }
17239
15815
  function objectPropertySchema(schema, property) {
17240
- return isRecord10(schema) && isRecord10(schema.properties) ? schema.properties[property] : null;
15816
+ return isRecord6(schema) && isRecord6(schema.properties) ? schema.properties[property] : null;
17241
15817
  }
17242
15818
  function playOutputHasField(schema, field) {
17243
15819
  return objectPropertySchema(schema, field) != null;
@@ -17413,14 +15989,14 @@ ${indent2.slice(2)}}`;
17413
15989
  }
17414
15990
  function requiredPlayInputFields(play) {
17415
15991
  const schema = play?.inputSchema;
17416
- if (!isRecord10(schema)) return [];
15992
+ if (!isRecord6(schema)) return [];
17417
15993
  if (Array.isArray(schema.required)) {
17418
15994
  return schema.required.filter(
17419
15995
  (value) => typeof value === "string"
17420
15996
  );
17421
15997
  }
17422
15998
  if (Array.isArray(schema.fields)) {
17423
- return schema.fields.filter(isRecord10).filter(
15999
+ return schema.fields.filter(isRecord6).filter(
17424
16000
  (field) => field.required === true && typeof field.name === "string"
17425
16001
  ).map((field) => String(field.name));
17426
16002
  }
@@ -17601,7 +16177,7 @@ function validateBootstrapRoutes(input2) {
17601
16177
  }
17602
16178
  }
17603
16179
  function staticPipelineSubsteps(pipeline) {
17604
- if (!isRecord10(pipeline)) return [];
16180
+ if (!isRecord6(pipeline)) return [];
17605
16181
  return [
17606
16182
  ...extractionEntries(pipeline.stages),
17607
16183
  ...extractionEntries(pipeline.substeps)
@@ -17609,7 +16185,7 @@ function staticPipelineSubsteps(pipeline) {
17609
16185
  }
17610
16186
  function playUsesMapBackedRuntime(play) {
17611
16187
  const pipeline = play?.staticPipeline;
17612
- if (!isRecord10(pipeline)) return false;
16188
+ if (!isRecord6(pipeline)) return false;
17613
16189
  if (stringValue(pipeline.tableNamespace)) return true;
17614
16190
  return staticPipelineSubsteps(pipeline).some((substep) => {
17615
16191
  if (stringValue(substep.type) === "map") return true;
@@ -17618,7 +16194,7 @@ function playUsesMapBackedRuntime(play) {
17618
16194
  aliases: [],
17619
16195
  runCommand: "",
17620
16196
  examples: [],
17621
- staticPipeline: isRecord10(substep.pipeline) ? substep.pipeline : null
16197
+ staticPipeline: isRecord6(substep.pipeline) ? substep.pipeline : null
17622
16198
  });
17623
16199
  });
17624
16200
  }
@@ -22966,35 +21542,35 @@ async function runDeployment(params, hooks) {
22966
21542
  } catch (error) {
22967
21543
  if (revokedFinalStatus(error)) throw error;
22968
21544
  const body = error instanceof DeployApiError ? error.body : null;
22969
- const errorText2 = body?.error ?? (error instanceof Error ? error.message : String(error));
22970
- if (/PLAY_DEPLOYMENT_NOT_ACTIVE/.test(errorText2)) {
21545
+ const errorText = body?.error ?? (error instanceof Error ? error.message : String(error));
21546
+ if (/PLAY_DEPLOYMENT_NOT_ACTIVE/.test(errorText)) {
22971
21547
  console.info("[deploy-worker] cancelled at promote", {
22972
21548
  deploymentId: params.deploymentId
22973
21549
  });
22974
21550
  return { finalStatus: "cancelled", outcomes: [] };
22975
21551
  }
22976
- if (/PLAY_DEPLOYMENT_STALE/.test(errorText2)) {
21552
+ if (/PLAY_DEPLOYMENT_STALE/.test(errorText)) {
22977
21553
  console.info("[deploy-worker] superseded at promote", {
22978
21554
  deploymentId: params.deploymentId
22979
21555
  });
22980
21556
  await setStatus({
22981
21557
  status: "superseded",
22982
- error: errorText2.slice(0, 2e3),
21558
+ error: errorText.slice(0, 2e3),
22983
21559
  buildSeconds: buildSeconds()
22984
21560
  });
22985
21561
  return { finalStatus: "superseded", outcomes: [] };
22986
21562
  }
22987
21563
  return await failWithCheck({
22988
21564
  title: "Deploy failed during promotion",
22989
- summary: errorText2,
22990
- error: errorText2,
21565
+ summary: errorText,
21566
+ error: errorText,
22991
21567
  outcomes: [
22992
21568
  ...outcomes,
22993
21569
  ...(body?.outcomes ?? toPromote).map((entry) => ({
22994
21570
  name: entry.name,
22995
21571
  file: playByName.get(entry.name)?.file ?? entry.name,
22996
21572
  status: "failed",
22997
- error: ("error" in entry ? entry.error : void 0) ?? errorText2
21573
+ error: ("error" in entry ? entry.error : void 0) ?? errorText
22998
21574
  }))
22999
21575
  ]
23000
21576
  });
@@ -24869,7 +23445,7 @@ function playStatusErrorText(status) {
24869
23445
  function isRetryablePendingStartFailure(status) {
24870
23446
  if (status.status !== "failed") return false;
24871
23447
  if (status.runId && status.runId !== "pending") return false;
24872
- return isTransientPlayStreamError(new Error(playStatusErrorText(status)));
23448
+ return isTransientPlayRunReadError(new Error(playStatusErrorText(status)));
24873
23449
  }
24874
23450
  function pendingStartFailureStatus(input2) {
24875
23451
  const message = input2.error instanceof Error ? input2.error.message : String(input2.error);
@@ -25404,7 +23980,7 @@ function assertPlayWaitNotTimedOut(input2) {
25404
23980
  if (input2.waitTimeoutMs !== null && Date.now() - input2.startedAt >= input2.waitTimeoutMs) {
25405
23981
  const hasRealRunId = input2.workflowId.length > 0 && input2.workflowId !== "pending";
25406
23982
  const phaseSuffix = input2.lastPhase && input2.lastPhase.trim() ? ` (last observed phase: ${input2.lastPhase.trim()})` : "";
25407
- const tailHint = hasRealRunId ? ` The CLI stopped waiting; it did not cancel the run. Check its current state with 'deepline runs get ${input2.workflowId} --json', or reattach with 'deepline runs tail ${input2.workflowId} --json'. Do not start another run just to retrieve results.` : ` No run id was received, so acceptance is unknown. Check recent runs with 'deepline runs list --play <play-name> --json' before submitting again.`;
23983
+ const tailHint = hasRealRunId ? ` The CLI stopped waiting; it did not cancel the run. Check its current state with 'deepline runs get ${input2.workflowId} --json', or reattach with 'deepline runs watch ${input2.workflowId} --json'. Do not start another run just to retrieve results.` : ` No run id was received, so acceptance is unknown. Check recent runs with 'deepline runs list --play <play-name> --json' before submitting again.`;
25408
23984
  throw new DeeplineError(
25409
23985
  `Timed out waiting for play ${hasRealRunId ? input2.workflowId : "<no run id>"} after ${Math.ceil(input2.waitTimeoutMs / 1e3)}s${phaseSuffix}.${tailHint}`,
25410
23986
  void 0,
@@ -25417,63 +23993,54 @@ function assertPlayWaitNotTimedOut(input2) {
25417
23993
  );
25418
23994
  }
25419
23995
  }
25420
- var PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS = 15e3;
23996
+ var RUN_WATCH_RETRY_INTERVAL_MS = 2e3;
25421
23997
  function isAdmittedRunVisibilityDelay(error) {
25422
23998
  return error instanceof DeeplineError && error.statusCode === 404 && error.message.trim() === "Workflow run not found.";
25423
23999
  }
25424
- async function waitForPlayCompletionByStream(input2) {
24000
+ async function waitForPlayCompletionByWatch(input2) {
25425
24001
  let lastPhase = null;
25426
- let reconnectAttempt = 0;
25427
- const durableStatusProbeIntervalMs = input2.durableStatusProbeIntervalMs ?? PLAY_DURABLE_STATUS_PROBE_INTERVAL_MS;
25428
- let nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
25429
- let durableStatusProbe = null;
25430
24002
  let admissionConfirmed = false;
24003
+ let visibilityNoticeSent = false;
24004
+ let terminalStatusRead = null;
24005
+ const controller = new AbortController();
24006
+ let timedOut = false;
24007
+ const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
24008
+ const remaining = remainingWaitMs();
24009
+ const timeout = remaining === null ? null : setTimeout(
24010
+ () => {
24011
+ timedOut = true;
24012
+ controller.abort();
24013
+ },
24014
+ Math.max(1, remaining)
24015
+ );
25431
24016
  const confirmAdmission = async () => {
25432
24017
  if (admissionConfirmed) return;
25433
24018
  admissionConfirmed = true;
25434
24019
  await input2.onRunAdmitted?.(input2.workflowId);
25435
24020
  };
25436
24021
  const withDashboardUrl = (status) => input2.dashboardUrl ? { ...status, dashboardUrl: input2.dashboardUrl } : status;
25437
- const remainingWaitMs = () => input2.waitTimeoutMs === null ? null : input2.waitTimeoutMs - (Date.now() - input2.startedAt);
25438
24022
  const fetchTerminalStatus = async () => {
25439
- if (durableStatusProbe) return durableStatusProbe;
25440
- const probe = (async () => {
25441
- let refreshed;
25442
- try {
25443
- refreshed = await input2.client.getPlayStatus(input2.workflowId, {
25444
- billing: false
25445
- });
25446
- } catch (error) {
25447
- if (isTransientPlayStreamError(error) || isAdmittedRunVisibilityDelay(error)) {
25448
- return null;
25449
- }
25450
- throw error;
25451
- }
25452
- if (refreshed.runId === input2.workflowId && statusProvesPlayRunExecution(refreshed.status)) {
25453
- await confirmAdmission();
25454
- }
25455
- return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
25456
- })();
25457
- durableStatusProbe = probe;
24023
+ let refreshed;
25458
24024
  try {
25459
- return await probe;
25460
- } finally {
25461
- if (durableStatusProbe === probe) durableStatusProbe = null;
24025
+ refreshed = await input2.client.getPlayStatus(input2.workflowId, {
24026
+ billing: false
24027
+ });
24028
+ } catch (error) {
24029
+ if (isTransientPlayRunReadError(error) || isAdmittedRunVisibilityDelay(error)) {
24030
+ return null;
24031
+ }
24032
+ throw error;
25462
24033
  }
24034
+ if (refreshed.runId === input2.workflowId && statusProvesPlayRunExecution(refreshed.status)) {
24035
+ await confirmAdmission();
24036
+ }
24037
+ return TERMINAL_PLAY_STATUSES2.has(refreshed.status) ? withDashboardUrl(refreshed) : null;
25463
24038
  };
25464
- const handleLiveEvent = async (event, probeDurableStatus) => {
24039
+ const handleLiveEvent = async (event) => {
25465
24040
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
25466
24041
  if (getRunIdFromLiveEvent(event) === input2.workflowId && (eventConfirmsPlayRunLaunch(event) || eventProvesPlayRunExecution(event))) {
25467
24042
  await confirmAdmission();
25468
24043
  }
25469
- const now = Date.now();
25470
- if (now >= nextDurableProbeAt) {
25471
- nextDurableProbeAt = now + durableStatusProbeIntervalMs;
25472
- const durableTerminal = await probeDurableStatus();
25473
- if (durableTerminal) {
25474
- return durableTerminal;
25475
- }
25476
- }
25477
24044
  const phase = describeLiveEventPhase(event);
25478
24045
  if (phase) {
25479
24046
  lastPhase = phase;
@@ -25524,144 +24091,57 @@ async function waitForPlayCompletionByStream(input2) {
25524
24091
  }
25525
24092
  }
25526
24093
  const finalStatus = getFinalStatusFromLiveEvent(event);
25527
- if (finalStatus) {
24094
+ if (event.type === "play.run.final_status" && finalStatus) {
25528
24095
  return withDashboardUrl(finalStatus);
25529
24096
  }
25530
24097
  const status = getStatusFromLiveEvent(event);
25531
24098
  if (status && TERMINAL_PLAY_STATUSES2.has(status)) {
25532
- const refreshedStatus = await probeDurableStatus();
25533
- if (refreshedStatus) return refreshedStatus;
24099
+ terminalStatusRead ??= fetchTerminalStatus();
24100
+ return await terminalStatusRead;
25534
24101
  }
25535
24102
  return null;
25536
24103
  };
25537
- const streamOneWindow = async () => {
25538
- const controller = new AbortController();
25539
- let timedOut = false;
25540
- let sawEvent = false;
25541
- let durableTerminal = null;
25542
- let durableProbeError = null;
25543
- let durableProbeTimer = null;
25544
- const remaining = remainingWaitMs();
25545
- const timeout = remaining === null ? null : setTimeout(
25546
- () => {
25547
- timedOut = true;
25548
- controller.abort();
25549
- },
25550
- Math.max(1, remaining)
25551
- );
25552
- const scheduleDurableStatusProbe = () => {
25553
- durableProbeTimer = setTimeout(() => {
25554
- durableProbeTimer = null;
25555
- if (controller.signal.aborted) return;
25556
- nextDurableProbeAt = Date.now() + durableStatusProbeIntervalMs;
25557
- void fetchTerminalStatus().then((status) => {
25558
- if (controller.signal.aborted) return;
25559
- if (status) {
25560
- durableTerminal = status;
25561
- controller.abort();
25562
- return;
25563
- }
25564
- scheduleDurableStatusProbe();
25565
- }).catch((error) => {
25566
- if (controller.signal.aborted) return;
25567
- durableProbeError = error;
25568
- controller.abort();
25569
- });
25570
- }, durableStatusProbeIntervalMs);
25571
- };
25572
- try {
25573
- scheduleDurableStatusProbe();
25574
- for await (const event of input2.client.streamPlayRunEvents(
25575
- input2.workflowId,
25576
- { signal: controller.signal }
25577
- )) {
25578
- sawEvent = true;
25579
- if (durableTerminal) {
25580
- return { kind: "terminal", status: durableTerminal };
24104
+ try {
24105
+ for (; ; ) {
24106
+ try {
24107
+ let terminalFromWatch = null;
24108
+ for await (const event of input2.client.watchRunEvents(
24109
+ input2.workflowId,
24110
+ { signal: controller.signal }
24111
+ )) {
24112
+ const terminal3 = await handleLiveEvent(event);
24113
+ if (terminal3) terminalFromWatch = terminal3;
25581
24114
  }
25582
- const terminal = await handleLiveEvent(event, fetchTerminalStatus);
25583
- if (terminal) {
25584
- return { kind: "terminal", status: terminal };
24115
+ if (terminalFromWatch) return terminalFromWatch;
24116
+ } catch (error) {
24117
+ if (timedOut || controller.signal.aborted) break;
24118
+ if (!isAdmittedRunVisibilityDelay(error)) throw error;
24119
+ if (!visibilityNoticeSent && !input2.jsonOutput) {
24120
+ input2.progress.writeLine(
24121
+ `[play watch] run is accepted and waiting for its snapshot; checking again in ${RUN_WATCH_RETRY_INTERVAL_MS / 1e3}s`
24122
+ );
24123
+ visibilityNoticeSent = true;
25585
24124
  }
25586
24125
  }
25587
- } catch (error) {
25588
- if (timedOut) {
25589
- return { kind: "timed_out", sawEvent };
25590
- }
25591
- if (durableTerminal) {
25592
- return { kind: "terminal", status: durableTerminal };
25593
- }
25594
- if (durableProbeError) {
25595
- throw durableProbeError;
25596
- }
25597
- if (!isTransientPlayStreamError(error) && !isAdmittedRunVisibilityDelay(error)) {
25598
- throw error;
25599
- }
25600
- return {
25601
- kind: "ended",
25602
- sawEvent,
25603
- reason: error instanceof Error ? error.message : String(error)
25604
- };
25605
- } finally {
25606
- if (timeout) {
25607
- clearTimeout(timeout);
25608
- }
25609
- if (durableProbeTimer) {
25610
- clearTimeout(durableProbeTimer);
25611
- }
25612
- controller.abort();
25613
- }
25614
- if (timedOut) {
25615
- return { kind: "timed_out", sawEvent };
25616
- }
25617
- if (durableTerminal) {
25618
- return { kind: "terminal", status: durableTerminal };
25619
- }
25620
- if (durableProbeError) {
25621
- throw durableProbeError;
25622
- }
25623
- return {
25624
- kind: "ended",
25625
- sawEvent,
25626
- reason: "stream window ended before a terminal event"
25627
- };
25628
- };
25629
- for (; ; ) {
25630
- const connectedAt = Date.now();
25631
- const window = await streamOneWindow();
25632
- if (window.kind === "terminal") {
25633
- return window.status;
24126
+ const terminal2 = await fetchTerminalStatus();
24127
+ if (terminal2) return terminal2;
24128
+ assertPlayWaitNotTimedOut({ ...input2, lastPhase });
24129
+ const nextWait = remainingWaitMs();
24130
+ await sleep5(
24131
+ nextWait === null ? RUN_WATCH_RETRY_INTERVAL_MS : Math.min(RUN_WATCH_RETRY_INTERVAL_MS, Math.max(1, nextWait))
24132
+ );
25634
24133
  }
25635
24134
  const terminal = await fetchTerminalStatus();
25636
- if (terminal) {
25637
- return terminal;
25638
- }
24135
+ if (terminal) return terminal;
25639
24136
  assertPlayWaitNotTimedOut({ ...input2, lastPhase });
25640
- if (window.sawEvent || Date.now() - connectedAt >= STREAM_HEALTHY_CONNECTION_MS) {
25641
- reconnectAttempt = 0;
25642
- }
25643
- const delayMs = streamReconnectDelayMs(reconnectAttempt);
25644
- reconnectAttempt += 1;
25645
- const reason = window.kind === "ended" ? window.reason : "wait timeout raced the stream";
25646
- if (!input2.jsonOutput) {
25647
- input2.progress.writeLine(
25648
- `[play watch] stream ended without a terminal status; reconnecting to run ${input2.workflowId} (${reason})`
25649
- );
25650
- }
25651
- recordCliTrace({
25652
- phase: "cli.play_tail_stream_reconnect",
25653
- ms: Date.now() - input2.startedAt,
25654
- ok: true,
25655
- playName: input2.playName,
25656
- workflowId: input2.workflowId,
25657
- attempt: reconnectAttempt,
25658
- delayMs,
25659
- reason
25660
- });
25661
- const remainingBeforeSleep = remainingWaitMs();
25662
- await sleep5(
25663
- remainingBeforeSleep === null ? delayMs : Math.min(delayMs, Math.max(1, remainingBeforeSleep))
24137
+ throw new DeeplineError(
24138
+ `Run watch for ${input2.workflowId} ended before a terminal status.`,
24139
+ void 0,
24140
+ "PLAY_WATCH_ENDED"
25664
24141
  );
24142
+ } finally {
24143
+ if (timeout) clearTimeout(timeout);
24144
+ controller.abort();
25665
24145
  }
25666
24146
  }
25667
24147
  async function startAndWaitForPlayCompletionByStream(input2) {
@@ -25738,7 +24218,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25738
24218
  billing: false
25739
24219
  });
25740
24220
  } catch (error) {
25741
- if (isTransientPlayStreamError(error)) {
24221
+ if (isTransientPlayRunReadError(error)) {
25742
24222
  return null;
25743
24223
  }
25744
24224
  throw error;
@@ -25909,7 +24389,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25909
24389
  firstRunIdMs,
25910
24390
  lastPhase
25911
24391
  });
25912
- return waitForPlayCompletionByStream({
24392
+ return waitForPlayCompletionByWatch({
25913
24393
  client: input2.client,
25914
24394
  playName: input2.playName,
25915
24395
  workflowId: lastKnownWorkflowId,
@@ -25948,7 +24428,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25948
24428
  lastPhase
25949
24429
  });
25950
24430
  }
25951
- if (lastKnownWorkflowId && isTransientPlayStreamError(error)) {
24431
+ if (lastKnownWorkflowId && isTransientPlayRunReadError(error)) {
25952
24432
  if (timeout) {
25953
24433
  clearTimeout(timeout);
25954
24434
  }
@@ -25970,7 +24450,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25970
24450
  lastPhase,
25971
24451
  reason
25972
24452
  });
25973
- return waitForPlayCompletionByStream({
24453
+ return waitForPlayCompletionByWatch({
25974
24454
  client: input2.client,
25975
24455
  playName: input2.playName,
25976
24456
  workflowId: lastKnownWorkflowId,
@@ -25984,7 +24464,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
25984
24464
  onRunAdmitted: confirmAdmission
25985
24465
  });
25986
24466
  }
25987
- if (!lastKnownWorkflowId && isTransientPlayStreamError(error)) {
24467
+ if (!lastKnownWorkflowId && isTransientPlayRunReadError(error)) {
25988
24468
  recordCliTrace({
25989
24469
  phase: "cli.play_start_stream_transient_failure",
25990
24470
  ms: Date.now() - startedAt,
@@ -26024,7 +24504,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
26024
24504
  lastPhase,
26025
24505
  reason: "stream ended before terminal event"
26026
24506
  });
26027
- return waitForPlayCompletionByStream({
24507
+ return waitForPlayCompletionByWatch({
26028
24508
  client: input2.client,
26029
24509
  playName: input2.playName,
26030
24510
  workflowId: lastKnownWorkflowId,
@@ -26041,7 +24521,7 @@ async function startAndWaitForPlayCompletionByStreamOnce(input2) {
26041
24521
  const phaseSuffix = lastPhase && lastPhase.trim() ? ` (last observed phase: ${lastPhase.trim()})` : "";
26042
24522
  const idSuffix = lastKnownWorkflowId ? ` runId=${lastKnownWorkflowId}` : "";
26043
24523
  throw new DeeplineError(
26044
- `Play start stream ended before a terminal status was observed${idSuffix}${phaseSuffix}. If a run id was printed, inspect it with 'deepline runs get <run-id> --full --json' or continue watching with 'deepline runs tail <run-id>'.`,
24524
+ `Play start request ended before terminal status was observed${idSuffix}${phaseSuffix}. If a run id was printed, inspect it with 'deepline runs get <run-id> --full --json' or continue watching with 'deepline runs watch <run-id>'.`,
26045
24525
  void 0,
26046
24526
  "PLAY_START_STREAM_ENDED",
26047
24527
  {
@@ -28154,7 +26634,7 @@ function extractPlayValidationErrors(value) {
28154
26634
  if (value instanceof DeeplineError) {
28155
26635
  return extractPlayValidationErrors(value.details);
28156
26636
  }
28157
- if (!isRecord11(value)) {
26637
+ if (!isRecord7(value)) {
28158
26638
  return [];
28159
26639
  }
28160
26640
  const directErrors = stringArrayField(value, "errors");
@@ -28550,7 +27030,7 @@ function parsePlayRunOptions(args) {
28550
27030
  }
28551
27031
  if (arg === "--poll-interval-ms" || arg === "--interval-ms") {
28552
27032
  throw new Error(
28553
- `${arg} was removed. --watch uses the canonical run stream directly.`
27033
+ `${arg} was removed. --watch polls the canonical run snapshot.`
28554
27034
  );
28555
27035
  }
28556
27036
  if ((arg === "--tail-timeout-ms" || arg === "--timeout-ms") && args[index + 1]) {
@@ -28818,7 +27298,7 @@ function formatPlayRuntimeLimit(runtimeLimit) {
28818
27298
  if (seconds % 60 === 0) return `${seconds / 60} min`;
28819
27299
  return `${seconds} sec`;
28820
27300
  }
28821
- function isRecord11(value) {
27301
+ function isRecord7(value) {
28822
27302
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
28823
27303
  }
28824
27304
  function stringValue3(value) {
@@ -28828,14 +27308,14 @@ function asArray(value) {
28828
27308
  return Array.isArray(value) ? value : [];
28829
27309
  }
28830
27310
  function extractionEntries2(value) {
28831
- if (Array.isArray(value)) return value.filter(isRecord11);
28832
- if (!isRecord11(value)) return [];
27311
+ if (Array.isArray(value)) return value.filter(isRecord7);
27312
+ if (!isRecord7(value)) return [];
28833
27313
  return Object.entries(value).map(
28834
- ([name, entry]) => isRecord11(entry) ? { name, ...entry } : { name }
27314
+ ([name, entry]) => isRecord7(entry) ? { name, ...entry } : { name }
28835
27315
  );
28836
27316
  }
28837
27317
  function firstRawPath(entry) {
28838
- const details = isRecord11(entry.details) ? entry.details : {};
27318
+ const details = isRecord7(entry.details) ? entry.details : {};
28839
27319
  const paths = [
28840
27320
  ...asArray(details.rawToolOutputPaths),
28841
27321
  ...asArray(details.raw_tool_output_paths),
@@ -28853,12 +27333,12 @@ function checkHintRawPath(value) {
28853
27333
  function collectStaticPipelineToolIds(staticPipeline) {
28854
27334
  const seen = /* @__PURE__ */ new Set();
28855
27335
  const visitPipeline = (pipeline) => {
28856
- if (!isRecord11(pipeline)) return;
27336
+ if (!isRecord7(pipeline)) return;
28857
27337
  for (const step of [
28858
27338
  ...asArray(pipeline.stages),
28859
27339
  ...asArray(pipeline.substeps)
28860
27340
  ]) {
28861
- if (!isRecord11(step)) continue;
27341
+ if (!isRecord7(step)) continue;
28862
27342
  if (step.type === "tool") {
28863
27343
  const toolId = stringValue3(step.toolId) || stringValue3(step.tool);
28864
27344
  if (toolId) seen.add(toolId);
@@ -28872,9 +27352,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
28872
27352
  return [...seen].sort();
28873
27353
  }
28874
27354
  function toolGetterHintFromMetadata(toolId, tool) {
28875
- const usageGuidance = isRecord11(tool.usageGuidance) ? tool.usageGuidance : {};
28876
- const resultGuidance = isRecord11(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord11(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
28877
- const toolResponse = isRecord11(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord11(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
27355
+ const usageGuidance = isRecord7(tool.usageGuidance) ? tool.usageGuidance : {};
27356
+ const resultGuidance = isRecord7(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord7(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
27357
+ const toolResponse = isRecord7(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord7(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
28878
27358
  const lists = extractionEntries2(
28879
27359
  resultGuidance.extractedLists ?? resultGuidance.extracted_lists
28880
27360
  ).map((entry) => ({
@@ -29237,7 +27717,7 @@ function artifactForProductionCompatibilityCheck(artifact) {
29237
27717
  "DEEPLINE_PROD_CHECK_AUTHORING_CONTRACT_EDITION must be a positive integer."
29238
27718
  );
29239
27719
  }
29240
- const compatibility = isRecord11(artifact.compatibility) ? artifact.compatibility : {};
27720
+ const compatibility = isRecord7(artifact.compatibility) ? artifact.compatibility : {};
29241
27721
  return {
29242
27722
  ...artifact,
29243
27723
  compatibility: {
@@ -30137,7 +28617,7 @@ Active runs: ${next.running}`
30137
28617
  return 0;
30138
28618
  }
30139
28619
  async function handleRunTail(args) {
30140
- const usage = "Usage: deepline runs tail <run-id> [--json | --jsonl] [--compact] [--log-level debug|info|warn|error]";
28620
+ const usage = "Usage: deepline runs watch <run-id> [--json | --jsonl] [--compact] [--log-level debug|info|warn|error]";
30141
28621
  let runId;
30142
28622
  try {
30143
28623
  runId = parseRunIdPositional(args, usage);
@@ -30152,7 +28632,7 @@ async function handleRunTail(args) {
30152
28632
  const arg = args[index];
30153
28633
  if (arg === "--cursor") {
30154
28634
  console.error(
30155
- "--cursor was removed. deepline runs tail reads the canonical run stream."
28635
+ "--cursor was removed. deepline runs watch polls the canonical run snapshot."
30156
28636
  );
30157
28637
  return 1;
30158
28638
  }
@@ -30178,7 +28658,7 @@ async function handleRunTail(args) {
30178
28658
  continue;
30179
28659
  }
30180
28660
  if (arg.startsWith("--") && arg !== "--json" && arg !== "--jsonl" && arg !== "--compact") {
30181
- console.error(`${arg} is not supported by deepline runs tail.`);
28661
+ console.error(`${arg} is not supported by deepline runs watch.`);
30182
28662
  return 1;
30183
28663
  }
30184
28664
  }
@@ -30214,7 +28694,7 @@ async function handleRunTail(args) {
30214
28694
  verbose: debug,
30215
28695
  logLevel
30216
28696
  };
30217
- const status = await client2.runs.tail(runId, {
28697
+ const status = await client2.runs.watch(runId, {
30218
28698
  onEvent: jsonLines ? (event) => {
30219
28699
  process.stdout.write(
30220
28700
  `${JSON.stringify({
@@ -30260,9 +28740,9 @@ async function handleRunTail(args) {
30260
28740
  }
30261
28741
  } : void 0,
30262
28742
  // Human mode only: in --json mode emit nothing non-protocol.
30263
- onReconnect: jsonOutput && !debug && !hasExplicitLogLevel ? void 0 : ({ reason }) => {
28743
+ onRetry: jsonOutput && !debug && !hasExplicitLogLevel ? void 0 : ({ reason }) => {
30264
28744
  process.stderr.write(
30265
- `[runs tail] stream ended without a terminal status; reconnecting to run ${runId} (${reason})
28745
+ `[runs watch] snapshot polling failed; retrying for run ${runId} (${reason})
30266
28746
  `
30267
28747
  );
30268
28748
  }
@@ -31929,7 +30409,10 @@ Examples:
31929
30409
  ).option(
31930
30410
  "--log-level <level>",
31931
30411
  "Minimum live log severity: debug, info (default), warn, or error"
31932
- ).option("--tail-timeout-ms <ms>", "Timeout while watching the run stream").option("--force", "Start a fresh run graph").option(
30412
+ ).option(
30413
+ "--tail-timeout-ms <ms>",
30414
+ "Timeout while waiting for terminal run status"
30415
+ ).option("--force", "Start a fresh run graph").option(
31933
30416
  "--force-tool-refresh",
31934
30417
  "Refresh completed tool receipts; may repeat billed provider calls"
31935
30418
  ).option(
@@ -32399,13 +30882,13 @@ Concepts:
32399
30882
  stop mutates cloud state by requesting cancellation.
32400
30883
 
32401
30884
  Debug a run:
32402
- Active: deepline runs tail <run-id> --log-level debug
30885
+ Active: deepline runs watch <run-id> --log-level debug
32403
30886
  Historical: deepline runs logs <run-id> --out run.log --log-level debug --json
32404
30887
  Full state: deepline runs get <run-id> --full --json
32405
30888
 
32406
30889
  Examples:
32407
30890
  deepline runs get play/my-play/run/20260501t000000-000 --json
32408
- deepline runs tail play/my-play/run/20260501t000000-000
30891
+ deepline runs watch play/my-play/run/20260501t000000-000
32409
30892
  deepline runs logs play/my-play/run/20260501t000000-000 --out run.log --log-level debug --json
32410
30893
  deepline runs list --play my-play --status failed --json
32411
30894
  deepline runs list --status running --json
@@ -32539,29 +31022,30 @@ Examples:
32539
31022
  ...options.json ? ["--json"] : []
32540
31023
  ]);
32541
31024
  });
32542
- runs.command("tail <runId>").description("Read the canonical live stream for a play run.").addHelpText(
31025
+ runs.command("watch <runId>").alias("tail").description("Poll the canonical run snapshot until terminal status.").addHelpText(
32543
31026
  "after",
32544
31027
  `
32545
31028
  Notes:
32546
- Streams live run events until the stream ends. Human output shows info and
32547
- warning logs as they arrive. Use get for current status and logs for persisted
32548
- log history. In human output, --compact prints deduplicated
32549
- step transitions and progress instead of the full event stream. --json emits
32550
- one terminal package. --jsonl emits canonical live events as JSON Lines and
32551
- ends with the same compact package shape as runs get --json. --log-level
31029
+ Polls the authenticated run snapshot every two seconds. Human output shows
31030
+ info and warning logs as snapshots change. Use get for current status and
31031
+ logs for persisted log history. In human output, --compact prints
31032
+ deduplicated step transitions and progress. --json emits one terminal
31033
+ package. --jsonl emits canonical watched events as JSON Lines and ends with
31034
+ the same compact package shape as runs get --json. The tail command remains
31035
+ an alias. --log-level
32552
31036
  filters the rendered customer-safe runtime log lines; debug includes runtime
32553
31037
  and receipt diagnostics and writes them to stderr alongside JSON output.
32554
31038
 
32555
31039
  Examples:
32556
- deepline runs tail play/my-play/run/20260501t000000-000
32557
- deepline runs tail play/my-play/run/20260501t000000-000 --compact
32558
- deepline runs tail play/my-play/run/20260501t000000-000 --log-level debug
32559
- deepline runs tail play/my-play/run/20260501t000000-000 --log-level error
32560
- deepline runs tail play/my-play/run/20260501t000000-000 --jsonl
31040
+ deepline runs watch play/my-play/run/20260501t000000-000
31041
+ deepline runs watch play/my-play/run/20260501t000000-000 --compact
31042
+ deepline runs watch play/my-play/run/20260501t000000-000 --log-level debug
31043
+ deepline runs watch play/my-play/run/20260501t000000-000 --log-level error
31044
+ deepline runs watch play/my-play/run/20260501t000000-000 --jsonl
32561
31045
  `
32562
31046
  ).option("--json", "Emit one terminal JSON package after the run completes").option(
32563
31047
  "--jsonl",
32564
- "Stream live events as JSON Lines, then the terminal package"
31048
+ "Emit watched events as JSON Lines, then the terminal package"
32565
31049
  ).option(
32566
31050
  "--compact",
32567
31051
  "Show deduplicated human step transitions and progress"
@@ -34479,7 +32963,7 @@ function isMarkedTestAiInferenceCommand(command) {
34479
32963
  if (normalizeEnrichPlayRef(command.tool) !== "run_javascript") {
34480
32964
  return false;
34481
32965
  }
34482
- return isRecord12(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
32966
+ return isRecord8(command.payload) && command.payload[ENRICH_TEST_AI_INFERENCE_PAYLOAD_MARKER] === true;
34483
32967
  }
34484
32968
  function enrichDebugEnabled(env = process.env) {
34485
32969
  const raw = String(env.DEEPLINE_DEBUG_ENRICH ?? "").trim().toLowerCase();
@@ -34743,7 +33227,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
34743
33227
  if (Array.isArray(value)) {
34744
33228
  return value.map(rewrite);
34745
33229
  }
34746
- if (!isRecord12(value)) {
33230
+ if (!isRecord8(value)) {
34747
33231
  return value;
34748
33232
  }
34749
33233
  const next = Object.fromEntries(
@@ -34752,7 +33236,7 @@ function rewriteGeneratedPlayRerunForEnrich(status, enrichCommand) {
34752
33236
  key === "rerunCommand" && typeof entry === "string" ? enrichCommand : rewrite(entry)
34753
33237
  ])
34754
33238
  );
34755
- if (isRecord12(next.next) && typeof next.next.run === "string") {
33239
+ if (isRecord8(next.next) && typeof next.next.run === "string") {
34756
33240
  next.next = { ...next.next, run: enrichCommand };
34757
33241
  }
34758
33242
  return next;
@@ -35234,7 +33718,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
35234
33718
  }
35235
33719
  return input2.client.runs.get(runId, { full: true });
35236
33720
  }
35237
- function isRecord12(value) {
33721
+ function isRecord8(value) {
35238
33722
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
35239
33723
  }
35240
33724
  async function captureStdout(run, options = {}) {
@@ -35486,15 +33970,15 @@ function readFirstEnrichDatasetActions(value) {
35486
33970
  return null;
35487
33971
  }
35488
33972
  const record3 = candidate;
35489
- const actions = isRecord12(record3.actions) ? record3.actions : null;
35490
- const currentQuery = isRecord12(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
35491
- const legacyQuery = isRecord12(actions?.query) ? actions.query : null;
33973
+ const actions = isRecord8(record3.actions) ? record3.actions : null;
33974
+ const currentQuery = isRecord8(actions?.queryCurrentTable) ? actions.queryCurrentTable : null;
33975
+ const legacyQuery = isRecord8(actions?.query) ? actions.query : null;
35492
33976
  const query = currentQuery?.kind === "deepline_db_query" ? currentQuery : legacyQuery?.kind === "deepline_db_query" ? legacyQuery : null;
35493
33977
  if (query?.kind === "deepline_db_query") {
35494
33978
  return {
35495
33979
  dataset: record3,
35496
33980
  query,
35497
- ...isRecord12(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
33981
+ ...isRecord8(actions?.exportCsv) ? { exportCsv: actions.exportCsv } : {}
35498
33982
  };
35499
33983
  }
35500
33984
  if (options.allowLegacy && record3.kind === "dataset" && typeof record3.queryDatasetCommand === "string" && record3.queryDatasetCommand.trim()) {
@@ -35547,7 +34031,7 @@ function enrichCustomerDbJson(input2) {
35547
34031
  const dataset = actions.dataset;
35548
34032
  const sql = actionStringField(query, "sql") ?? parseSqlFromDbQueryCommand(actions.queryDatasetCommand);
35549
34033
  const datasetPath = actionStringField(query, "datasetPath") ?? actionStringField(dataset, "path") ?? actionStringField(dataset, "tableNamespace");
35550
- const api = isRecord12(query.api) ? query.api : null;
34034
+ const api = isRecord8(query.api) ? query.api : null;
35551
34035
  const apiPath = actionStringField(api ?? {}, "path") ?? "/api/v2/db/query";
35552
34036
  const apiMethod = actionStringField(api ?? {}, "method") ?? "POST";
35553
34037
  if (!datasetPath) {
@@ -35616,11 +34100,11 @@ function sqlStringLiteral(value) {
35616
34100
  return `'${value.replace(/'/g, "''")}'`;
35617
34101
  }
35618
34102
  function failureAliasFromCellMeta(cellMeta) {
35619
- if (!isRecord12(cellMeta)) {
34103
+ if (!isRecord8(cellMeta)) {
35620
34104
  return null;
35621
34105
  }
35622
34106
  for (const [alias, meta] of Object.entries(cellMeta)) {
35623
- if (!isRecord12(meta)) {
34107
+ if (!isRecord8(meta)) {
35624
34108
  continue;
35625
34109
  }
35626
34110
  const failure = failureCellFromMeta(meta, {});
@@ -36114,7 +34598,7 @@ function exportableSheetRow2(row, sourceRowStart = 0) {
36114
34598
  return fallback;
36115
34599
  }
36116
34600
  function failureCellFromMeta(meta, fallback) {
36117
- if (!isRecord12(meta)) {
34601
+ if (!isRecord8(meta)) {
36118
34602
  return null;
36119
34603
  }
36120
34604
  const status = typeof meta.status === "string" ? meta.status.trim().toLowerCase() : "";
@@ -36134,7 +34618,7 @@ function failureCellFromMeta(meta, fallback) {
36134
34618
  };
36135
34619
  }
36136
34620
  function applyFailureCellMeta(row, cellMeta, fallback) {
36137
- if (!isRecord12(cellMeta)) {
34621
+ if (!isRecord8(cellMeta)) {
36138
34622
  return;
36139
34623
  }
36140
34624
  for (const [field, meta] of Object.entries(cellMeta)) {
@@ -36362,7 +34846,7 @@ function stableRowSnapshot(value) {
36362
34846
  }
36363
34847
  function cellFailureError(value) {
36364
34848
  const parsed = parseMaybeJsonObject(value);
36365
- if (!isRecord12(parsed)) {
34849
+ if (!isRecord8(parsed)) {
36366
34850
  const text = typeof parsed === "string" ? parsed.trim() : "";
36367
34851
  if (/^(?:[A-Za-z0-9_:-]+:\s*)?(?:Error|TypeError|ReferenceError|SyntaxError|RangeError):\s+/.test(
36368
34852
  text
@@ -36370,12 +34854,12 @@ function cellFailureError(value) {
36370
34854
  return { message: text };
36371
34855
  }
36372
34856
  }
36373
- if (!isRecord12(parsed)) {
34857
+ if (!isRecord8(parsed)) {
36374
34858
  return null;
36375
34859
  }
36376
34860
  const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
36377
34861
  const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
36378
- const result = isRecord12(parsed.result) ? parsed.result : null;
34862
+ const result = isRecord8(parsed.result) ? parsed.result : null;
36379
34863
  const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
36380
34864
  if (!directError && !resultError && status !== "error" && status !== "failed") {
36381
34865
  return null;
@@ -36445,7 +34929,7 @@ function assignFlattenedFailurePath(target, field, value) {
36445
34929
  let cursor = target;
36446
34930
  for (const part of normalized.slice(0, -1)) {
36447
34931
  const existing = cursor[part];
36448
- if (!isRecord12(existing)) {
34932
+ if (!isRecord8(existing)) {
36449
34933
  const next = {};
36450
34934
  cursor[part] = next;
36451
34935
  cursor = next;
@@ -36609,10 +35093,10 @@ function waterfallExecutionSignal(status, spec) {
36609
35093
  let everyChildStatOnlyConditionSkipped = true;
36610
35094
  const childAliasesWithStats = /* @__PURE__ */ new Set();
36611
35095
  for (const childAlias of childAliases) {
36612
- for (const stat5 of summaries.map((summary) => summary[childAlias]).filter(isRecord12)) {
35096
+ for (const stat5 of summaries.map((summary) => summary[childAlias]).filter(isRecord8)) {
36613
35097
  sawChildStats = true;
36614
35098
  childAliasesWithStats.add(childAlias);
36615
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35099
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36616
35100
  const executedSummary = parseExecutionSummary(
36617
35101
  execution?.["completed:executed"]
36618
35102
  );
@@ -36642,7 +35126,7 @@ function waterfallExecutionSignal(status, spec) {
36642
35126
  }
36643
35127
  function emptyWaterfallStatsEvidence(status, spec) {
36644
35128
  const summaries = collectColumnStats(status);
36645
- const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord12);
35129
+ const parentStats = summaries.map((summary) => summary[spec.alias]).filter(isRecord8);
36646
35130
  for (const stat5 of parentStats) {
36647
35131
  const nonEmpty = parseExecutionSummary(stat5.non_empty);
36648
35132
  if (nonEmpty?.total && nonEmpty.count === 0) {
@@ -36656,7 +35140,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
36656
35140
  let selectedRows = 0;
36657
35141
  let sawStatsForEveryChild = true;
36658
35142
  for (const childAlias of childAliases) {
36659
- const stat5 = summaries.map((summary) => summary[childAlias]).find(isRecord12);
35143
+ const stat5 = summaries.map((summary) => summary[childAlias]).find(isRecord8);
36660
35144
  if (!stat5) {
36661
35145
  sawStatsForEveryChild = false;
36662
35146
  break;
@@ -36665,7 +35149,7 @@ function emptyWaterfallStatsEvidence(status, spec) {
36665
35149
  if ((nonEmpty?.count ?? 0) > 0) {
36666
35150
  return null;
36667
35151
  }
36668
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35152
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36669
35153
  const executed = parseExecutionSummary(execution?.["completed:executed"]);
36670
35154
  const reused = parseExecutionSummary(execution?.["completed:reused"]);
36671
35155
  const skipped = parseExecutionSummary(execution?.["skipped:condition"]);
@@ -36707,11 +35191,11 @@ function collectStatusFailureJobs(input2) {
36707
35191
  const jobs = [];
36708
35192
  aliases.forEach((spec, aliasIndex) => {
36709
35193
  const { alias } = spec;
36710
- const stat5 = summaries.map((summary) => summary[alias]).find(isRecord12);
35194
+ const stat5 = summaries.map((summary) => summary[alias]).find(isRecord8);
36711
35195
  if (!stat5) {
36712
35196
  return;
36713
35197
  }
36714
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35198
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36715
35199
  const failedCount = Math.min(
36716
35200
  selectedRows,
36717
35201
  Math.max(
@@ -36818,10 +35302,10 @@ function collectColumnStats(status) {
36818
35302
  value.forEach(visit);
36819
35303
  return;
36820
35304
  }
36821
- if (!isRecord12(value)) {
35305
+ if (!isRecord8(value)) {
36822
35306
  return;
36823
35307
  }
36824
- if (isRecord12(value.columnStats)) {
35308
+ if (isRecord8(value.columnStats)) {
36825
35309
  summaries.push(value.columnStats);
36826
35310
  }
36827
35311
  Object.values(value).forEach(visit);
@@ -36833,12 +35317,12 @@ function firstAliasExecutionCounts(input2) {
36833
35317
  const aliases = collectConfigScalarAliasOrder(input2.config);
36834
35318
  const summaries = collectColumnStats(input2.status);
36835
35319
  for (const alias of aliases) {
36836
- const stat5 = summaries.map((summary) => summary[alias]).find(isRecord12);
35320
+ const stat5 = summaries.map((summary) => summary[alias]).find(isRecord8);
36837
35321
  if (!stat5) continue;
36838
35322
  if (input2.forceAliases.has(normalizeAlias2(alias))) {
36839
35323
  return { executed: input2.selectedRows, reused: 0 };
36840
35324
  }
36841
- const execution = isRecord12(stat5.execution) ? stat5.execution : null;
35325
+ const execution = isRecord8(stat5.execution) ? stat5.execution : null;
36842
35326
  if (!execution) continue;
36843
35327
  return {
36844
35328
  executed: parseExecutionCount(execution["completed:executed"]),
@@ -36865,14 +35349,14 @@ function rewriteEnrichJsonStatus(input2) {
36865
35349
  if (Array.isArray(value)) {
36866
35350
  return value.map(rewrite);
36867
35351
  }
36868
- if (!isRecord12(value)) {
35352
+ if (!isRecord8(value)) {
36869
35353
  return value;
36870
35354
  }
36871
35355
  const next = {};
36872
35356
  for (const [key, entry] of Object.entries(value)) {
36873
35357
  next[key] = rewrite(entry);
36874
35358
  }
36875
- if (isRecord12(next.progress)) {
35359
+ if (isRecord8(next.progress)) {
36876
35360
  next.progress = {
36877
35361
  ...next.progress,
36878
35362
  ...selectedRows > 0 ? { total: selectedRows } : {},
@@ -36881,8 +35365,8 @@ function rewriteEnrichJsonStatus(input2) {
36881
35365
  ...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
36882
35366
  };
36883
35367
  }
36884
- if (isRecord12(next.summary)) {
36885
- const rowCounts = isRecord12(next.summary.rowCounts) ? next.summary.rowCounts : null;
35368
+ if (isRecord8(next.summary)) {
35369
+ const rowCounts = isRecord8(next.summary.rowCounts) ? next.summary.rowCounts : null;
36886
35370
  if (failedRows > 0) {
36887
35371
  next.summary = {
36888
35372
  ...next.summary,
@@ -36895,11 +35379,11 @@ function rewriteEnrichJsonStatus(input2) {
36895
35379
  };
36896
35380
  }
36897
35381
  }
36898
- if (isRecord12(next.columnStats) && selectedRows > 0) {
35382
+ if (isRecord8(next.columnStats) && selectedRows > 0) {
36899
35383
  const columnStats = { ...next.columnStats };
36900
35384
  for (const alias of forcedAliases) {
36901
- const stat5 = isRecord12(columnStats[alias]) ? columnStats[alias] : null;
36902
- const execution = isRecord12(stat5?.execution) ? stat5.execution : null;
35385
+ const stat5 = isRecord8(columnStats[alias]) ? columnStats[alias] : null;
35386
+ const execution = isRecord8(stat5?.execution) ? stat5.execution : null;
36903
35387
  if (!stat5 || !execution) continue;
36904
35388
  columnStats[alias] = {
36905
35389
  ...stat5,
@@ -36918,14 +35402,14 @@ function rewriteEnrichJsonStatus(input2) {
36918
35402
  return next;
36919
35403
  };
36920
35404
  const rewritten = rewrite(input2.status);
36921
- if (failedRows === 0 || !isRecord12(rewritten)) {
35405
+ if (failedRows === 0 || !isRecord8(rewritten)) {
36922
35406
  return rewritten;
36923
35407
  }
36924
35408
  const partialStatus = selectedRows > 0 && failedRows < selectedRows ? "partial_success" : "failed";
36925
35409
  return {
36926
35410
  ...rewritten,
36927
35411
  ...rewritten.status === "completed" || rewritten.status === "failed" ? { status: partialStatus } : {},
36928
- ...isRecord12(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
35412
+ ...isRecord8(rewritten.run) && (rewritten.run.status === "completed" || rewritten.run.status === "failed") ? { run: { ...rewritten.run, status: partialStatus } } : {}
36929
35413
  };
36930
35414
  }
36931
35415
  function summarizeFailedJobError(value) {
@@ -37549,7 +36033,7 @@ function materializeCsvCellValue(value) {
37549
36033
  return value;
37550
36034
  }
37551
36035
  function compactArrayEnvelopeCompleteValue(value) {
37552
- if (!isRecord12(value) || value.kind !== "array") {
36036
+ if (!isRecord8(value) || value.kind !== "array") {
37553
36037
  return null;
37554
36038
  }
37555
36039
  if (!Array.isArray(value.preview)) {
@@ -37563,7 +36047,7 @@ function compactArrayEnvelopeCompleteValue(value) {
37563
36047
  }
37564
36048
  function disambiguateCompactAiInferencePayload(value) {
37565
36049
  const parsed = parseMaybeJsonObject(value);
37566
- if (!isRecord12(parsed) || !cellFailureError(parsed)) {
36050
+ if (!isRecord8(parsed) || !cellFailureError(parsed)) {
37567
36051
  return value;
37568
36052
  }
37569
36053
  return {
@@ -37572,14 +36056,14 @@ function disambiguateCompactAiInferencePayload(value) {
37572
36056
  };
37573
36057
  }
37574
36058
  function compactAiInferenceCellForCsv(value) {
37575
- if (!isRecord12(value)) {
36059
+ if (!isRecord8(value)) {
37576
36060
  return value;
37577
36061
  }
37578
36062
  const extractedJson = value.extracted_json;
37579
36063
  if (extractedJson !== null && extractedJson !== void 0) {
37580
36064
  return disambiguateCompactAiInferencePayload(extractedJson);
37581
36065
  }
37582
- const result = isRecord12(value.result) ? value.result : null;
36066
+ const result = isRecord8(value.result) ? value.result : null;
37583
36067
  const object = result?.object;
37584
36068
  if (object !== null && object !== void 0) {
37585
36069
  return disambiguateCompactAiInferencePayload(object);
@@ -37596,12 +36080,12 @@ function compactAiInferenceCellForCsv(value) {
37596
36080
  }
37597
36081
  function materializeEnrichAliasCellForCsv(row, alias, options) {
37598
36082
  const direct = row[alias];
37599
- if (isRecord12(direct)) {
36083
+ if (isRecord8(direct)) {
37600
36084
  const completeArray = compactArrayEnvelopeCompleteValue(direct);
37601
36085
  if (completeArray) {
37602
36086
  return materializeCsvCellValue(completeArray);
37603
36087
  }
37604
- if (options?.compactAiCell && direct.status === "completed" && (isRecord12(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
36088
+ if (options?.compactAiCell && direct.status === "completed" && (isRecord8(direct.result) || Object.prototype.hasOwnProperty.call(direct, "extracted_json") || typeof direct.output === "string")) {
37605
36089
  return materializeCsvCellValue(compactAiInferenceCellForCsv(direct));
37606
36090
  }
37607
36091
  if (Object.prototype.hasOwnProperty.call(direct, "matched_result") || Object.prototype.hasOwnProperty.call(direct, "matchedResult") || Object.prototype.hasOwnProperty.call(direct, "result")) {
@@ -37742,11 +36226,11 @@ function normalizeEnrichRowsForCsvExport(rows, config, options) {
37742
36226
  }
37743
36227
  function legacyMetadataFromRow(row) {
37744
36228
  const direct = parseLegacyMetadataCell(row._metadata);
37745
- if (direct && isRecord12(direct.columns)) {
36229
+ if (direct && isRecord8(direct.columns)) {
37746
36230
  return direct;
37747
36231
  }
37748
36232
  const relocated = parseLegacyMetadataCell(row.metadata);
37749
- if (relocated && isRecord12(relocated.columns)) {
36233
+ if (relocated && isRecord8(relocated.columns)) {
37750
36234
  return relocated;
37751
36235
  }
37752
36236
  const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
@@ -37763,7 +36247,7 @@ function legacyMetadataFromRow(row) {
37763
36247
  }
37764
36248
  function parseLegacyMetadataCell(value) {
37765
36249
  const parsed = parseMaybeJsonObject(value);
37766
- if (isRecord12(parsed)) {
36250
+ if (isRecord8(parsed)) {
37767
36251
  return parsed;
37768
36252
  }
37769
36253
  if (typeof value !== "string") {
@@ -37780,12 +36264,12 @@ function parseLegacyMetadataCell(value) {
37780
36264
  for (const candidate of candidates) {
37781
36265
  try {
37782
36266
  const decoded = JSON.parse(candidate);
37783
- if (isRecord12(decoded)) {
36267
+ if (isRecord8(decoded)) {
37784
36268
  return decoded;
37785
36269
  }
37786
36270
  if (typeof decoded === "string") {
37787
36271
  const nested = JSON.parse(decoded);
37788
- if (isRecord12(nested)) {
36272
+ if (isRecord8(nested)) {
37789
36273
  return nested;
37790
36274
  }
37791
36275
  }
@@ -37795,8 +36279,8 @@ function parseLegacyMetadataCell(value) {
37795
36279
  return null;
37796
36280
  }
37797
36281
  function mergeLegacyMetadataRecords(base, enriched) {
37798
- const baseColumns = isRecord12(base.columns) ? base.columns : null;
37799
- const enrichedColumns = isRecord12(enriched.columns) ? enriched.columns : null;
36282
+ const baseColumns = isRecord8(base.columns) ? base.columns : null;
36283
+ const enrichedColumns = isRecord8(enriched.columns) ? enriched.columns : null;
37800
36284
  const merged = {
37801
36285
  ...base,
37802
36286
  ...enriched
@@ -51183,7 +49667,7 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
51183
49667
  }
51184
49668
  function extractionContractEntries(entries) {
51185
49669
  return entries.flatMap((entry) => {
51186
- if (!isRecord13(entry)) return [];
49670
+ if (!isRecord9(entry)) return [];
51187
49671
  const name = stringField2(entry, "name");
51188
49672
  const expression = stringField2(entry, "expression");
51189
49673
  return name && expression ? [{ name, expression }] : [];
@@ -51204,7 +49688,7 @@ function printMonitorTypeFilters(tool) {
51204
49688
  }
51205
49689
  console.log("Deploy filters (set in the monitor payload):");
51206
49690
  for (const name of names) {
51207
- const field = isRecord13(properties[name]) ? properties[name] : {};
49691
+ const field = isRecord9(properties[name]) ? properties[name] : {};
51208
49692
  const star = required.has(name) ? "*" : "";
51209
49693
  const enumVals = arrayField2(field, "enum").filter(
51210
49694
  (v) => typeof v === "string"
@@ -51218,7 +49702,7 @@ function printMonitorTypeFilterExamples(tool) {
51218
49702
  const documentation = recordField2(tool, "documentation");
51219
49703
  const fields2 = recordField2(documentation, "fields");
51220
49704
  const examples = Object.entries(fields2).flatMap(([name, rawField]) => {
51221
- const grammar = recordField2(isRecord13(rawField) ? rawField : {}, "grammar");
49705
+ const grammar = recordField2(isRecord9(rawField) ? rawField : {}, "grammar");
51222
49706
  const example = stringField2(grammar, "example");
51223
49707
  const values = [
51224
49708
  ...arrayField2(grammar, "examples").filter(
@@ -51237,14 +49721,14 @@ function printMonitorTypeFilterExamples(tool) {
51237
49721
  }
51238
49722
  function printMonitorTypeStreams(tool) {
51239
49723
  const streams = arrayField2(tool, "streams", "output_streams").filter(
51240
- isRecord13
49724
+ isRecord9
51241
49725
  );
51242
49726
  if (!streams.length) return;
51243
49727
  console.log("");
51244
49728
  console.log("Filter columns (a play's sqlListeners.where, per stream):");
51245
49729
  for (const stream of streams) {
51246
49730
  const name = stringField2(stream, "stream");
51247
- const cols = arrayField2(stream, "columns").filter(isRecord13).map((col) => stringField2(col, "name")).filter(Boolean);
49731
+ const cols = arrayField2(stream, "columns").filter(isRecord9).map((col) => stringField2(col, "name")).filter(Boolean);
51248
49732
  console.log(`- ${name}: ${cols.join(", ")}`);
51249
49733
  }
51250
49734
  }
@@ -51261,7 +49745,7 @@ function monitorTypePricingLines(tool) {
51261
49745
  }
51262
49746
  const lines = ["Pricing (Deepline credits per accepted event):"];
51263
49747
  for (const key of keys) {
51264
- const entry = isRecord13(byType[key]) ? byType[key] : {};
49748
+ const entry = isRecord9(byType[key]) ? byType[key] : {};
51265
49749
  const credits = numberField2(entry, "deepline_credits", "deeplineCredits");
51266
49750
  const display = stringField2(entry, "display");
51267
49751
  const shown = display || (credits !== null ? `${formatDecimal(credits)} credits/event` : "see --json");
@@ -51311,8 +49795,8 @@ function printCompactToolContract(tool, requestedToolId) {
51311
49795
  return;
51312
49796
  }
51313
49797
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
51314
- const cost = isRecord13(contract.cost) ? contract.cost : {};
51315
- const getters = isRecord13(contract.getters) ? contract.getters : {};
49798
+ const cost = isRecord9(contract.cost) ? contract.cost : {};
49799
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51316
49800
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51317
49801
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51318
49802
  const inputFields = recursiveToolInputFieldsForDisplay(
@@ -51329,7 +49813,7 @@ function printCompactToolContract(tool, requestedToolId) {
51329
49813
  printToolOutputArrayShape(contract);
51330
49814
  printToolExecutionHints(contract);
51331
49815
  if (contract.deprecated === true) {
51332
- const deprecation = isRecord13(contract.deprecation) ? contract.deprecation : {};
49816
+ const deprecation = isRecord9(contract.deprecation) ? contract.deprecation : {};
51333
49817
  const message = stringField2(deprecation, "message");
51334
49818
  const replacementToolId = stringField2(
51335
49819
  deprecation,
@@ -51356,7 +49840,7 @@ function printCompactToolContract(tool, requestedToolId) {
51356
49840
  console.log("");
51357
49841
  console.log("Inputs:");
51358
49842
  for (const field of inputFields) {
51359
- if (!isRecord13(field)) continue;
49843
+ if (!isRecord9(field)) continue;
51360
49844
  const name = stringField2(field, "name");
51361
49845
  if (!name) continue;
51362
49846
  const required = field.required ? "*" : "";
@@ -51376,7 +49860,7 @@ function printCompactToolContract(tool, requestedToolId) {
51376
49860
  }
51377
49861
  console.log("");
51378
49862
  printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
51379
- const starterScript = isRecord13(contract.starterScript) ? contract.starterScript : {};
49863
+ const starterScript = isRecord9(contract.starterScript) ? contract.starterScript : {};
51380
49864
  const starterPath = stringField2(starterScript, "path");
51381
49865
  if (starterPath) {
51382
49866
  console.log("");
@@ -51390,14 +49874,14 @@ function printCompactToolContract(tool, requestedToolId) {
51390
49874
  console.log("Getters:");
51391
49875
  if (listGetters.length) console.log("Lists:");
51392
49876
  for (const entry of listGetters) {
51393
- if (isRecord13(entry))
49877
+ if (isRecord9(entry))
51394
49878
  console.log(
51395
49879
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51396
49880
  );
51397
49881
  }
51398
49882
  if (valueGetters.length) console.log("Values:");
51399
49883
  for (const entry of valueGetters) {
51400
- if (isRecord13(entry))
49884
+ if (isRecord9(entry))
51401
49885
  console.log(
51402
49886
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51403
49887
  );
@@ -51496,10 +49980,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
51496
49980
  ` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
51497
49981
  );
51498
49982
  console.log("});");
51499
- const getters = isRecord13(contract.getters) ? contract.getters : {};
49983
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51500
49984
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51501
49985
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51502
- const firstGetter = [...valueGetters, ...listGetters].find(isRecord13);
49986
+ const firstGetter = [...valueGetters, ...listGetters].find(isRecord9);
51503
49987
  if (firstGetter) {
51504
49988
  const name = stringField2(firstGetter, "name") || "value";
51505
49989
  const expression = stringField2(firstGetter, "expression");
@@ -51535,7 +50019,7 @@ function printPlayLikeToolUsage(tool, requestedToolId) {
51535
50019
  }
51536
50020
  function printToolGettersOnly(tool, requestedToolId) {
51537
50021
  const contract = toolContractJsonForDescribe(tool, requestedToolId);
51538
- const getters = isRecord13(contract.getters) ? contract.getters : {};
50022
+ const getters = isRecord9(contract.getters) ? contract.getters : {};
51539
50023
  const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
51540
50024
  const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
51541
50025
  console.log(`Getters: ${contract.toolId}`);
@@ -51548,7 +50032,7 @@ function printToolGettersOnly(tool, requestedToolId) {
51548
50032
  if (listGetters.length) {
51549
50033
  console.log("Lists:");
51550
50034
  for (const entry of listGetters) {
51551
- if (isRecord13(entry))
50035
+ if (isRecord9(entry))
51552
50036
  console.log(
51553
50037
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51554
50038
  );
@@ -51557,7 +50041,7 @@ function printToolGettersOnly(tool, requestedToolId) {
51557
50041
  if (valueGetters.length) {
51558
50042
  console.log("Values:");
51559
50043
  for (const entry of valueGetters) {
51560
- if (isRecord13(entry))
50044
+ if (isRecord9(entry))
51561
50045
  console.log(
51562
50046
  `- ${stringField2(entry, "name")}: ${playResultExpression(entry)}`
51563
50047
  );
@@ -51583,7 +50067,7 @@ function sampleValueForField(field) {
51583
50067
  function samplePayloadForInputFields(fields2) {
51584
50068
  return Object.fromEntries(
51585
50069
  fields2.slice(0, 4).flatMap((field) => {
51586
- if (!isRecord13(field)) return [];
50070
+ if (!isRecord9(field)) return [];
51587
50071
  const name = stringField2(field, "name");
51588
50072
  if (!name) return [];
51589
50073
  return [[name, sampleValueForField(field)]];
@@ -51713,8 +50197,8 @@ function formatListedToolCost(tool) {
51713
50197
  }
51714
50198
  function toolInputFieldsForDisplay(inputSchema) {
51715
50199
  if (Array.isArray(inputSchema.fields)) {
51716
- const fields2 = inputSchema.fields.filter(isRecord13);
51717
- if (!isRecord13(inputSchema.jsonSchema)) return fields2;
50200
+ const fields2 = inputSchema.fields.filter(isRecord9);
50201
+ if (!isRecord9(inputSchema.jsonSchema)) return fields2;
51718
50202
  const jsonSchemaFields = new Map(
51719
50203
  recursiveToolInputFieldsForDisplay({
51720
50204
  jsonSchema: inputSchema.jsonSchema
@@ -51726,26 +50210,26 @@ function toolInputFieldsForDisplay(inputSchema) {
51726
50210
  const jsonSchemaField = typeof field.name === "string" ? jsonSchemaFields.get(field.name) : void 0;
51727
50211
  const minItems = typeof field.minItems === "number" ? field.minItems : jsonSchemaField?.minItems;
51728
50212
  const maxItems = typeof field.maxItems === "number" ? field.maxItems : jsonSchemaField?.maxItems;
51729
- const items = isRecord13(field.items) ? field.items : jsonSchemaField?.items;
50213
+ const items = isRecord9(field.items) ? field.items : jsonSchemaField?.items;
51730
50214
  return {
51731
50215
  ...field,
51732
- ...isRecord13(items) ? { items } : {},
50216
+ ...isRecord9(items) ? { items } : {},
51733
50217
  ...typeof minItems === "number" ? { minItems } : {},
51734
50218
  ...typeof maxItems === "number" ? { maxItems } : {}
51735
50219
  };
51736
50220
  });
51737
50221
  }
51738
- const jsonSchema = isRecord13(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
51739
- const properties = isRecord13(jsonSchema.properties) ? jsonSchema.properties : {};
50222
+ const jsonSchema = isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
50223
+ const properties = isRecord9(jsonSchema.properties) ? jsonSchema.properties : {};
51740
50224
  const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
51741
50225
  return Object.entries(properties).map(([name, value]) => {
51742
- const property = isRecord13(value) ? value : {};
50226
+ const property = isRecord9(value) ? value : {};
51743
50227
  return {
51744
50228
  name,
51745
50229
  type: typeof property.type === "string" ? property.type : "unknown",
51746
50230
  required: required.has(name),
51747
50231
  description: property.description,
51748
- ...isRecord13(property.items) ? { items: property.items } : {},
50232
+ ...isRecord9(property.items) ? { items: property.items } : {},
51749
50233
  ...typeof property.minItems === "number" ? { minItems: property.minItems } : {},
51750
50234
  ...typeof property.maxItems === "number" ? { maxItems: property.maxItems } : {},
51751
50235
  ...Object.prototype.hasOwnProperty.call(property, "default") ? { default: property.default } : {}
@@ -51762,7 +50246,7 @@ function toolOutputFieldsForDisplay(outputSchema) {
51762
50246
  }
51763
50247
  function printToolOutputArrayShape(tool) {
51764
50248
  const outputFields = toolOutputFieldsForDisplay(
51765
- recordField2(isRecord13(tool) ? tool : {}, "outputSchema", "output_schema")
50249
+ recordField2(isRecord9(tool) ? tool : {}, "outputSchema", "output_schema")
51766
50250
  );
51767
50251
  if (outputFields.length === 0) return;
51768
50252
  console.log(" Output array shape (declared schema):");
@@ -51777,10 +50261,10 @@ function printToolOutputArrayShape(tool) {
51777
50261
  }
51778
50262
  }
51779
50263
  function canonicalToolJsonSchema(inputSchema) {
51780
- return isRecord13(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
50264
+ return isRecord9(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
51781
50265
  }
51782
50266
  function declaredToolJsonSchema(inputSchema) {
51783
- if (isRecord13(inputSchema.jsonSchema)) {
50267
+ if (isRecord9(inputSchema.jsonSchema)) {
51784
50268
  return inputSchema.jsonSchema;
51785
50269
  }
51786
50270
  return Array.isArray(inputSchema.fields) ? null : inputSchema;
@@ -51805,7 +50289,7 @@ function publicToolInputSchemaForDescribe(inputSchema) {
51805
50289
  };
51806
50290
  const stripDescriptions = (value) => {
51807
50291
  if (Array.isArray(value)) return value.map(stripDescriptions);
51808
- if (!isRecord13(value)) return value;
50292
+ if (!isRecord9(value)) return value;
51809
50293
  return Object.fromEntries(
51810
50294
  Object.entries(value).flatMap(([key, nested]) => {
51811
50295
  if (key === "description" && typeof nested === "string" && exposesProviderSpend(nested)) {
@@ -51826,7 +50310,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51826
50310
  for (const item of value) collectSchemaIds(item);
51827
50311
  return;
51828
50312
  }
51829
- if (!isRecord13(value)) return;
50313
+ if (!isRecord9(value)) return;
51830
50314
  if (typeof value.$id === "string" && value.$id.trim()) {
51831
50315
  schemasById.set(value.$id.trim(), value);
51832
50316
  }
@@ -51839,10 +50323,10 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51839
50323
  let current = root;
51840
50324
  for (const rawSegment of ref.slice(2).split("/")) {
51841
50325
  const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
51842
- if (!isRecord13(current)) return schema;
50326
+ if (!isRecord9(current)) return schema;
51843
50327
  current = current[segment];
51844
50328
  }
51845
- return isRecord13(current) ? current : schema;
50329
+ return isRecord9(current) ? current : schema;
51846
50330
  };
51847
50331
  const addField = (field) => {
51848
50332
  const name = typeof field.name === "string" ? field.name : "";
@@ -51857,7 +50341,7 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51857
50341
  if (ref && activeRefs.has(ref)) return;
51858
50342
  const schema = resolveRef(unresolvedSchema);
51859
50343
  const nextActiveRefs = ref ? /* @__PURE__ */ new Set([...activeRefs, ref]) : activeRefs;
51860
- const type = Array.isArray(schema.type) ? schema.type.map(String).join("|") : typeof schema.type === "string" ? schema.type : isRecord13(schema.properties) ? "object" : schema.items ? "array" : "unknown";
50344
+ const type = Array.isArray(schema.type) ? schema.type.map(String).join("|") : typeof schema.type === "string" ? schema.type : isRecord9(schema.properties) ? "object" : schema.items ? "array" : "unknown";
51861
50345
  if (path) {
51862
50346
  addField({
51863
50347
  name: path,
@@ -51865,18 +50349,18 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51865
50349
  required,
51866
50350
  description: schema.description,
51867
50351
  ...Array.isArray(schema.enum) ? { enum: schema.enum } : {},
51868
- ...isRecord13(schema.items) ? { items: schema.items } : {},
50352
+ ...isRecord9(schema.items) ? { items: schema.items } : {},
51869
50353
  ...typeof schema.minItems === "number" ? { minItems: schema.minItems } : {},
51870
50354
  ...typeof schema.maxItems === "number" ? { maxItems: schema.maxItems } : {},
51871
50355
  ...Object.prototype.hasOwnProperty.call(schema, "default") ? { default: schema.default } : {}
51872
50356
  });
51873
50357
  }
51874
- const properties = isRecord13(schema.properties) ? schema.properties : {};
50358
+ const properties = isRecord9(schema.properties) ? schema.properties : {};
51875
50359
  const requiredNames = new Set(
51876
50360
  Array.isArray(schema.required) ? schema.required.map(String) : []
51877
50361
  );
51878
50362
  for (const [name, value] of Object.entries(properties)) {
51879
- if (!isRecord13(value)) continue;
50363
+ if (!isRecord9(value)) continue;
51880
50364
  visit(
51881
50365
  value,
51882
50366
  path ? `${path}.${name}` : name,
@@ -51884,13 +50368,13 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51884
50368
  nextActiveRefs
51885
50369
  );
51886
50370
  }
51887
- if (isRecord13(schema.items)) {
50371
+ if (isRecord9(schema.items)) {
51888
50372
  visit(schema.items, `${path}[]`, false, nextActiveRefs);
51889
50373
  }
51890
50374
  for (const keyword of ["anyOf", "oneOf", "allOf"]) {
51891
50375
  const branches = Array.isArray(schema[keyword]) ? schema[keyword] : [];
51892
50376
  for (const branch of branches) {
51893
- if (isRecord13(branch)) {
50377
+ if (isRecord9(branch)) {
51894
50378
  visit(branch, path, required, nextActiveRefs);
51895
50379
  }
51896
50380
  }
@@ -51900,21 +50384,21 @@ function recursiveToolInputFieldsForDisplay(inputSchema) {
51900
50384
  return fields2.size ? [...fields2.values()] : toolInputFieldsForDisplay(inputSchema);
51901
50385
  }
51902
50386
  function inputFieldJsonForDescribe(field) {
51903
- const publicItems = isRecord13(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
50387
+ const publicItems = isRecord9(field.items) ? publicToolInputSchemaForDescribe({ items: field.items }).items : void 0;
51904
50388
  return {
51905
50389
  name: field.name,
51906
50390
  type: field.type ?? "unknown",
51907
50391
  required: Boolean(field.required),
51908
50392
  ...field.description ? { description: field.description } : {},
51909
- ...isRecord13(publicItems) ? { items: publicItems } : {},
50393
+ ...isRecord9(publicItems) ? { items: publicItems } : {},
51910
50394
  ...typeof field.minItems === "number" ? { minItems: field.minItems } : {},
51911
50395
  ...typeof field.maxItems === "number" ? { maxItems: field.maxItems } : {},
51912
50396
  ...Object.prototype.hasOwnProperty.call(field, "default") ? { default: field.default } : {}
51913
50397
  };
51914
50398
  }
51915
50399
  function arrayItemBoundsSuffix(field) {
51916
- const itemSchema = isRecord13(field.items) ? field.items : null;
51917
- const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord13(itemSchema.properties) ? "object" : "unknown" : null;
50400
+ const itemSchema = isRecord9(field.items) ? field.items : null;
50401
+ const itemType = itemSchema ? typeof itemSchema.type === "string" ? itemSchema.type : isRecord9(itemSchema.properties) ? "object" : "unknown" : null;
51918
50402
  const itemEnum = Array.isArray(itemSchema?.enum) ? ` enum=${itemSchema.enum.map(String).join("|")}` : "";
51919
50403
  const itemTypeSuffix = itemType && itemType !== "unknown" ? ` items=${itemType}${itemEnum}` : "";
51920
50404
  const minItems = typeof field.minItems === "number" && Number.isFinite(field.minItems) ? field.minItems : null;
@@ -51928,13 +50412,13 @@ function arrayItemBoundsSuffix(field) {
51928
50412
  }
51929
50413
  function printToolExecutionHints(value) {
51930
50414
  const batchCapabilityRecord = recordField2(
51931
- isRecord13(value) ? value : {},
50415
+ isRecord9(value) ? value : {},
51932
50416
  "batchCapability",
51933
50417
  "batch_capability"
51934
50418
  );
51935
50419
  const batchCapability = Object.keys(batchCapabilityRecord).length > 0 ? batchCapabilityRecord : null;
51936
50420
  const executionMetadata = recordField2(
51937
- isRecord13(value) ? value : {},
50421
+ isRecord9(value) ? value : {},
51938
50422
  "executionMetadata",
51939
50423
  "execution_metadata"
51940
50424
  );
@@ -51974,7 +50458,7 @@ function printToolExecutionHints(value) {
51974
50458
  executionMetadata,
51975
50459
  "configuredRateLimits",
51976
50460
  "configured_rate_limits"
51977
- ).filter(isRecord13);
50461
+ ).filter(isRecord9);
51978
50462
  if (configuredRateLimits.length > 0) {
51979
50463
  console.log("");
51980
50464
  console.log(
@@ -52039,17 +50523,17 @@ function printJsonPreview(label, payload) {
52039
50523
  }
52040
50524
  function samplePayload(samples, key) {
52041
50525
  const entry = samples[key];
52042
- if (!isRecord13(entry)) return void 0;
50526
+ if (!isRecord9(entry)) return void 0;
52043
50527
  return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
52044
50528
  }
52045
50529
  function commandEnvelopeFromRawResponse(rawResponse) {
52046
- return isRecord13(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
50530
+ return isRecord9(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
52047
50531
  }
52048
50532
  function toolExecuteExitCode(envelope) {
52049
50533
  return envelope.status === "failed" || envelope.ok === false ? 1 : 0;
52050
50534
  }
52051
50535
  function extractToolExecutionWarningMessages(rawResponse) {
52052
- if (!isRecord13(rawResponse)) return [];
50536
+ if (!isRecord9(rawResponse)) return [];
52053
50537
  const candidates = [
52054
50538
  recordField2(recordField2(rawResponse, "toolResponse"), "meta"),
52055
50539
  recordField2(
@@ -52066,7 +50550,7 @@ function extractToolExecutionWarningMessages(rawResponse) {
52066
50550
  for (const warning of warnings) {
52067
50551
  if (typeof warning === "string" && warning.trim()) {
52068
50552
  messages.push(warning.trim());
52069
- } else if (isRecord13(warning)) {
50553
+ } else if (isRecord9(warning)) {
52070
50554
  const message = stringField2(warning, "message");
52071
50555
  if (message) messages.push(message);
52072
50556
  }
@@ -52075,7 +50559,7 @@ function extractToolExecutionWarningMessages(rawResponse) {
52075
50559
  return [...new Set(messages)];
52076
50560
  }
52077
50561
  function apifySyncRecoveryNext(rawResponse) {
52078
- if (!isRecord13(rawResponse) || rawResponse.status !== "running") return null;
50562
+ if (!isRecord9(rawResponse) || rawResponse.status !== "running") return null;
52079
50563
  const toolResponse = recordField2(rawResponse, "toolResponse");
52080
50564
  const raw = recordField2(toolResponse, "raw");
52081
50565
  if (raw.state !== "awaiting_apify") return null;
@@ -52098,7 +50582,7 @@ function apifySyncRecoveryNext(rawResponse) {
52098
50582
  }
52099
50583
  function listExtractorPathsFromUsageGuidance(tool) {
52100
50584
  const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
52101
- const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord13(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
50585
+ const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord9(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
52102
50586
  return extractedLists.flatMap((entry) => {
52103
50587
  const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
52104
50588
  if (!Array.isArray(paths)) return [];
@@ -52114,7 +50598,7 @@ function formatDecimal(value) {
52114
50598
  function formatUsd(value) {
52115
50599
  return `$${formatDecimal(value)}`;
52116
50600
  }
52117
- function isRecord13(value) {
50601
+ function isRecord9(value) {
52118
50602
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
52119
50603
  }
52120
50604
  function stringField2(source, ...keys) {
@@ -52141,7 +50625,7 @@ function arrayField2(source, ...keys) {
52141
50625
  function recordField2(source, ...keys) {
52142
50626
  for (const key of keys) {
52143
50627
  const value = source[key];
52144
- if (isRecord13(value)) return value;
50628
+ if (isRecord9(value)) return value;
52145
50629
  }
52146
50630
  return {};
52147
50631
  }
@@ -52207,7 +50691,7 @@ function parseJsonObjectArgument(raw, flagName) {
52207
50691
  }
52208
50692
  throw invalidJsonError(flagName, message);
52209
50693
  }
52210
- if (!isRecord13(parsed)) {
50694
+ if (!isRecord9(parsed)) {
52211
50695
  throw invalidJsonError(flagName, "expected an object.");
52212
50696
  }
52213
50697
  return parsed;
@@ -52409,7 +50893,7 @@ function buildToolExecuteBaseEnvelope(input2) {
52409
50893
  kind: summaryEntries.length > 0 ? "object" : "raw",
52410
50894
  summary: input2.summary
52411
50895
  };
52412
- const envelopeHasCanonicalOutput = isRecord13(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
50896
+ const envelopeHasCanonicalOutput = isRecord9(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
52413
50897
  const envelopeHasDeclaredOutput = Object.prototype.hasOwnProperty.call(
52414
50898
  envelope,
52415
50899
  "output"
@@ -52436,7 +50920,7 @@ function buildToolExecuteBaseEnvelope(input2) {
52436
50920
  return {
52437
50921
  ...envelope,
52438
50922
  ...input2.idempotencyKey ? { idempotency_key: input2.idempotencyKey } : {},
52439
- ...isRecord13(input2.rawResponse) && isRecord13(input2.rawResponse.executionRecovery) ? { execution_recovery: input2.rawResponse.executionRecovery } : {},
50923
+ ...isRecord9(input2.rawResponse) && isRecord9(input2.rawResponse.executionRecovery) ? { execution_recovery: input2.rawResponse.executionRecovery } : {},
52440
50924
  ...envelopeHasCanonicalOutput || envelopeHasDeclaredOutput ? { output_preview: outputPreview } : { output: outputPreview },
52441
50925
  ...summaryEntries.length > 0 ? { summary: input2.summary } : {},
52442
50926
  ...warningMessages.length > 0 ? { warnings: warningMessages } : {},
@@ -52495,7 +50979,7 @@ function buildToolExecuteRowArtifactEnvelope(input2) {
52495
50979
  void _render;
52496
50980
  void _next;
52497
50981
  void _local;
52498
- const billingLookup = isRecord13(input2.baseEnvelope.next) && typeof input2.baseEnvelope.next.billing === "string" ? input2.baseEnvelope.next.billing : null;
50982
+ const billingLookup = isRecord9(input2.baseEnvelope.next) && typeof input2.baseEnvelope.next.billing === "string" ? input2.baseEnvelope.next.billing : null;
52499
50983
  return {
52500
50984
  ...base,
52501
50985
  status: typeof base.status === "string" ? base.status : "completed",
@@ -52671,7 +51155,7 @@ async function executeTool(args) {
52671
51155
  {
52672
51156
  ...baseEnvelope,
52673
51157
  local: {
52674
- ...isRecord13(baseEnvelope.local) ? baseEnvelope.local : {},
51158
+ ...isRecord9(baseEnvelope.local) ? baseEnvelope.local : {},
52675
51159
  payload_file: jsonPath
52676
51160
  }
52677
51161
  },
@@ -52985,7 +51469,7 @@ var PLAY_EQUIVALENT = {
52985
51469
  schema: "deepline plays describe <name>",
52986
51470
  runs: "deepline runs list --play <name>",
52987
51471
  run: "deepline runs get <run-id>",
52988
- tail: "deepline runs tail <run-id>",
51472
+ tail: "deepline runs watch <run-id>",
52989
51473
  cancel: "deepline runs stop <run-id>",
52990
51474
  delete: "deepline plays delete <name>"
52991
51475
  };