deepline 0.1.211 → 0.1.213

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 (54) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +317 -340
  2. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/customer-console.ts +23 -0
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +1 -1
  4. package/dist/bundling-sources/sdk/src/client.ts +118 -3
  5. package/dist/bundling-sources/sdk/src/index.ts +2 -0
  6. package/dist/bundling-sources/sdk/src/play.ts +8 -1
  7. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +1 -1
  8. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +11 -1
  9. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  10. package/dist/bundling-sources/sdk/src/types.ts +47 -0
  11. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +302 -30
  12. package/dist/bundling-sources/shared_libs/play-runtime/child-execution-placement.ts +14 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/child-execution-strategy.ts +57 -23
  14. package/dist/bundling-sources/shared_libs/play-runtime/completed-receipt-cache.ts +166 -0
  15. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +164 -121
  16. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +2 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +42 -1
  18. package/dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts +10 -4
  19. package/dist/bundling-sources/shared_libs/play-runtime/db-session.ts +9 -0
  20. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +163 -7
  21. package/dist/bundling-sources/shared_libs/play-runtime/gateway-auth-session.ts +93 -0
  22. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +14 -2
  23. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +4 -2
  24. package/dist/bundling-sources/shared_libs/play-runtime/play-call-execution.ts +1 -0
  25. package/dist/bundling-sources/shared_libs/play-runtime/receipt-completion-sink.ts +16 -1
  26. package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +21 -1
  27. package/dist/bundling-sources/shared_libs/play-runtime/receipt-state-sink.ts +10 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +80 -3
  29. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +128 -6
  30. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +7 -0
  31. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +94 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +91 -6
  33. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +19 -10
  34. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +540 -92
  35. package/dist/bundling-sources/shared_libs/play-runtime/runtime-postgres-admission.ts +162 -0
  36. package/dist/bundling-sources/shared_libs/play-runtime/secret-capability.ts +18 -4
  37. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +16 -17
  38. package/dist/bundling-sources/shared_libs/play-runtime/tool-execute-retry-policy.ts +29 -9
  39. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +22 -1
  40. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +1 -0
  41. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +79 -1
  42. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +2 -4
  43. package/dist/cli/index.js +637 -229
  44. package/dist/cli/index.mjs +637 -229
  45. package/dist/{compiler-manifest-j6z8qzpd.d.mts → compiler-manifest-BhgZ23A4.d.mts} +1 -0
  46. package/dist/{compiler-manifest-j6z8qzpd.d.ts → compiler-manifest-BhgZ23A4.d.ts} +1 -0
  47. package/dist/index.d.mts +84 -11
  48. package/dist/index.d.ts +84 -11
  49. package/dist/index.js +225 -43
  50. package/dist/index.mjs +225 -43
  51. package/dist/plays/bundle-play-file.d.mts +2 -2
  52. package/dist/plays/bundle-play-file.d.ts +2 -2
  53. package/dist/plays/bundle-play-file.mjs +65 -4
  54. package/package.json +1 -1
@@ -0,0 +1,23 @@
1
+ export function formatCustomerConsoleValue(value: unknown): string {
2
+ if (typeof value === 'string') return value;
3
+ try {
4
+ if (value instanceof Error) return value.stack ?? value.message;
5
+ if (value && typeof value === 'object') {
6
+ const seen = new WeakSet<object>();
7
+ const serialized = JSON.stringify(value, (_key, nested) => {
8
+ if (typeof nested === 'symbol' || typeof nested === 'bigint') {
9
+ return nested.toString();
10
+ }
11
+ if (nested && typeof nested === 'object') {
12
+ if (seen.has(nested)) return '[Circular]';
13
+ seen.add(nested);
14
+ }
15
+ return nested;
16
+ });
17
+ if (serialized !== undefined) return serialized;
18
+ }
19
+ return String(value);
20
+ } catch {
21
+ return '[Unprintable]';
22
+ }
23
+ }
@@ -229,7 +229,7 @@ type WorkerToolCompletionResult =
229
229
  const WORKER_TOOL_BATCH_GRACE_MS = 250;
230
230
  const COMPLETE_RECEIPT_RETRY_BACKOFFS_MS = [1_000, 3_000, 9_000] as const;
231
231
  const COMPLETE_RECEIPT_RETRY_MIN_HEADROOM_MS = 10_000;
232
- export const WORKER_TOOL_COMPLETE_RECEIPTS_MAX_BATCH_BYTES = 8 * 1024 * 1024;
232
+ export const WORKER_TOOL_COMPLETE_RECEIPTS_MAX_BATCH_BYTES = 32 * 1024 * 1024;
233
233
  export const WORKER_TOOL_COMPLETE_RECEIPTS_MAX_BATCH_MEMBERS = 500;
234
234
  export const WORKER_TOOL_RECEIPT_RECOVERY_MAX_CONCURRENT_READS = 25;
235
235
 
@@ -282,9 +282,23 @@ export type RunsListOptions = {
282
282
  limit?: number;
283
283
  };
284
284
 
285
+ /** Options for `client.runs.get(...)`. */
286
+ export type RunsGetOptions = {
287
+ /** Return the raw status payload instead of the compact package. */
288
+ full?: boolean;
289
+ /** Attach a bounded end-of-stream window for a failed run. */
290
+ failedLogs?: boolean;
291
+ /** Requested failed-log lines to attach (default 20, hard-capped at 20). */
292
+ failedLogLimit?: number;
293
+ };
294
+
295
+ const RUNS_FAILED_LOG_LIMIT = 20;
296
+
285
297
  /** Streaming options for `client.runs.tail(...)`. */
286
298
  export type RunsTailOptions = {
287
299
  signal?: AbortSignal;
300
+ /** Observe each canonical live event while `tail` waits for terminal state. */
301
+ onEvent?: (event: PlayLiveEvent) => void;
288
302
  /**
289
303
  * Called before each stream reconnect. Server stream windows are finite, so
290
304
  * long runs reconnect with backoff until a terminal status is observed.
@@ -308,6 +322,8 @@ export type RunsLogsOptions = {
308
322
  limit?: number;
309
323
  /** Fetch every stored log line, paginating to the full totalCount. */
310
324
  all?: boolean;
325
+ /** Select the bounded failure view; truncated runs degrade explicitly. */
326
+ failed?: boolean;
311
327
  };
312
328
 
313
329
  /** Persisted log response for one play run. */
@@ -320,6 +336,14 @@ export type RunsLogsResult = {
320
336
  truncated: boolean;
321
337
  hasMore: boolean;
322
338
  entries: string[];
339
+ /** Selected public log view. */
340
+ view?: 'tail' | 'failed' | 'all';
341
+ /** Whether entries are terminal context or the last pre-truncation lines. */
342
+ association?: 'terminal_failure_window' | 'retained_before_truncation';
343
+ /** Loud explanation when the terminal failure window was not retained. */
344
+ warning?: string;
345
+ /** Exact follow-up command when the selected view is degraded. */
346
+ next?: { logs: string };
323
347
  /**
324
348
  * True when the run crossed the Run Log Stream retention cap: `totalCount`
325
349
  * keeps counting, but stored line bodies end at a loud truncation marker.
@@ -342,6 +366,10 @@ type RunLogsPageResponse = {
342
366
  lastSeq: number | null;
343
367
  hasMore: boolean;
344
368
  nextAfterSeq: number | null;
369
+ view?: 'failed';
370
+ association?: 'terminal_failure_window' | 'retained_before_truncation';
371
+ warning?: string;
372
+ next?: { logs: string };
345
373
  };
346
374
 
347
375
  /** One persisted runtime-sheet row returned by `client.runs.exportDatasetRows(...)`. */
@@ -395,7 +423,7 @@ export type PlaySecretMetadata = {
395
423
  */
396
424
  export type RunsNamespace = {
397
425
  /** Get current run status by public run id. */
398
- get: (runId: string, options?: { full?: boolean }) => Promise<PlayStatus>;
426
+ get: (runId: string, options?: RunsGetOptions) => Promise<PlayStatus>;
399
427
  /** List runs for one play, optionally filtered by status. */
400
428
  list: (options: RunsListOptions) => Promise<PlayRunListItem[]>;
401
429
  /** Stream run events and return the latest/terminal run status. */
@@ -2469,7 +2497,7 @@ export class DeeplineClient {
2469
2497
  */
2470
2498
  async getRunStatus(
2471
2499
  runId: string,
2472
- options?: { full?: boolean },
2500
+ options?: RunsGetOptions,
2473
2501
  ): Promise<PlayStatus> {
2474
2502
  const params = new URLSearchParams();
2475
2503
  if (options?.full === true) {
@@ -2479,7 +2507,55 @@ export class DeeplineClient {
2479
2507
  const response = await this.http.get<Record<string, unknown>>(
2480
2508
  `/api/v2/runs/${encodeURIComponent(runId)}${query}`,
2481
2509
  );
2482
- return normalizePlayStatus(response);
2510
+ const status = normalizePlayStatus(response);
2511
+ if (options?.failedLogs !== true || status.status !== 'failed') {
2512
+ return status;
2513
+ }
2514
+ const requestedFailedLogLimit =
2515
+ typeof options.failedLogLimit === 'number' &&
2516
+ Number.isFinite(options.failedLogLimit)
2517
+ ? Math.max(1, Math.floor(options.failedLogLimit))
2518
+ : RUNS_FAILED_LOG_LIMIT;
2519
+ let failedLogs: RunsLogsResult;
2520
+ let failedLogsLoaded = true;
2521
+ try {
2522
+ failedLogs = await this.getRunLogs(runId, {
2523
+ failed: true,
2524
+ limit: Math.min(RUNS_FAILED_LOG_LIMIT, requestedFailedLogLimit),
2525
+ });
2526
+ } catch (error) {
2527
+ failedLogsLoaded = false;
2528
+ const retryCommand = `deepline runs get ${runId} --log-failed --json`;
2529
+ const reason =
2530
+ error instanceof Error && error.message.trim()
2531
+ ? ` (${error.message.trim().slice(0, 500)})`
2532
+ : '';
2533
+ failedLogs = {
2534
+ runId,
2535
+ totalCount: 0,
2536
+ returnedCount: 0,
2537
+ firstSequence: null,
2538
+ lastSequence: null,
2539
+ truncated: false,
2540
+ hasMore: false,
2541
+ entries: [],
2542
+ view: 'failed',
2543
+ warning: `Failed logs could not be loaded${reason}. The run status and persisted datasets are still available.`,
2544
+ next: { logs: retryCommand },
2545
+ };
2546
+ }
2547
+ return {
2548
+ ...status,
2549
+ failedLogs: {
2550
+ ...failedLogs,
2551
+ view: 'failed' as const,
2552
+ ...(failedLogsLoaded
2553
+ ? {
2554
+ association: failedLogs.association ?? 'terminal_failure_window',
2555
+ }
2556
+ : {}),
2557
+ },
2558
+ };
2483
2559
  }
2484
2560
 
2485
2561
  /**
@@ -2657,6 +2733,7 @@ export class DeeplineClient {
2657
2733
  onNotice: options?.onNotice,
2658
2734
  fallback: 'none',
2659
2735
  })) {
2736
+ options?.onEvent?.(event);
2660
2737
  const status = updatePlayLiveStatusState(state, event);
2661
2738
  if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
2662
2739
  continue;
@@ -2725,6 +2802,7 @@ export class DeeplineClient {
2725
2802
  mode: 'cli',
2726
2803
  signal: options?.signal,
2727
2804
  })) {
2805
+ options?.onEvent?.(event);
2728
2806
  sawEvent = true;
2729
2807
  const status = updatePlayLiveStatusState(state, event);
2730
2808
  if (!status || !TERMINAL_PLAY_STATUSES.has(status.status)) {
@@ -2786,6 +2864,42 @@ export class DeeplineClient {
2786
2864
  runId: string,
2787
2865
  options?: RunsLogsOptions,
2788
2866
  ): Promise<RunsLogsResult> {
2867
+ if (options?.all === true && options.failed === true) {
2868
+ throw new DeeplineError(
2869
+ 'runs.logs cannot combine all and failed views.',
2870
+ undefined,
2871
+ 'INVALID_RUN_LOG_VIEW',
2872
+ );
2873
+ }
2874
+ if (options?.failed === true) {
2875
+ const requestedLimit =
2876
+ typeof options.limit === 'number' &&
2877
+ Number.isFinite(options.limit) &&
2878
+ options.limit > 0
2879
+ ? Math.trunc(options.limit)
2880
+ : RUNS_FAILED_LOG_LIMIT;
2881
+ const failedLimit = Math.min(RUNS_FAILED_LOG_LIMIT, requestedLimit);
2882
+ const page = await this.http.get<RunLogsPageResponse>(
2883
+ `/api/v2/runs/${encodeURIComponent(runId)}/logs?view=failed&limit=${failedLimit}`,
2884
+ );
2885
+ return {
2886
+ runId: page.runId,
2887
+ totalCount: page.totalLogCount,
2888
+ returnedCount: page.entries.length,
2889
+ firstSequence: page.firstSeq,
2890
+ lastSequence: page.lastSeq,
2891
+ // The failed view is a complete designed window, not a pageable slice.
2892
+ // `truncated` means retention loss here; association/warning explain it.
2893
+ truncated: page.logsTruncated === true,
2894
+ hasMore: false,
2895
+ entries: page.entries.map((entry) => entry.line),
2896
+ view: page.view ?? 'failed',
2897
+ association: page.association ?? 'terminal_failure_window',
2898
+ ...(page.warning ? { warning: page.warning } : {}),
2899
+ ...(page.next ? { next: page.next } : {}),
2900
+ ...(page.logsTruncated ? { logsTruncated: true } : {}),
2901
+ };
2902
+ }
2789
2903
  const limit = options?.all
2790
2904
  ? Number.MAX_SAFE_INTEGER
2791
2905
  : typeof options?.limit === 'number' &&
@@ -2830,6 +2944,7 @@ export class DeeplineClient {
2830
2944
  truncated: entries.length < probe.totalLogCount,
2831
2945
  hasMore: lastSequence !== null && lastSequence < lastStoredSeq,
2832
2946
  entries: entries.map((entry) => entry.line),
2947
+ view: options?.all ? 'all' : 'tail',
2833
2948
  ...(probe.logsTruncated ? { logsTruncated: true } : {}),
2834
2949
  };
2835
2950
  }
@@ -184,6 +184,8 @@ export type {
184
184
  PreviousCell,
185
185
  PlayDataset,
186
186
  PlayDatasetInput,
187
+ PlayCallExecution,
188
+ PlayCallOptions,
187
189
  PlayStepProgramStep,
188
190
  PrebuiltPlayRef,
189
191
  StepOptions,
@@ -114,6 +114,13 @@ import type {
114
114
  } from './types.js';
115
115
  import type { ToolExecution } from './client.js';
116
116
 
117
+ export type PlayCallExecution = 'inline' | 'child-workflow';
118
+
119
+ export interface PlayCallOptions {
120
+ description?: string;
121
+ execution?: PlayCallExecution;
122
+ }
123
+
117
124
  /**
118
125
  * Optional trigger bindings for a play.
119
126
  *
@@ -891,7 +898,7 @@ export interface DeeplinePlayRuntimeContext {
891
898
  key: string,
892
899
  playRef: string | PlayReferenceLike,
893
900
  input: Record<string, unknown>,
894
- options: { description: string },
901
+ options?: PlayCallOptions,
895
902
  ): Promise<TOutput>;
896
903
 
897
904
  /**
@@ -39,7 +39,7 @@ export type {
39
39
 
40
40
  export { extractDefinedPlayName } from '../../../shared_libs/plays/bundling/index.js';
41
41
 
42
- const PLAY_BUNDLE_CACHE_VERSION = 30;
42
+ const PLAY_BUNDLE_CACHE_VERSION = 31;
43
43
  const MODULE_DIR = dirname(fileURLToPath(import.meta.url));
44
44
  const SDK_PACKAGE_ROOT = resolve(MODULE_DIR, '..', '..');
45
45
  const SOURCE_REPO_ROOT = resolve(SDK_PACKAGE_ROOT, '..');
@@ -274,6 +274,7 @@ export async function harnessStartSheetDataset(input: {
274
274
  attemptExpiresAt?: string | null;
275
275
  attemptSeq?: number | null;
276
276
  attemptLeaseTtlMs?: number | null;
277
+ writeVersion?: number | null;
277
278
  inputOffset?: number;
278
279
  force?: boolean;
279
280
  userEmail?: string | null;
@@ -288,6 +289,7 @@ export async function harnessStartSheetDataset(input: {
288
289
  attemptOwnerRunId?: string;
289
290
  attemptExpiresAt?: string;
290
291
  attemptSeq?: number;
292
+ writeVersion?: number;
291
293
  timings?: Array<Record<string, unknown>>;
292
294
  }> {
293
295
  return requireBinding().startSheetDataset(input);
@@ -312,8 +314,16 @@ export async function harnessPersistCompletedSheetRows(input: {
312
314
  attemptOwnerRunId?: string | null;
313
315
  attemptExpiresAt?: string | null;
314
316
  attemptSeq?: number | null;
317
+ writeVersion?: number | null;
315
318
  forceFailedRows?: boolean;
316
319
  userEmail?: string | null;
317
- }): Promise<{ ok: true; rowsWritten: number; tableNamespace: string }> {
320
+ }): Promise<{
321
+ ok: true;
322
+ rowsWritten: number;
323
+ tableNamespace: string;
324
+ fencedKeys?: string[];
325
+ staleDropped?: number;
326
+ staleDroppedKeys?: string[];
327
+ }> {
318
328
  return requireBinding().persistCompletedMapRows(input);
319
329
  }
@@ -106,10 +106,10 @@ export const SDK_RELEASE = {
106
106
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
107
107
  // fields shipped in 0.1.153.
108
108
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
109
- version: '0.1.211',
109
+ version: '0.1.213',
110
110
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
111
111
  supportPolicy: {
112
- latest: '0.1.211',
112
+ latest: '0.1.213',
113
113
  minimumSupported: '0.1.53',
114
114
  deprecatedBelow: '0.1.53',
115
115
  commandMinimumSupported: [
@@ -463,6 +463,14 @@ export type PlayRunActionPackage =
463
463
  runId: string;
464
464
  datasetPath: string;
465
465
  format: 'csv';
466
+ }
467
+ | {
468
+ kind: 'deepline_run_logs';
469
+ runId: string;
470
+ view: 'failed' | 'tail';
471
+ limit: number;
472
+ command: string;
473
+ api: { method: 'GET'; path: string };
466
474
  };
467
475
 
468
476
  /**
@@ -493,11 +501,30 @@ export interface PlayRunPackage {
493
501
  steps: Array<Record<string, unknown>>;
494
502
  /** Named output summaries, including dataset handles and scalar outputs. */
495
503
  outputs: Record<string, Record<string, unknown>>;
504
+ /** Every durable Dataset Handle explicitly registered by this run. */
505
+ datasets?: Array<{
506
+ kind: 'dataset';
507
+ datasetId?: string;
508
+ path: string;
509
+ tableNamespace?: string;
510
+ rowCount?: number;
511
+ recovered?: true;
512
+ preview?: Record<string, unknown>;
513
+ actions?: Record<string, PlayRunActionPackage>;
514
+ }>;
515
+ /** Small retained tail of customer and runtime logs; fetch the full stream through `runs.logs`. */
516
+ logs?: {
517
+ tail: string[];
518
+ totalCount: number;
519
+ returnedCount: number;
520
+ truncated?: boolean;
521
+ };
496
522
  /** Follow-up actions a caller can perform against the run. */
497
523
  next?: {
498
524
  inspect?: PlayRunActionPackage;
499
525
  export?: PlayRunActionPackage;
500
526
  query?: PlayRunActionPackage;
527
+ logs?: PlayRunActionPackage;
501
528
  };
502
529
  }
503
530
 
@@ -524,6 +551,8 @@ export interface PlayStatus {
524
551
  apiVersion?: number;
525
552
  /** Saved play name for this run, when available. */
526
553
  name?: string;
554
+ /** Exact saved revision launched for this run, when applicable. */
555
+ revisionId?: string;
527
556
  /** Alias for `name` used by run/result APIs. */
528
557
  playName?: string;
529
558
  /** Dashboard URL for inspecting the play and its run output in the app. */
@@ -564,6 +593,24 @@ export interface PlayStatus {
564
593
  } | null;
565
594
  /** Structured follow-up actions for inspect/query/export. */
566
595
  next?: PlayRunPackage['next'] | Record<string, unknown>;
596
+ /** Bounded terminal-failure log window requested by `runs.get`. */
597
+ failedLogs?: {
598
+ runId: string;
599
+ totalCount: number;
600
+ returnedCount: number;
601
+ firstSequence: number | null;
602
+ lastSequence: number | null;
603
+ truncated: boolean;
604
+ hasMore: boolean;
605
+ entries: string[];
606
+ view?: 'failed';
607
+ association?: 'terminal_failure_window' | 'retained_before_truncation';
608
+ warning?: string;
609
+ next?: { logs: string };
610
+ logsTruncated?: boolean;
611
+ };
612
+ /** Exact ordinary `plays run` command that can rerun a failed execution. */
613
+ rerunCommand?: string;
567
614
  }
568
615
 
569
616
  export type LiveEventScope = 'play' | 'agent';