deepline 0.1.21 → 0.1.22

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.
@@ -34,6 +34,7 @@
34
34
  * @module
35
35
  */
36
36
  import { resolveConfig } from './config.js';
37
+ import { DeeplineError } from './errors.js';
37
38
  import { HttpClient } from './http.js';
38
39
  import type {
39
40
  DeeplineClientOptions,
@@ -88,11 +89,7 @@ export type RunsListOptions = {
88
89
  };
89
90
 
90
91
  export type RunsTailOptions = {
91
- cursor?: string | number;
92
- afterLogIndex?: number;
93
- waitMs?: number;
94
- terminalOnly?: boolean;
95
- compact?: boolean;
92
+ signal?: AbortSignal;
96
93
  };
97
94
 
98
95
  export type RunsLogsOptions = {
@@ -127,11 +124,7 @@ function isRecord(value: unknown): value is Record<string, unknown> {
127
124
 
128
125
  function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
129
126
  const status =
130
- typeof raw.status === 'string'
131
- ? raw.status
132
- : typeof raw.temporalStatus === 'string'
133
- ? mapLegacyTemporalStatus(raw.temporalStatus)
134
- : 'running';
127
+ typeof raw.status === 'string' ? raw.status : 'running';
135
128
  const runId =
136
129
  typeof raw.runId === 'string'
137
130
  ? raw.runId
@@ -145,24 +138,6 @@ function normalizePlayStatus(raw: Record<string, unknown>): PlayStatus {
145
138
  };
146
139
  }
147
140
 
148
- function mapLegacyTemporalStatus(status: string): PlayStatus['status'] {
149
- switch (status.trim().toUpperCase()) {
150
- case 'PENDING':
151
- return 'queued';
152
- case 'COMPLETED':
153
- return 'completed';
154
- case 'FAILED':
155
- return 'failed';
156
- case 'CANCELLED':
157
- case 'TERMINATED':
158
- case 'TIMED_OUT':
159
- return 'cancelled';
160
- case 'RUNNING':
161
- default:
162
- return 'running';
163
- }
164
- }
165
-
166
141
  function decodeBase64Bytes(value: string): Uint8Array {
167
142
  const binary = atob(value);
168
143
  const bytes = new Uint8Array(binary.length);
@@ -172,6 +147,131 @@ function decodeBase64Bytes(value: string): Uint8Array {
172
147
  return bytes;
173
148
  }
174
149
 
150
+ function readStringArray(value: unknown): string[] {
151
+ return Array.isArray(value)
152
+ ? value.filter((line): line is string => typeof line === 'string')
153
+ : [];
154
+ }
155
+
156
+ type PlayLiveStatusState = {
157
+ runId: string;
158
+ status: PlayStatus['status'];
159
+ logs: string[];
160
+ result?: unknown;
161
+ error?: string;
162
+ latest: PlayStatus | null;
163
+ };
164
+
165
+ function getPlayLiveEventPayload(event: PlayLiveEvent): Record<string, unknown> {
166
+ return event.payload && typeof event.payload === 'object'
167
+ ? (event.payload as Record<string, unknown>)
168
+ : {};
169
+ }
170
+
171
+ function normalizeLiveStatus(value: unknown): PlayStatus['status'] | null {
172
+ if (
173
+ value === 'queued' ||
174
+ value === 'running' ||
175
+ value === 'waiting' ||
176
+ value === 'completed' ||
177
+ value === 'failed' ||
178
+ value === 'cancelled'
179
+ ) {
180
+ return value;
181
+ }
182
+ return null;
183
+ }
184
+
185
+ function updatePlayLiveStatusState(
186
+ state: PlayLiveStatusState,
187
+ event: PlayLiveEvent,
188
+ ): PlayStatus | null {
189
+ const payload = getPlayLiveEventPayload(event);
190
+ if (event.type === 'play.run.log') {
191
+ state.logs.push(...readStringArray(payload.lines));
192
+ return null;
193
+ }
194
+ if (
195
+ event.type !== 'play.run.snapshot' &&
196
+ event.type !== 'play.run.status' &&
197
+ event.type !== 'play.run.final_status'
198
+ ) {
199
+ return null;
200
+ }
201
+
202
+ const runId =
203
+ typeof payload.runId === 'string' && payload.runId
204
+ ? payload.runId
205
+ : state.runId;
206
+ const status = normalizeLiveStatus(payload.status) ?? state.status;
207
+ const logs = readStringArray(payload.logs);
208
+ if (logs.length > 0 || event.type === 'play.run.snapshot') {
209
+ state.logs = logs;
210
+ }
211
+ if ('result' in payload) {
212
+ state.result = payload.result;
213
+ }
214
+ if (typeof payload.error === 'string' && payload.error.trim()) {
215
+ state.error = payload.error;
216
+ }
217
+ state.runId = runId;
218
+ state.status = status;
219
+
220
+ const progressRecord =
221
+ payload.progress &&
222
+ typeof payload.progress === 'object' &&
223
+ !Array.isArray(payload.progress)
224
+ ? (payload.progress as Record<string, unknown>)
225
+ : {};
226
+ const next: PlayStatus = {
227
+ ...(payload as unknown as Omit<PlayStatus, 'runId' | 'status' | 'progress'>),
228
+ runId,
229
+ status,
230
+ progress: {
231
+ ...progressRecord,
232
+ status:
233
+ typeof progressRecord.status === 'string'
234
+ ? progressRecord.status
235
+ : status,
236
+ logs: state.logs,
237
+ ...(state.error ? { error: state.error } : {}),
238
+ },
239
+ ...('result' in state ? { result: state.result } : {}),
240
+ };
241
+ state.latest = next;
242
+ return next;
243
+ }
244
+
245
+ function playRunResultFromStatus(
246
+ status: PlayStatus,
247
+ startedAt: number,
248
+ fallbackRunId: string,
249
+ ): PlayRunResult {
250
+ return {
251
+ success: status.status === 'completed',
252
+ runId: status.runId || fallbackRunId,
253
+ result: status.result,
254
+ logs: status.progress?.logs ?? [],
255
+ durationMs: Date.now() - startedAt,
256
+ error:
257
+ status.progress?.error ??
258
+ (status.status !== 'completed' ? status.status : undefined),
259
+ };
260
+ }
261
+
262
+ function playRunStatusFromState(state: PlayLiveStatusState): PlayStatus {
263
+ return {
264
+ runId: state.runId,
265
+ status: state.status,
266
+ progress: {
267
+ status: state.status,
268
+ logs: state.logs,
269
+ ...(state.error ? { error: state.error } : {}),
270
+ },
271
+ ...('result' in state ? { result: state.result } : {}),
272
+ };
273
+ }
274
+
175
275
  /**
176
276
  * Low-level client for the Deepline REST API.
177
277
  *
@@ -339,7 +439,7 @@ export class DeeplineClient {
339
439
  /**
340
440
  * Search available tools using Deepline's ranked backend search.
341
441
  *
342
- * This is the same discovery surface used by the legacy CLI: it ranks across
442
+ * This is the same discovery surface used by the CLI: it ranks across
343
443
  * tool metadata, categories, agent guidance, and input schema fields.
344
444
  */
345
445
  async searchTools(
@@ -453,7 +553,7 @@ export class DeeplineClient {
453
553
  * `progress.logs`; they are not part of the user output object.
454
554
  *
455
555
  * @param request - Play run configuration (name, code, input, etc.)
456
- * @returns Workflow metadata including the `workflowId` for status polling
556
+ * @returns Run metadata including the public `workflowId`
457
557
  *
458
558
  * @example
459
559
  * ```typescript
@@ -917,9 +1017,6 @@ export class DeeplineClient {
917
1017
  * Internal/advanced primitive. Public callers should usually prefer
918
1018
  * {@link runPlay}, {@link PlayJob.get}, or `deepline play run --watch`.
919
1019
  *
920
- * Poll this method until `status` reaches a terminal state:
921
- * `'completed'`, `'failed'`, or `'cancelled'`.
922
- *
923
1020
  * @param workflowId - Play-run id from {@link startPlayRun}
924
1021
  * @returns Current status with progress logs and partial results
925
1022
  *
@@ -945,43 +1042,11 @@ export class DeeplineClient {
945
1042
  return normalizePlayStatus(response);
946
1043
  }
947
1044
 
948
- /**
949
- * Get the lightweight tail-polling status for a play execution.
950
- *
951
- * This is intentionally smaller than {@link getPlayStatus}: it returns the
952
- * fields needed for CLI log tailing while the run is in flight, without
953
- * forcing the API to rebuild final result views on every poll. Call
954
- * {@link getPlayStatus} once after a terminal state for the full result.
955
- */
956
- async getPlayTailStatus(
957
- workflowId: string,
958
- options?: {
959
- afterLogIndex?: number;
960
- waitMs?: number;
961
- terminalOnly?: boolean;
962
- },
963
- ): Promise<PlayStatus> {
964
- const params = new URLSearchParams({ mode: 'tail' });
965
- if (typeof options?.afterLogIndex === 'number') {
966
- params.set('afterLogIndex', String(options.afterLogIndex));
967
- }
968
- if (typeof options?.waitMs === 'number') {
969
- params.set('waitMs', String(options.waitMs));
970
- }
971
- if (options?.terminalOnly) {
972
- params.set('terminalOnly', 'true');
973
- }
974
- const response = await this.http.get<Record<string, unknown>>(
975
- `/api/v2/plays/run/${encodeURIComponent(workflowId)}?${params.toString()}`,
976
- );
977
- return normalizePlayStatus(response);
978
- }
979
-
980
1045
  /**
981
1046
  * Stream semantic play-run events using the same SSE feed as the dashboard.
982
1047
  *
983
- * Consumers should still keep a polling fallback: SSE is the fast live-update
984
- * transport, while the status endpoints remain the authoritative recovery path.
1048
+ * The server emits a canonical `play.run.snapshot` event first for every
1049
+ * connection, then incremental live events until terminal state or reconnect.
985
1050
  */
986
1051
  async *streamPlayRunEvents(
987
1052
  workflowId: string,
@@ -1012,7 +1077,7 @@ export class DeeplineClient {
1012
1077
  *
1013
1078
  * Sends a stop request for the run.
1014
1079
  *
1015
- * @param workflowId - Temporal workflow ID to cancel
1080
+ * @param workflowId - Public Deepline play-run id to cancel
1016
1081
  *
1017
1082
  * @example
1018
1083
  * ```typescript
@@ -1029,7 +1094,7 @@ export class DeeplineClient {
1029
1094
  /**
1030
1095
  * Stop a running play execution, including open HITL waits.
1031
1096
  *
1032
- * @param workflowId - Temporal workflow ID to stop
1097
+ * @param workflowId - Public Deepline play-run id to stop
1033
1098
  * @param options.reason - Optional audit/debug reason
1034
1099
  */
1035
1100
  async stopPlay(
@@ -1108,39 +1173,42 @@ export class DeeplineClient {
1108
1173
  return response.runs ?? [];
1109
1174
  }
1110
1175
 
1111
- /**
1112
- * Fetch the lightweight tail status for a run using the public runs resource model.
1113
- *
1114
- * This is the SDK equivalent of:
1115
- *
1116
- * ```bash
1117
- * deepline runs tail <run-id> --json
1118
- * ```
1119
- */
1176
+ /** Read the canonical run stream and return the latest run snapshot. */
1120
1177
  async tailRun(runId: string, options?: RunsTailOptions): Promise<PlayStatus> {
1121
- const afterLogIndex =
1122
- typeof options?.afterLogIndex === 'number'
1123
- ? options.afterLogIndex
1124
- : typeof options?.cursor === 'number'
1125
- ? options.cursor
1126
- : typeof options?.cursor === 'string' && options.cursor.trim()
1127
- ? Number(options.cursor)
1128
- : undefined;
1129
- const params = new URLSearchParams();
1130
- if (Number.isFinite(afterLogIndex)) {
1131
- params.set('afterLogIndex', String(Number(afterLogIndex)));
1178
+ const state: PlayLiveStatusState = {
1179
+ runId,
1180
+ status: 'running',
1181
+ logs: [],
1182
+ latest: null,
1183
+ };
1184
+ let terminal = false;
1185
+ for await (const event of this.streamPlayRunEvents(runId, {
1186
+ mode: 'cli',
1187
+ signal: options?.signal,
1188
+ })) {
1189
+ const status = updatePlayLiveStatusState(state, event);
1190
+ if (!status) {
1191
+ continue;
1192
+ }
1193
+ terminal = TERMINAL_PLAY_STATUSES.has(status.status);
1194
+ if (terminal) {
1195
+ break;
1196
+ }
1132
1197
  }
1133
- if (typeof options?.waitMs === 'number') {
1134
- params.set('waitMs', String(options.waitMs));
1198
+ if (terminal && state.latest) {
1199
+ return await this.getRunStatus(state.latest.runId || runId).catch(
1200
+ () => state.latest ?? playRunStatusFromState(state),
1201
+ );
1135
1202
  }
1136
- if (options?.terminalOnly) {
1137
- params.set('terminalOnly', 'true');
1203
+ if (state.latest) {
1204
+ return state.latest;
1138
1205
  }
1139
- const suffix = params.toString() ? `?${params.toString()}` : '';
1140
- const response = await this.http.get<Record<string, unknown>>(
1141
- `/api/v2/runs/${encodeURIComponent(runId)}/tail${suffix}`,
1206
+ throw new DeeplineError(
1207
+ `Run stream for ${runId} ended before the initial snapshot.`,
1208
+ undefined,
1209
+ 'PLAY_RUN_STREAM_EMPTY',
1210
+ { runId },
1142
1211
  );
1143
- return normalizePlayStatus(response);
1144
1212
  }
1145
1213
 
1146
1214
  /**
@@ -1337,11 +1405,11 @@ export class DeeplineClient {
1337
1405
  // ——————————————————————————————————————————————————————————
1338
1406
 
1339
1407
  /**
1340
- * Run a play end-to-end: submit, poll until terminal, return result.
1408
+ * Run a play end-to-end: submit, stream until terminal, return result.
1341
1409
  *
1342
1410
  * This is the highest-level play execution method. It submits the play,
1343
- * polls for status updates, and returns a structured result with logs
1344
- * and timing. Supports cancellation via `AbortSignal`.
1411
+ * reads the canonical run stream for status updates, and returns a structured
1412
+ * result with logs and timing. Supports cancellation via `AbortSignal`.
1345
1413
  *
1346
1414
  * @param code - Source string fallback; pass the bundled artifact in `options.artifact`
1347
1415
  * @param csvPath - Input CSV path, or `null`
@@ -1357,7 +1425,6 @@ export class DeeplineClient {
1357
1425
  * const logs = status.progress?.logs ?? [];
1358
1426
  * console.log(`[${status.status}] ${logs.length} log lines`);
1359
1427
  * },
1360
- * pollIntervalMs: 1000,
1361
1428
  * });
1362
1429
  *
1363
1430
  * if (result.success) {
@@ -1383,10 +1450,8 @@ export class DeeplineClient {
1383
1450
  csvPath: string | null,
1384
1451
  name?: string,
1385
1452
  options?: {
1386
- /** Called on each poll iteration with the current status. */
1453
+ /** Called for each status snapshot emitted by the run stream. */
1387
1454
  onProgress?: (status: PlayStatus) => void;
1388
- /** Milliseconds between status polls. Default: `500`. */
1389
- pollIntervalMs?: number;
1390
1455
  /** Abort signal — triggers cancellation and immediate return. */
1391
1456
  signal?: AbortSignal;
1392
1457
  /** Runtime input for the play function. */
@@ -1409,39 +1474,59 @@ export class DeeplineClient {
1409
1474
  packagedFiles: options?.packagedFiles,
1410
1475
  force: options?.force,
1411
1476
  });
1412
- const pollInterval = options?.pollIntervalMs ?? 500;
1413
1477
  const start = Date.now();
1478
+ const state: PlayLiveStatusState = {
1479
+ runId: workflowId,
1480
+ status: 'running',
1481
+ logs: [],
1482
+ latest: null,
1483
+ };
1414
1484
 
1415
- while (true) {
1485
+ if (options?.signal?.aborted) {
1486
+ await this.cancelPlay(workflowId);
1487
+ return {
1488
+ success: false,
1489
+ runId: workflowId,
1490
+ logs: [],
1491
+ durationMs: Date.now() - start,
1492
+ error: 'Cancelled by user',
1493
+ };
1494
+ }
1495
+
1496
+ for await (const event of this.streamPlayRunEvents(workflowId, {
1497
+ mode: 'cli',
1498
+ signal: options?.signal,
1499
+ })) {
1416
1500
  if (options?.signal?.aborted) {
1417
1501
  await this.cancelPlay(workflowId);
1418
1502
  return {
1419
1503
  success: false,
1420
1504
  runId: workflowId,
1421
- logs: [],
1505
+ logs: state.logs,
1422
1506
  durationMs: Date.now() - start,
1423
1507
  error: 'Cancelled by user',
1424
1508
  };
1425
1509
  }
1426
1510
 
1427
- const status = await this.getPlayStatus(workflowId);
1511
+ const status = updatePlayLiveStatusState(state, event);
1512
+ if (!status) {
1513
+ continue;
1514
+ }
1428
1515
  options?.onProgress?.(status);
1429
1516
 
1430
1517
  if (TERMINAL_PLAY_STATUSES.has(status.status)) {
1431
- return {
1432
- success: status.status === 'completed',
1433
- runId: status.runId || workflowId,
1434
- result: status.result,
1435
- logs: status.progress?.logs ?? [],
1436
- durationMs: Date.now() - start,
1437
- error:
1438
- status.progress?.error ??
1439
- (status.status !== 'completed' ? status.status : undefined),
1440
- };
1518
+ const finalStatus = await this.getPlayStatus(status.runId || workflowId)
1519
+ .catch(() => status);
1520
+ return playRunResultFromStatus(finalStatus, start, workflowId);
1441
1521
  }
1442
-
1443
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
1444
1522
  }
1523
+
1524
+ throw new DeeplineError(
1525
+ `Run stream for ${workflowId} ended before the run reached a terminal state.`,
1526
+ undefined,
1527
+ 'PLAY_RUN_STREAM_ENDED',
1528
+ { runId: workflowId, workflowId },
1529
+ );
1445
1530
  }
1446
1531
 
1447
1532
  // ——————————————————————————————————————————————————————————
@@ -200,7 +200,7 @@ export interface ToolMetadata extends ToolDefinition {
200
200
  export interface PlayRunResult {
201
201
  /** `true` if the play completed successfully (`status === 'completed'`). */
202
202
  success: boolean;
203
- /** Public play-run identifier — use for `play tail` or status polling. */
203
+ /** Public play-run identifier. */
204
204
  runId: string;
205
205
  /** The play's return value. Only present on success. */
206
206
  result?: unknown;
@@ -222,8 +222,6 @@ export interface PlayProgressStatus {
222
222
  totalRows?: number;
223
223
  /** Accumulated log lines from `ctx.log()`. Grows monotonically. */
224
224
  logs: string[];
225
- /** Zero-based offset of the first returned log line when a tail cursor is used. */
226
- logOffset?: number;
227
225
  /** Error message if the play has failed. */
228
226
  error?: string;
229
227
  }
@@ -265,7 +263,7 @@ export interface PlayStatus {
265
263
  progress?: PlayProgressStatus;
266
264
  /** Partial or final result. Available once the play returns. */
267
265
  result?: unknown;
268
- /** Temporal-backed run metadata when returned by the status endpoint. */
266
+ /** Scheduler-backed run metadata when returned by the status endpoint. */
269
267
  run?: {
270
268
  startTime?: string | null;
271
269
  closeTime?: string | null;
@@ -315,9 +313,9 @@ export interface StopPlayRunResult {
315
313
  * Summary of a single play run, returned by {@link DeeplineClient.listPlayRuns}.
316
314
  */
317
315
  export interface PlayRunListItem {
318
- /** Temporal workflow ID. */
316
+ /** Public Deepline play-run id. */
319
317
  workflowId: string;
320
- /** Temporal run ID (unique per retry of the same workflow). */
318
+ /** Backend run attempt id, when exposed. */
321
319
  runId: string;
322
320
  /** Workflow type (typically `'Workflow'`). */
323
321
  type: string;
@@ -440,7 +438,7 @@ export interface PlayDefinitionDetail {
440
438
  runCount: number;
441
439
  /** Primary key column for CSV-based plays. */
442
440
  tableNamespace?: string | null;
443
- /** Temporal workflow ID of the latest run. */
441
+ /** Public Deepline id of the latest run. */
444
442
  latestRunId?: string | null;
445
443
  /** Unix timestamp (ms). */
446
444
  createdAt: number;
@@ -559,12 +557,11 @@ export interface ClearPlayHistoryResult {
559
557
  * ```typescript
560
558
  * const started = await client.startPlayRun({ name: 'my-play', input: { domain: 'stripe.com' } });
561
559
  * console.log(`Started: ${started.workflowId}`);
562
- * console.log(`Status URL: ${started.statusUrl}`);
563
560
  * console.log(`Dashboard: ${started.dashboardUrl}`);
564
561
  * ```
565
562
  */
566
563
  export interface PlayRunStart {
567
- /** Temporal workflow ID for tracking this execution. */
564
+ /** Public Deepline play-run id for tracking this execution. */
568
565
  workflowId: string;
569
566
  /** Public Deepline play-run API version. */
570
567
  apiVersion?: number;
@@ -576,8 +573,6 @@ export interface PlayRunStart {
576
573
  runtimeBackend?: string;
577
574
  /** Canonical run contract compatibility metadata. */
578
575
  contract?: Record<string, unknown> | null;
579
- /** URL to poll for status updates. */
580
- statusUrl?: string;
581
576
  /** Dashboard URL for the named play. */
582
577
  dashboardUrl?: string;
583
578
  /** Terminal status returned when the start request used a short completion wait. */
@@ -589,7 +584,7 @@ export interface PlayRunStart {
589
584
  *
590
585
  * This is the check-only version of play artifact registration: the server runs
591
586
  * the same preflight compiler and static-analysis pass without storing,
592
- * publishing, or starting a Temporal run.
587
+ * publishing, or starting a play run.
593
588
  */
594
589
  export interface PlayCheckResult {
595
590
  valid: boolean;
@@ -657,8 +652,7 @@ export interface StartPlayRunRequest {
657
652
  waitForCompletionMs?: number;
658
653
  /**
659
654
  * Per-run execution profile override. The server defaults to `workers_edge`;
660
- * tests/benchmarks pass `legacy` or `local` here. Most callers should leave
661
- * this unset.
655
+ * tests can pass `local` here. Most callers should leave this unset.
662
656
  */
663
657
  profile?: string;
664
658
  }
@@ -1,2 +1,2 @@
1
- export const SDK_VERSION = "0.1.21";
1
+ export const SDK_VERSION = "0.1.22";
2
2
  export const SDK_API_CONTRACT = "2026-05-runs-v2";
@@ -1,9 +1,8 @@
1
1
  /**
2
2
  * Execution profile = the (scheduler, runner, dedup) tuple selected for a run.
3
3
  *
4
- * Profiles let us hot-swap whole architectures for benchmarking and migration:
4
+ * Profiles define the supported execution architectures:
5
5
  * - `workers_edge` — Full-CF: Dynamic Workers + Cloudflare Workflows + DO dedup (default)
6
- * - `legacy` — Daytona + Temporal + in-memory dedup (deprecated; kept for benchmarking)
7
6
  * - `local` — Local subprocess + in-process scheduler (for tests)
8
7
  *
9
8
  * Selection: the API hardcodes `workers_edge` as the default. Per-run
@@ -30,7 +29,6 @@ export type PlayExecutionProfile = {
30
29
  };
31
30
 
32
31
  export const PLAY_EXECUTION_PROFILE_IDS = {
33
- legacy: 'legacy',
34
32
  workersEdge: 'workers_edge',
35
33
  local: 'local',
36
34
  } as const;
@@ -42,13 +40,6 @@ export const PLAY_EXECUTION_PROFILES: Record<
42
40
  PlayExecutionProfileId,
43
41
  PlayExecutionProfile
44
42
  > = {
45
- legacy: {
46
- id: 'legacy',
47
- scheduler: PLAY_SCHEDULER_BACKENDS.temporal,
48
- runner: PLAY_RUNTIME_BACKENDS.daytona,
49
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
50
- label: 'Daytona + Temporal (production today)',
51
- },
52
43
  workers_edge: {
53
44
  id: 'workers_edge',
54
45
  scheduler: PLAY_SCHEDULER_BACKENDS.cfWorkflows,
@@ -67,10 +58,9 @@ export const PLAY_EXECUTION_PROFILES: Record<
67
58
 
68
59
  export function defaultExecutionProfile(): PlayExecutionProfile {
69
60
  // Hardcoded. The full-Cloudflare path is the only production execution
70
- // story Dynamic Workflows + Dynamic Workers + DO dedup. legacy/local
71
- // remain selectable via the per-run `profile` body field on
72
- // POST /api/v2/plays/run for benchmarking and tests; do NOT reintroduce
73
- // env-var-based switching here.
61
+ // story: Dynamic Workflows + Dynamic Workers + DO dedup. local remains
62
+ // selectable via the per-run `profile` body field on POST /api/v2/plays/run
63
+ // for tests; do not reintroduce env-var-based switching here.
74
64
  return PLAY_EXECUTION_PROFILES.workers_edge;
75
65
  }
76
66
 
@@ -7,7 +7,7 @@ export type RuntimeRunStatusAction = {
7
7
  action: 'update_run_status';
8
8
  playId: string;
9
9
  status: string;
10
- error?: string;
10
+ error?: string | null;
11
11
  runtimeBackend?: string | null;
12
12
  artifactHash?: string | null;
13
13
  graphHash?: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.21",
3
+ "version": "0.1.22",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {