deepline 0.3.128 → 0.3.129

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +34 -9
  2. package/dist/bundling-sources/sdk/src/http.ts +22 -0
  3. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  4. package/dist/bundling-sources/shared_libs/play-data-plane/r2.ts +22 -0
  5. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +265 -2
  6. package/dist/bundling-sources/shared_libs/play-runtime/bounded-batch-function.ts +682 -0
  7. package/dist/bundling-sources/shared_libs/play-runtime/child-execution-strategy.ts +21 -5
  8. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +5390 -1732
  9. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +107 -1
  10. package/dist/bundling-sources/shared_libs/play-runtime/deployment/commands/roll-execution-relay.ts +7 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-machines.ts +229 -7
  12. package/dist/bundling-sources/shared_libs/play-runtime/deployment/fly-registry.ts +25 -4
  13. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-gateway-capacity.ts +71 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-gateway-drain.ts +1 -1
  15. package/dist/bundling-sources/shared_libs/play-runtime/deployment/runtime-topology.ts +4 -1
  16. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +694 -28
  17. package/dist/bundling-sources/shared_libs/play-runtime/egress-bandwidth-probe.ts +167 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/execute-server-timing.ts +103 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-receipt-output-reference.ts +34 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/execution-gateway-response-size.ts +27 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/gateway-postgres-admission.ts +66 -1
  22. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +425 -71
  23. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +210 -32
  24. package/dist/bundling-sources/shared_libs/play-runtime/governor/in-memory-rate-state-backend.ts +27 -13
  25. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +19 -6
  26. package/dist/bundling-sources/shared_libs/play-runtime/governor/rate-state-backend.ts +61 -2
  27. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/contracts.ts +33 -1
  28. package/dist/bundling-sources/shared_libs/play-runtime/integration-operation-reader-fence/job.ts +42 -1
  29. package/dist/bundling-sources/shared_libs/play-runtime/launch-source-policy.ts +11 -11
  30. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +49 -16
  31. package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +1653 -98
  32. package/dist/bundling-sources/shared_libs/play-runtime/memory-ledger.ts +807 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/memory-pressure-signal.ts +138 -0
  34. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +85 -3
  35. package/dist/bundling-sources/shared_libs/play-runtime/persistence-latch.ts +60 -2
  36. package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +46 -1
  37. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/contracts.ts +2 -0
  38. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/job.ts +1 -0
  39. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/ports.ts +1 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/play-runs/terminal/postgres-adapter.ts +1 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +70 -27
  42. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +56 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/adaptive-provider-capacity-controller.ts +192 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/epoch-aimd-rate-controller.ts +194 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/fixture-capacity-simulator.ts +220 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/gradient2-concurrency-controller.ts +214 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/provider-capacity-policy.ts +43 -0
  48. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/provider-concurrency-policy.ts +30 -0
  49. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/provider-rate-policy.ts +95 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/provider-capacity/provider-throttle-classifier.ts +40 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +1535 -11
  52. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +49 -2
  53. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +6 -1
  54. package/dist/bundling-sources/shared_libs/play-runtime/run-log-buffer.ts +55 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/egress-probe.ts +221 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/index.ts +339 -29
  57. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-deadline.ts +28 -1
  58. package/dist/bundling-sources/shared_libs/play-runtime/runner-app/runtime-progress-push.ts +192 -165
  59. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +6 -0
  60. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +90 -5
  61. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-runtime-watchdog.ts +281 -6
  62. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +27 -1
  63. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +19 -0
  64. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/modal.ts +108 -0
  65. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +40 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +11 -5
  67. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +30 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api-compression.ts +276 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +723 -115
  70. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +98 -2
  71. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +3 -2
  72. package/dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts +41 -4
  73. package/dist/bundling-sources/shared_libs/play-runtime/runtime-flow.ts +448 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/runtime-map-row-feed.ts +215 -0
  75. package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation-contract.ts +11 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +161 -14
  77. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-value.ts +184 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-writer.ts +607 -121
  79. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sandbox-placement-policy.ts +4 -0
  80. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-row-writer.ts +21 -0
  81. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/contract.ts +15 -2
  82. package/dist/bundling-sources/shared_libs/play-runtime/sandbox-runs/runner-backend-adapter.ts +71 -14
  83. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-play-deploy-task.ts +2 -2
  84. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-runtime-worker.ts +288 -119
  85. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-shared.ts +8 -6
  86. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/absurd-worker-required-env.ts +28 -3
  87. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/canonical-integration-operation-store.ts +179 -0
  88. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-heavy-request-admission.ts +80 -2
  89. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/gateway-progress-registry.ts +31 -2
  90. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/integration-operation-store-contract.ts +104 -0
  91. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/integration-operation-value-reference.ts +47 -0
  92. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/integration-operation-value-retirement.ts +193 -0
  93. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/integration-operation-value-storage.ts +420 -0
  94. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-pool.ts +41 -0
  95. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-progress.ts +134 -3
  96. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres-rate-state.ts +1657 -95
  97. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/postgres.ts +885 -73
  98. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-completion-coalescer.ts +452 -0
  99. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/receipt-gateway.ts +601 -42
  100. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/run-terminal-transition.ts +1 -0
  101. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/runtime-receipt-value-storage.ts +371 -0
  102. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backends/worker-resource-metrics.ts +86 -7
  103. package/dist/bundling-sources/shared_libs/play-runtime/secret-redaction.ts +153 -22
  104. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/index.ts +1 -0
  105. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/receipt-cohort.ts +188 -38
  106. package/dist/bundling-sources/shared_libs/play-runtime/tool-call/runtime-step-receipts-adapter.ts +28 -13
  107. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +44 -1
  108. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +56 -4
  109. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +2 -0
  110. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +16 -10
  111. package/dist/bundling-sources/shared_libs/plays/dataset.ts +4 -1
  112. package/dist/cli/index.js +250 -38
  113. package/dist/cli/index.mjs +250 -38
  114. package/dist/{compiler-manifest-DfSnbCTW.d.mts → compiler-manifest-BIqRyj5m.d.mts} +1 -1
  115. package/dist/{compiler-manifest-DfSnbCTW.d.ts → compiler-manifest-BIqRyj5m.d.ts} +1 -1
  116. package/dist/index.d.mts +4 -2
  117. package/dist/index.d.ts +4 -2
  118. package/dist/index.js +231 -35
  119. package/dist/index.mjs +231 -35
  120. package/dist/install-integrity.json +31 -2
  121. package/dist/plays/bundle-play-file.d.mts +2 -2
  122. package/dist/plays/bundle-play-file.d.ts +2 -2
  123. package/dist/plays/bundle-play-file.mjs +65 -1
  124. package/dist/release.d.mts +1 -1
  125. package/dist/release.d.ts +1 -1
  126. package/dist/release.js +1 -1
  127. package/dist/release.mjs +1 -1
  128. package/package.json +1 -1
@@ -59,6 +59,7 @@ import {
59
59
  providerMetaFromToolResponseRawV2,
60
60
  type ToolResponseView,
61
61
  } from '../plays/tool-response-contract';
62
+ import type { RuntimeReceiptValueReference } from './runtime-receipt-value';
62
63
 
63
64
  type PathSegment = string | number | '*';
64
65
 
@@ -69,9 +70,48 @@ const SERIALIZED_TOOL_EXECUTE_RESULT_V2_KIND =
69
70
  const SERIALIZED_TOOL_RESULT_LIST_PREVIEW_LIMIT = 5;
70
71
  const LIVE_TOOL_RESULT_LIST_DATASET_REGISTRY_LIMIT = 256;
71
72
  const SERIALIZED_TOOL_LIST_ROWS = Symbol('deepline.serialized_tool_list_rows');
73
+
74
+ /**
75
+ * A live tool result may have been durably published by the execution relay
76
+ * before the runner sees its provider body. Keep that transport-only fact out
77
+ * of the public ToolExecuteResult and its persisted schema: the caller still
78
+ * receives the ordinary fully materialized result, while receipt publication
79
+ * can use the compact immutable R2 reference.
80
+ */
81
+ const relayPublishedResultReferences = new WeakMap<
82
+ object,
83
+ RuntimeReceiptValueReference
84
+ >();
85
+
86
+ export function attachRelayPublishedToolResultReference(
87
+ result: ToolExecuteResult,
88
+ reference: RuntimeReceiptValueReference,
89
+ ): ToolExecuteResult {
90
+ relayPublishedResultReferences.set(result, reference);
91
+ return result;
92
+ }
93
+
94
+ export function relayPublishedToolResultReference(
95
+ result: ToolExecuteResult,
96
+ ): RuntimeReceiptValueReference | null {
97
+ return relayPublishedResultReferences.get(result) ?? null;
98
+ }
99
+ /**
100
+ * This registry is a same-process rehydration fast path, not an owner of a
101
+ * tool result. A strong process-global cache retained the full rows behind up
102
+ * to 256 otherwise-discarded list results. At map scale, a caller that only
103
+ * awaits `ctx.tools.execute()` could therefore keep hundreds of provider
104
+ * bodies alive after its cell had returned.
105
+ *
106
+ * The ToolExecuteResult that owns a live list already strongly owns its
107
+ * accessor and dataset. A weak lookup keeps the fast path while that result is
108
+ * still reachable, but lets the runtime release a result the authored Play no
109
+ * longer uses. Durable serialization still carries its normal list rows or
110
+ * preview, so a collected entry falls back to the existing durable path.
111
+ */
72
112
  const liveToolResultListDatasets = new Map<
73
113
  string,
74
- PlayDataset<Record<string, unknown>>
114
+ WeakRef<PlayDataset<Record<string, unknown>>>
75
115
  >();
76
116
 
77
117
  /**
@@ -229,6 +269,12 @@ export type ParsedToolExecuteResponse = {
229
269
  result: unknown;
230
270
  /** Tool extractor metadata parsed from `_metadata.tool`, if present. */
231
271
  metadata: ToolResultMetadataInput | null;
272
+ /**
273
+ * Transport-only reference attached by the trusted execution relay after it
274
+ * persisted the complete serialized result. The raw response still remains
275
+ * present for ordinary live Play evaluation.
276
+ */
277
+ receiptOutputRef?: RuntimeReceiptValueReference;
232
278
  };
233
279
 
234
280
  export function parseToolExecuteResponse(
@@ -1473,7 +1519,7 @@ function rememberLiveToolResultListDataset(
1473
1519
  ): void {
1474
1520
  if (!datasetId) return;
1475
1521
  liveToolResultListDatasets.delete(datasetId);
1476
- liveToolResultListDatasets.set(datasetId, dataset);
1522
+ liveToolResultListDatasets.set(datasetId, new WeakRef(dataset));
1477
1523
  while (
1478
1524
  liveToolResultListDatasets.size >
1479
1525
  LIVE_TOOL_RESULT_LIST_DATASET_REGISTRY_LIMIT
@@ -1487,8 +1533,14 @@ function rememberLiveToolResultListDataset(
1487
1533
  function readLiveToolResultListDataset(
1488
1534
  serialized: SerializedPlayDataset<Record<string, unknown>>,
1489
1535
  ): PlayDataset<Record<string, unknown>> | null {
1490
- const dataset = liveToolResultListDatasets.get(serialized.datasetId);
1491
- if (!dataset) return null;
1536
+ const reference = liveToolResultListDatasets.get(serialized.datasetId);
1537
+ const dataset = reference?.deref();
1538
+ if (!dataset) {
1539
+ // Keep the small key registry honest too. A dead weak entry is not useful
1540
+ // to a later deserialize and must not consume one of the LRU slots.
1541
+ liveToolResultListDatasets.delete(serialized.datasetId);
1542
+ return null;
1543
+ }
1492
1544
  const current = dataset.toJSON();
1493
1545
  if (current.count !== serialized.count) return null;
1494
1546
  return dataset;
@@ -43,6 +43,8 @@ export function workReceiptFailureKindCodeForWrite(
43
43
 
44
44
  export type WorkReceipt = {
45
45
  key: string;
46
+ /** Completion acknowledgement only: whether this request published the output. */
47
+ completionDisposition?: 'persisted' | 'existing';
46
48
  status: WorkReceiptStatus;
47
49
  output?: unknown;
48
50
  error?: string | null;
@@ -7,18 +7,17 @@ import type { ToolExecutionErrorSchemaVersion } from './tool-execution-error';
7
7
  import type { PlayDataset, PlayDatasetInput, PlayDatasetRow } from './dataset';
8
8
 
9
9
  export const LEGACY_PLAY_AUTHORING_CONTRACT_EDITION = 1 as const;
10
- export const PLAY_AUTHORING_CONTRACT_EDITION = 7 as const;
10
+ export const PLAY_AUTHORING_CONTRACT_EDITION = 8 as const;
11
11
  export const PLAY_AUTHORING_INPUT_SCHEMA_SNAPSHOT_EDITION = 3 as const;
12
12
  export const SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS = [
13
- 1, 2, 3, 4, 5, 6, 7,
13
+ 1, 2, 3, 4, 5, 6, 7, 8,
14
14
  ] as const;
15
15
 
16
16
  export type PlayAuthoringContractEdition =
17
17
  (typeof SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS)[number];
18
18
 
19
- export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
19
+ const PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS = [
20
20
  {
21
- edition: 1,
22
21
  changed:
23
22
  'Historical extraction semantics. Invalid or unresolved optional authoring fields may normalize to absence.',
24
23
  compatibilityOwner: 'Plays Runtime',
@@ -27,7 +26,6 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
27
26
  'After every retained edition 1 artifact has a materialized admitted snapshot.',
28
27
  },
29
28
  {
30
- edition: 2,
31
29
  changed:
32
30
  'Pins admitted authoring snapshots and rejects ambiguous billing, secret, webhook, fetch, timeout, receipt-wait, and freshness contracts.',
33
31
  compatibilityOwner: 'Plays Runtime',
@@ -36,7 +34,6 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
36
34
  'After every retained edition 2 artifact has an admitted input schema or has been republished.',
37
35
  },
38
36
  {
39
- edition: 3,
40
37
  changed:
41
38
  'Materializes the declared input schema in the admitted snapshot so launch never reparses current source.',
42
39
  compatibilityOwner: 'Plays Runtime',
@@ -44,7 +41,6 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
44
41
  readerRemoval: null,
45
42
  },
46
43
  {
47
- edition: 4,
48
44
  changed:
49
45
  'ctx.secrets.get(name) resolves an allowed secret to a plaintext string for ordinary Play code. Editions 1–3 retain opaque secret handles.',
50
46
  compatibilityOwner: 'Plays Runtime',
@@ -52,7 +48,6 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
52
48
  readerRemoval: null,
53
49
  },
54
50
  {
55
- edition: 5,
56
51
  changed:
57
52
  'ctx.fetch throws a typed, redacted CtxFetchHttpError for non-2xx responses. Editions 1–4 continue to return the response record for every HTTP status.',
58
53
  compatibilityOwner: 'Plays Runtime',
@@ -60,7 +55,6 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
60
55
  readerRemoval: null,
61
56
  },
62
57
  {
63
- edition: 6,
64
58
  changed:
65
59
  'Adds static cron input and rejects unknown definePlay and binding fields during new admission. Editions 1–5 retain their admitted binding semantics.',
66
60
  compatibilityOwner: 'Plays Runtime',
@@ -68,15 +62,27 @@ export const PLAY_AUTHORING_CONTRACT_CHANGELOG = [
68
62
  readerRemoval: null,
69
63
  },
70
64
  {
71
- edition: 7,
72
65
  changed:
73
66
  'Slack HITL calls that omit timeout wait one week. Editions 1–6 retain the historical 24-hour default.',
74
67
  compatibilityOwner: 'Plays Runtime',
75
68
  newWritesEnd: null,
76
69
  readerRemoval: null,
77
70
  },
71
+ {
72
+ changed:
73
+ 'Lets an inline scalar child execute without a stored static pipeline. Dataset creation and suspension remain rejected by the authoritative runtime capability boundary; editions 1–7 retain static-contract preflight rejection.',
74
+ compatibilityOwner: 'Plays Runtime',
75
+ newWritesEnd: null,
76
+ readerRemoval: null,
77
+ },
78
78
  ] as const;
79
79
 
80
+ export const PLAY_AUTHORING_CONTRACT_CHANGELOG =
81
+ SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS.map((edition, index) => ({
82
+ edition,
83
+ ...PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS[index]!,
84
+ }));
85
+
80
86
  /**
81
87
  * Customer-visible runtime capabilities that are not expressible as one
82
88
  * `ctx.*` signature. The generated authoring reference renders this inventory
@@ -6,6 +6,7 @@ const residentRowsByDataset = new WeakMap<object, readonly unknown[]>();
6
6
  const DEFAULT_MATERIALIZE_LIMIT = 10_000;
7
7
  export const PLAY_DATASET_EXECUTION_PAGE_ROWS = 1_000;
8
8
  export const PLAY_DATASET_EXECUTION_PAGE_BYTES = 64 * 1024 * 1024;
9
+ const DATASET_UTF8_ENCODER = new TextEncoder();
9
10
 
10
11
  export type PlayDatasetKind = 'csv' | 'map';
11
12
 
@@ -899,7 +900,9 @@ export async function* iteratePlayDatasetInputPages<T>(
899
900
  options?.estimateRowBytes ??
900
901
  ((row: T) => {
901
902
  const serialized = JSON.stringify(row);
902
- return serialized === undefined ? 0 : serialized.length;
903
+ return serialized === undefined
904
+ ? 0
905
+ : DATASET_UTF8_ENCODER.encode(serialized).byteLength;
903
906
  });
904
907
  let page: T[] = [];
905
908
  let pageBytes = 0;
package/dist/cli/index.js CHANGED
@@ -3068,7 +3068,7 @@ var SDK_RELEASE = {
3068
3068
  // getters keep their established compatibility behavior.
3069
3069
  // 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
3070
3070
  // 0.3.90 is the first deliberately versioned SDK release for API v3.
3071
- version: "0.3.128",
3071
+ version: "0.3.129",
3072
3072
  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.",
3073
3073
  packageCapabilities: {
3074
3074
  updatePreferences: 1
@@ -3906,6 +3906,20 @@ var HttpClient = class {
3906
3906
  }
3907
3907
  throw lastError;
3908
3908
  }
3909
+ if (typeof parsed === "string") {
3910
+ const interstitial = detectHtmlErrorBody(
3911
+ body,
3912
+ response.headers.get("content-type")
3913
+ );
3914
+ if (interstitial) {
3915
+ throw new DeeplineError(
3916
+ `${this.config.baseUrl} returned a deployment-protection page instead of JSON. Set VERCEL_PROTECTION_BYPASS_TOKEN, or run \`vercel login\` if the CLI session expired.`,
3917
+ response.status,
3918
+ "DEPLOYMENT_PROTECTED",
3919
+ { htmlErrorPage: true }
3920
+ );
3921
+ }
3922
+ }
3909
3923
  return parsed;
3910
3924
  } catch (error) {
3911
3925
  clearTimeout(timeoutId);
@@ -4402,6 +4416,11 @@ function normalizePlayRunLedgerTerminalSource(value) {
4402
4416
  ) ? value : null;
4403
4417
  }
4404
4418
 
4419
+ // ../play-runtime/run-log-buffer.ts
4420
+ var RUNNER_LOG_MAX_BYTES = 5 * 1024 * 1024;
4421
+ var TERMINAL_RESERVE_BYTES = 64 * 1024;
4422
+ var encoder = new TextEncoder();
4423
+
4405
4424
  // ../play-runtime/secret-redaction.ts
4406
4425
  var SECRET_REDACTION_PLACEHOLDER = "[REDACTED_SECRET]";
4407
4426
  var BEARER_TOKEN_RE = /\bBearer\s+[A-Za-z0-9._~+/=-]{12,}\b/g;
@@ -4419,6 +4438,18 @@ var SENSITIVE_FIELD_NAME_RE = new RegExp(
4419
4438
  `(^|[._-])(?:${SENSITIVE_FIELD_NAME})$`,
4420
4439
  "i"
4421
4440
  );
4441
+ var SENSITIVE_FIELD_NAME_CACHE_MAX_ENTRIES = 4096;
4442
+ var sensitiveFieldNameCache = /* @__PURE__ */ new Map();
4443
+ function isSensitiveFieldName(key) {
4444
+ const cached = sensitiveFieldNameCache.get(key);
4445
+ if (cached !== void 0) return cached;
4446
+ const sensitive = SENSITIVE_FIELD_NAME_RE.test(key);
4447
+ if (sensitiveFieldNameCache.size >= SENSITIVE_FIELD_NAME_CACHE_MAX_ENTRIES) {
4448
+ sensitiveFieldNameCache.clear();
4449
+ }
4450
+ sensitiveFieldNameCache.set(key, sensitive);
4451
+ return sensitive;
4452
+ }
4422
4453
  var SERIALIZED_SECRET_FIELD_RE = new RegExp(
4423
4454
  `"(${SENSITIVE_FIELD_NAME})"\\s*:\\s*(?:"[^"\\\\]*"|\\{[^{}]*\\})`,
4424
4455
  "gi"
@@ -4426,7 +4457,45 @@ var SERIALIZED_SECRET_FIELD_RE = new RegExp(
4426
4457
  function escapeRegExp(value) {
4427
4458
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4428
4459
  }
4460
+ var REDACTION_TRIGGER_RE = new RegExp(
4461
+ [
4462
+ // Sensitive field names, in object keys and in `name=`/`"name":` text.
4463
+ "token",
4464
+ "secret",
4465
+ "password",
4466
+ "authorization",
4467
+ "cookie",
4468
+ "credential",
4469
+ // One `key` branch instead of `api[_-]?key`, `private[_-]?key` and `key_`.
4470
+ // A regex alternation costs roughly one substring scan per branch, and a
4471
+ // broader branch can only send more payloads down the exact path.
4472
+ "key",
4473
+ // Self-identifying credential prefixes.
4474
+ "bearer",
4475
+ "basic",
4476
+ "-----BEGIN",
4477
+ "xox[baprs]-",
4478
+ "[prs]k_",
4479
+ "pat_",
4480
+ "ghp_",
4481
+ // URL credentials: `//user:pass@host` userinfo and sensitive query params.
4482
+ // The userinfo class excludes `/` exactly as the rule it guards does.
4483
+ "//[^\\s/]{0,256}@",
4484
+ "[?#&]sig",
4485
+ // JWTs carry no keyword at all, so the shape itself is the marker. Anchor
4486
+ // on the separating dot and drop JWT_RE's leading `{8,}` segment: a dot is
4487
+ // rare enough for the engine to skip between candidates, which makes this
4488
+ // gate roughly ten times cheaper than re-running JWT_RE itself, and
4489
+ // dropping a required segment can only widen what it accepts.
4490
+ "\\.[A-Za-z0-9_-]{1,16384}\\.[A-Za-z0-9_-]{8}"
4491
+ ].join("|"),
4492
+ "i"
4493
+ );
4494
+ function mightContainRedactableSecret(value) {
4495
+ return REDACTION_TRIGGER_RE.test(value);
4496
+ }
4429
4497
  function redactSecretLikeString(value) {
4498
+ if (!mightContainRedactableSecret(value)) return value;
4430
4499
  const serializedRedacted = value.replace(
4431
4500
  SERIALIZED_SECRET_FIELD_RE,
4432
4501
  `"$1":"${SECRET_REDACTION_PLACEHOLDER}"`
@@ -4448,9 +4517,26 @@ function redactSecretLikeString(value) {
4448
4517
  }
4449
4518
  function createSecretRedactionContext(initialValues = []) {
4450
4519
  const exactSecrets = /* @__PURE__ */ new Set();
4520
+ const exactSecretMatchers = /* @__PURE__ */ new Map();
4451
4521
  function register(value) {
4452
4522
  if (value.length > 0) exactSecrets.add(value);
4453
4523
  }
4524
+ function matchersForSecret(secret) {
4525
+ const cached = exactSecretMatchers.get(secret);
4526
+ if (cached) return cached;
4527
+ const literals = [secret];
4528
+ try {
4529
+ const encoded = encodeURIComponent(secret);
4530
+ if (encoded !== secret) literals.push(encoded);
4531
+ } catch {
4532
+ }
4533
+ const built = literals.map((literal) => ({
4534
+ literal,
4535
+ matcher: new RegExp(escapeRegExp(literal), "g")
4536
+ }));
4537
+ exactSecretMatchers.set(secret, built);
4538
+ return built;
4539
+ }
4454
4540
  for (const value of initialValues) register(value);
4455
4541
  function containsRegisteredSecret(value, {
4456
4542
  includeEncoded = false,
@@ -4473,21 +4559,13 @@ function createSecretRedactionContext(initialValues = []) {
4473
4559
  return exactSecrets.has(value);
4474
4560
  }
4475
4561
  function redactRegisteredSecrets(value) {
4562
+ if (exactSecrets.size === 0) return value;
4476
4563
  let output2 = value;
4477
4564
  for (const secret of exactSecrets) {
4478
- output2 = output2.replace(
4479
- new RegExp(escapeRegExp(secret), "g"),
4480
- SECRET_REDACTION_PLACEHOLDER
4481
- );
4482
- try {
4483
- const encoded = encodeURIComponent(secret);
4484
- if (encoded !== secret) {
4485
- output2 = output2.replace(
4486
- new RegExp(escapeRegExp(encoded), "g"),
4487
- SECRET_REDACTION_PLACEHOLDER
4488
- );
4489
- }
4490
- } catch {
4565
+ for (const { literal, matcher } of matchersForSecret(secret)) {
4566
+ if (!output2.includes(literal)) continue;
4567
+ matcher.lastIndex = 0;
4568
+ output2 = output2.replace(matcher, SECRET_REDACTION_PLACEHOLDER);
4491
4569
  }
4492
4570
  }
4493
4571
  return output2;
@@ -4498,13 +4576,33 @@ function createSecretRedactionContext(initialValues = []) {
4498
4576
  }
4499
4577
  function redact(value) {
4500
4578
  if (typeof value === "string") return redactString2(value);
4501
- if (Array.isArray(value)) return value.map((entry) => redact(entry));
4579
+ if (Array.isArray(value)) {
4580
+ let changed = false;
4581
+ const next = new Array(value.length);
4582
+ for (let index = 0; index < value.length; index += 1) {
4583
+ const entry = value[index];
4584
+ const redacted = redact(entry);
4585
+ next[index] = redacted;
4586
+ if (redacted !== entry) changed = true;
4587
+ }
4588
+ return changed ? next : value;
4589
+ }
4502
4590
  if (value && typeof value === "object") {
4591
+ const prototype = Object.getPrototypeOf(value);
4592
+ let changed = prototype !== Object.prototype && prototype !== null;
4593
+ const source = value;
4594
+ const keys = Object.keys(source);
4595
+ const redactedValues = new Array(keys.length);
4596
+ for (let index = 0; index < keys.length; index += 1) {
4597
+ const key = keys[index];
4598
+ const entry = source[key];
4599
+ const redacted = isSensitiveFieldName(key) ? SECRET_REDACTION_PLACEHOLDER : redact(entry);
4600
+ redactedValues[index] = redacted;
4601
+ if (redacted !== entry) changed = true;
4602
+ }
4603
+ if (!changed) return value;
4503
4604
  return Object.fromEntries(
4504
- Object.entries(value).map(([key, entry]) => [
4505
- key,
4506
- SENSITIVE_FIELD_NAME_RE.test(key) ? SECRET_REDACTION_PLACEHOLDER : redact(entry)
4507
- ])
4605
+ keys.map((key, index) => [key, redactedValues[index]])
4508
4606
  );
4509
4607
  }
4510
4608
  return value;
@@ -4542,9 +4640,10 @@ var CUSTOMER_OUTPUT_VALUE_MAX_BYTES = 5 * 1024 * 1024;
4542
4640
  var CUSTOMER_OUTPUT_TOTAL_MAX_BYTES = 5 * 1024 * 1024;
4543
4641
  var RUNTIME_RECEIPT_OUTPUT_MAX_BYTES = 10 * 1024 * 1024;
4544
4642
  var RUNTIME_RECEIPT_COMPLETION_BUFFER_MAX_BYTES = 32 * 1024 * 1024;
4643
+ var RUNTIME_RECEIPT_CONTROL_BUFFER_MAX_BYTES = 2 * 1024 * 1024;
4545
4644
  var RUNNER_TERMINAL_PUSH_MAX_BODY_BYTES = 16 * 1024 * 1024;
4546
4645
  var RUNTIME_RECEIPT_GATEWAY_BATCH_MAX_BYTES = 12 * 1024 * 1024;
4547
- var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 4 * 1024 * 1024;
4646
+ var RUNTIME_RECEIPT_WRITER_TARGET_BATCH_BYTES = 8 * 1024 * 1024;
4548
4647
  var RUNNER_POST_TERMINAL_DIAGNOSTIC_MAX_BYTES = 64 * 1024;
4549
4648
  var JSON_SIZE_LIMIT_REACHED = Symbol("JSON_SIZE_LIMIT_REACHED");
4550
4649
 
@@ -5352,7 +5451,11 @@ function normalizePlayRunLedgerSnapshot(value, fallback) {
5352
5451
  finiteNumber(value.totalLogCount) ?? logTail.length,
5353
5452
  logTail.length
5354
5453
  ),
5355
- logsTruncated: value.logsTruncated === true,
5454
+ // A persisted snapshot carrying more lines than the tail keeps is
5455
+ // truncated here, whatever the stored flag says. Reporting `false` while
5456
+ // dropping lines is silent loss: a reader would take the tail for the
5457
+ // whole log.
5458
+ logsTruncated: value.logsTruncated === true || logTail.length > LOG_TAIL_LIMIT,
5356
5459
  activeStepId: optionalNullableString(value.activeStepId),
5357
5460
  activeActivityId: optionalNullableString(value.activeActivityId),
5358
5461
  activeArtifactTableNamespace: optionalNullableString(
@@ -6343,28 +6446,42 @@ var PLAY_BACKEND_DESCRIPTORS = {
6343
6446
  // ../play-runtime/runtime-environment.ts
6344
6447
  var PLAY_RUNTIME_ENVIRONMENTS = ["preview"];
6345
6448
  var PLAY_RUNTIME_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]{0,30}$/;
6449
+ var PLAY_RUNTIME_SANDBOX_PLACEMENT_POLICY_PATTERN = /^[a-z][a-z0-9_]*@[1-9][0-9]*$/;
6346
6450
  function normalizePlayRuntimeNamespace(value) {
6347
6451
  if (typeof value !== "string") return null;
6348
6452
  const normalized = value.trim();
6349
6453
  return PLAY_RUNTIME_NAMESPACE_PATTERN.test(normalized) ? normalized : null;
6350
6454
  }
6455
+ function normalizePlayRuntimeSandboxPlacementPolicy(value) {
6456
+ if (typeof value !== "string") return null;
6457
+ const normalized = value.trim();
6458
+ return PLAY_RUNTIME_SANDBOX_PLACEMENT_POLICY_PATTERN.test(normalized) ? normalized : null;
6459
+ }
6351
6460
  function normalizePlayRuntimeSelection(value) {
6352
6461
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
6353
6462
  const record3 = value;
6354
6463
  if (Object.keys(record3).some(
6355
- (key) => key !== "environment" && key !== "namespace" && key !== "backend"
6464
+ (key) => key !== "environment" && key !== "namespace" && key !== "backend" && key !== "sandboxPlacementPolicy"
6356
6465
  ) || record3.environment !== "preview") {
6357
6466
  return null;
6358
6467
  }
6359
6468
  const namespace = normalizePlayRuntimeNamespace(record3.namespace);
6360
6469
  if (!namespace) return null;
6361
- if (record3.backend === void 0) {
6362
- return { environment: "preview", namespace };
6470
+ const sandboxPlacementPolicy = record3.sandboxPlacementPolicy === void 0 ? void 0 : normalizePlayRuntimeSandboxPlacementPolicy(
6471
+ record3.sandboxPlacementPolicy
6472
+ );
6473
+ if (record3.sandboxPlacementPolicy !== void 0 && sandboxPlacementPolicy === null) {
6474
+ return null;
6363
6475
  }
6364
- if (record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
6476
+ if (record3.backend !== void 0 && record3.backend !== PLAY_RUNTIME_BACKENDS.daytona && record3.backend !== PLAY_RUNTIME_BACKENDS.modal) {
6365
6477
  return null;
6366
6478
  }
6367
- return { environment: "preview", namespace, backend: record3.backend };
6479
+ return {
6480
+ environment: "preview",
6481
+ namespace,
6482
+ ...record3.backend === void 0 ? {} : { backend: record3.backend },
6483
+ ...sandboxPlacementPolicy ? { sandboxPlacementPolicy } : {}
6484
+ };
6368
6485
  }
6369
6486
  function normalizePlayRuntimeEnvironment(value) {
6370
6487
  return typeof value === "string" && PLAY_RUNTIME_ENVIRONMENTS.includes(value) ? value : null;
@@ -6458,7 +6575,7 @@ function resolvePlayRunRuntimeSelection(request) {
6458
6575
  const runtime = normalizePlayRuntimeSelection(request.runtime);
6459
6576
  if (!runtime) {
6460
6577
  throw new DeeplineError(
6461
- 'runtime must be { environment: "preview", namespace, backend?: "daytona" | "modal" } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
6578
+ 'runtime must be { environment: "preview", namespace, backend?: "daytona" | "modal", sandboxPlacementPolicy?: "policy_name@1" } with namespace matching ^[a-z][a-z0-9-]{0,30}$.',
6462
6579
  void 0,
6463
6580
  "INVALID_RUNTIME_SELECTION"
6464
6581
  );
@@ -6468,11 +6585,15 @@ function resolvePlayRunRuntimeSelection(request) {
6468
6585
  const configured = process.env.DEEPLINE_RUNTIME_ENVIRONMENT?.trim();
6469
6586
  const configuredNamespace = process.env.DEEPLINE_RUNTIME_NAMESPACE?.trim();
6470
6587
  const configuredToken = process.env.DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN?.trim();
6588
+ const configuredPlacementPolicy = process.env.DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY?.trim();
6471
6589
  if (!configured) {
6472
- if (configuredNamespace || configuredToken) {
6590
+ if (configuredNamespace || configuredToken || configuredPlacementPolicy) {
6473
6591
  const present = [];
6474
6592
  if (configuredNamespace) present.push("DEEPLINE_RUNTIME_NAMESPACE");
6475
6593
  if (configuredToken) present.push("DEEPLINE_RUNTIME_ENVIRONMENT_TOKEN");
6594
+ if (configuredPlacementPolicy) {
6595
+ present.push("DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY");
6596
+ }
6476
6597
  const isPlural = present.length > 1;
6477
6598
  throw new DeeplineError(
6478
6599
  [
@@ -6503,18 +6624,28 @@ function resolvePlayRunRuntimeSelection(request) {
6503
6624
  "INVALID_RUNTIME_NAMESPACE"
6504
6625
  );
6505
6626
  }
6506
- const configuredBackend = process.env.DEEPLINE_PLAY_RUNNER_BACKEND?.trim();
6507
- if (!configuredBackend) {
6508
- return { environment, namespace };
6509
- }
6510
- if (configuredBackend !== "daytona" && configuredBackend !== "modal") {
6627
+ const configuredBackendValue = process.env.DEEPLINE_PLAY_RUNNER_BACKEND?.trim();
6628
+ const configuredBackend = configuredBackendValue === "daytona" || configuredBackendValue === "modal" ? configuredBackendValue : void 0;
6629
+ if (configuredBackendValue && !configuredBackend) {
6511
6630
  throw new DeeplineError(
6512
- `DEEPLINE_PLAY_RUNNER_BACKEND must be daytona or modal for preview runtime selection. Received "${configuredBackend}".`,
6631
+ `DEEPLINE_PLAY_RUNNER_BACKEND must be daytona or modal for preview runtime selection. Received "${configuredBackendValue}".`,
6513
6632
  void 0,
6514
6633
  "INVALID_RUNTIME_BACKEND"
6515
6634
  );
6516
6635
  }
6517
- return { environment, namespace, backend: configuredBackend };
6636
+ if (configuredPlacementPolicy && !normalizePlayRuntimeSandboxPlacementPolicy(configuredPlacementPolicy)) {
6637
+ throw new DeeplineError(
6638
+ `DEEPLINE_RUNTIME_SANDBOX_PLACEMENT_POLICY must be a versioned placement policy id such as daytona_only@1. Received "${configuredPlacementPolicy}".`,
6639
+ void 0,
6640
+ "INVALID_RUNTIME_SANDBOX_PLACEMENT_POLICY"
6641
+ );
6642
+ }
6643
+ return {
6644
+ environment,
6645
+ namespace,
6646
+ ...configuredBackend ? { backend: configuredBackend } : {},
6647
+ ...configuredPlacementPolicy ? { sandboxPlacementPolicy: configuredPlacementPolicy } : {}
6648
+ };
6518
6649
  }
6519
6650
  function runtimeSelectionHeaders(runtime) {
6520
6651
  if (!runtime) return void 0;
@@ -16815,6 +16946,70 @@ var import_esbuild = require("esbuild");
16815
16946
  // ../plays/authoring-contract.ts
16816
16947
  var import_typebox = require("@sinclair/typebox");
16817
16948
  var import_value = require("@sinclair/typebox/value");
16949
+ var SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS = [
16950
+ 1,
16951
+ 2,
16952
+ 3,
16953
+ 4,
16954
+ 5,
16955
+ 6,
16956
+ 7,
16957
+ 8
16958
+ ];
16959
+ var PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS = [
16960
+ {
16961
+ changed: "Historical extraction semantics. Invalid or unresolved optional authoring fields may normalize to absence.",
16962
+ compatibilityOwner: "Plays Runtime",
16963
+ newWritesEnd: "2026-11-03",
16964
+ readerRemoval: "After every retained edition 1 artifact has a materialized admitted snapshot."
16965
+ },
16966
+ {
16967
+ changed: "Pins admitted authoring snapshots and rejects ambiguous billing, secret, webhook, fetch, timeout, receipt-wait, and freshness contracts.",
16968
+ compatibilityOwner: "Plays Runtime",
16969
+ newWritesEnd: "2026-08-03",
16970
+ readerRemoval: "After every retained edition 2 artifact has an admitted input schema or has been republished."
16971
+ },
16972
+ {
16973
+ changed: "Materializes the declared input schema in the admitted snapshot so launch never reparses current source.",
16974
+ compatibilityOwner: "Plays Runtime",
16975
+ newWritesEnd: "2026-08-19",
16976
+ readerRemoval: null
16977
+ },
16978
+ {
16979
+ changed: "ctx.secrets.get(name) resolves an allowed secret to a plaintext string for ordinary Play code. Editions 1\u20133 retain opaque secret handles.",
16980
+ compatibilityOwner: "Plays Runtime",
16981
+ newWritesEnd: null,
16982
+ readerRemoval: null
16983
+ },
16984
+ {
16985
+ changed: "ctx.fetch throws a typed, redacted CtxFetchHttpError for non-2xx responses. Editions 1\u20134 continue to return the response record for every HTTP status.",
16986
+ compatibilityOwner: "Plays Runtime",
16987
+ newWritesEnd: null,
16988
+ readerRemoval: null
16989
+ },
16990
+ {
16991
+ changed: "Adds static cron input and rejects unknown definePlay and binding fields during new admission. Editions 1\u20135 retain their admitted binding semantics.",
16992
+ compatibilityOwner: "Plays Runtime",
16993
+ newWritesEnd: null,
16994
+ readerRemoval: null
16995
+ },
16996
+ {
16997
+ changed: "Slack HITL calls that omit timeout wait one week. Editions 1\u20136 retain the historical 24-hour default.",
16998
+ compatibilityOwner: "Plays Runtime",
16999
+ newWritesEnd: null,
17000
+ readerRemoval: null
17001
+ },
17002
+ {
17003
+ changed: "Lets an inline scalar child execute without a stored static pipeline. Dataset creation and suspension remain rejected by the authoritative runtime capability boundary; editions 1\u20137 retain static-contract preflight rejection.",
17004
+ compatibilityOwner: "Plays Runtime",
17005
+ newWritesEnd: null,
17006
+ readerRemoval: null
17007
+ }
17008
+ ];
17009
+ var PLAY_AUTHORING_CONTRACT_CHANGELOG = SUPPORTED_PLAY_AUTHORING_CONTRACT_EDITIONS.map((edition, index) => ({
17010
+ edition,
17011
+ ...PLAY_AUTHORING_CONTRACT_CHANGELOG_DETAILS[index]
17012
+ }));
16818
17013
  var PLAY_SQL_LISTENER_WHERE_OPERATORS = [
16819
17014
  "eq",
16820
17015
  "neq",
@@ -23460,7 +23655,7 @@ function assertPlayWaitNotTimedOut(input2) {
23460
23655
  if (input2.waitTimeoutMs !== null && Date.now() - input2.startedAt >= input2.waitTimeoutMs) {
23461
23656
  const hasRealRunId = input2.workflowId.length > 0 && input2.workflowId !== "pending";
23462
23657
  const phaseSuffix = input2.lastPhase && input2.lastPhase.trim() ? ` (last observed phase: ${input2.lastPhase.trim()})` : "";
23463
- const tailHint = hasRealRunId ? ` Run 'deepline runs tail ${input2.workflowId} --json' to inspect it, or rerun with a larger --tail-timeout-ms.` : ` The run never reported a workflow id \u2014 the start request likely failed before reaching the scheduler. Check server logs and rerun with a larger --tail-timeout-ms.`;
23658
+ 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.`;
23464
23659
  throw new DeeplineError(
23465
23660
  `Timed out waiting for play ${hasRealRunId ? input2.workflowId : "<no run id>"} after ${Math.ceil(input2.waitTimeoutMs / 1e3)}s${phaseSuffix}.${tailHint}`,
23466
23661
  void 0,
@@ -25025,6 +25220,18 @@ function buildRunPackageTextLines(packaged) {
25025
25220
  const lines = [
25026
25221
  `${status === "completed" ? "\u2713" : status === "failed" ? "\u2717" : "\u2022"} ${status} ${runId}`
25027
25222
  ];
25223
+ const isRuntimeTimeout = status === "failed" && (readRecordArray(packaged.errors).some(
25224
+ (error) => error.code === "RUNTIME_LIMIT_EXCEEDED"
25225
+ ) || typeof run.error === "string" && /RUNTIME_LIMIT_EXCEEDED/.test(run.error));
25226
+ if (isRuntimeTimeout) {
25227
+ lines.push(" RUNTIME_LIMIT_EXCEEDED: the Play stopped before returning.");
25228
+ lines.push(
25229
+ " Inspect the dataset catalog below and export saved data before rerunning unfinished work."
25230
+ );
25231
+ lines.push(
25232
+ " Adjust runtime.timeout in the Play (maximum 4h), remove the override for the 30-minute default, or use fewer rows."
25233
+ );
25234
+ }
25028
25235
  const runError = typeof run.error === "string" && run.error.trim() ? run.error.trim() : null;
25029
25236
  if (runError && (status === "failed" || status === "cancelled")) {
25030
25237
  lines.push(` error: ${truncateErrorForDisplay(runError, runId)}`);
@@ -25101,14 +25308,19 @@ function buildRunPackageTextLines(packaged) {
25101
25308
  const legacyExportCommand = hasCatalogExportAction ? null : actionToCommand(next.export);
25102
25309
  const runAgainCommand = typeof next.run === "string" && next.run.trim() ? next.run.trim() : null;
25103
25310
  if (inspectCommand) lines.push(` inspect: ${inspectCommand}`);
25104
- if (fullResultCommand) lines.push(` full result: ${fullResultCommand}`);
25311
+ if (fullResultCommand)
25312
+ lines.push(
25313
+ ` ${isRuntimeTimeout ? "full run details" : "full result"}: ${fullResultCommand}`
25314
+ );
25105
25315
  if (logsCommand) lines.push(` logs: ${logsCommand}`);
25106
25316
  if (billingCommand) lines.push(` billing: ${billingCommand}`);
25107
25317
  if (legacyExportCommand) {
25108
25318
  lines.push(` export CSV: ${legacyExportCommand}`);
25109
25319
  }
25110
25320
  if (runAgainCommand) {
25111
- lines.push(" run again (completed work is reused):");
25321
+ lines.push(
25322
+ isRuntimeTimeout ? " run again after adjusting the deadline or batch (compatible completed work may be reused):" : " run again (completed work is reused):"
25323
+ );
25112
25324
  lines.push(` ${runAgainCommand}`);
25113
25325
  }
25114
25326
  return lines;