deepline 0.2.36 → 0.2.38

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.
@@ -160,7 +160,7 @@ export const SDK_RELEASE = {
160
160
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
161
161
  // exposed storage-dependent synchronous access. This deliberate minor
162
162
  // release keeps lazy paging semantics independent of row residency.
163
- version: '0.2.36',
163
+ version: '0.2.38',
164
164
  contracts: {
165
165
  api: {
166
166
  name: 'sdk-http-api',
@@ -8367,12 +8367,19 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
8367
8367
  const success =
8368
8368
  successfulLiveStepCallIds.has(req.callId) ||
8369
8369
  this.getCachedToolResult(toolId, req.cacheKey)?.result != null;
8370
- return {
8371
- rowId: req.rowId,
8372
- status: success ? 'completed' : 'failed',
8373
- success,
8374
- error: success ? null : 'Tool call failed',
8375
- };
8370
+ return success
8371
+ ? {
8372
+ rowId: req.rowId,
8373
+ status: 'completed',
8374
+ success: true,
8375
+ error: null,
8376
+ }
8377
+ : {
8378
+ rowId: req.rowId,
8379
+ status: 'failed',
8380
+ success: false,
8381
+ error: 'Tool call failed',
8382
+ };
8376
8383
  });
8377
8384
  // Step traces are lifecycle observability, not a second row/receipt
8378
8385
  // store. Keep only call ids long enough to record their bounded
@@ -1018,14 +1018,18 @@ export type PlayDatasetSubstep =
1018
1018
  description?: string;
1019
1019
  };
1020
1020
 
1021
- export interface PlayStepRowResult {
1021
+ type PlayStepRowResultFields = {
1022
1022
  rowId: number;
1023
- status: 'completed' | 'failed' | 'missed' | 'skipped';
1024
- success: boolean;
1025
1023
  provider?: string;
1026
1024
  value?: unknown;
1027
1025
  error?: string | null;
1028
- }
1026
+ };
1027
+
1028
+ export type PlayStepRowResult = PlayStepRowResultFields &
1029
+ (
1030
+ | { status: 'completed'; success: true }
1031
+ | { status: 'failed' | 'missed' | 'skipped'; success: false }
1032
+ );
1029
1033
 
1030
1034
  export interface PlayRowUpdate {
1031
1035
  key: string;
@@ -1,6 +1,5 @@
1
1
  import type { PlayRuntimeBackendId } from './backend';
2
2
  import type { PlayArtifactKind } from './backend';
3
- import type { PlayDedupBackendId } from './dedup-backend';
4
3
  import type { PlaySchedulerBackendId } from './scheduler-backend';
5
4
  import {
6
5
  PLAY_RUNTIME_PROVIDERS,
@@ -15,7 +14,6 @@ export type PlayExecutionProfile = {
15
14
  id: PlayExecutionProfileId;
16
15
  scheduler: PlaySchedulerBackendId;
17
16
  runner: PlayRuntimeBackendId;
18
- dedup: PlayDedupBackendId;
19
17
  artifactKind: PlayArtifactKind;
20
18
  label: string;
21
19
  };
@@ -235,15 +235,25 @@ export type PlayRunnerEvent =
235
235
  result: PlayRunnerResult;
236
236
  };
237
237
 
238
- export type PlayRunnerRuntimeTiming = {
239
- backend: 'daytona' | 'modal';
240
- daytonaCreateMs?: number;
241
- daytonaUploadMs?: number;
242
- daytonaExecuteMs?: number;
243
- modalCreateMs?: number;
244
- modalUploadMs?: number;
245
- modalExecuteMs?: number;
246
- };
238
+ export type PlayRunnerRuntimeTiming =
239
+ | {
240
+ backend: 'daytona';
241
+ daytonaCreateMs?: number;
242
+ daytonaUploadMs?: number;
243
+ daytonaExecuteMs?: number;
244
+ modalCreateMs?: never;
245
+ modalUploadMs?: never;
246
+ modalExecuteMs?: never;
247
+ }
248
+ | {
249
+ backend: 'modal';
250
+ modalCreateMs?: number;
251
+ modalUploadMs?: number;
252
+ modalExecuteMs?: number;
253
+ daytonaCreateMs?: never;
254
+ daytonaUploadMs?: never;
255
+ daytonaExecuteMs?: never;
256
+ };
247
257
 
248
258
  /**
249
259
  * Why replay checkpoint state is present or absent on the detached-runner
@@ -4,7 +4,6 @@ import {
4
4
  type PlayArtifactKind,
5
5
  type PlayRuntimeBackendId,
6
6
  } from './backend';
7
- import { PLAY_DEDUP_BACKENDS, type PlayDedupBackendId } from './dedup-backend';
8
7
  import {
9
8
  PLAY_SCHEDULER_BACKENDS,
10
9
  type PlaySchedulerBackendId,
@@ -21,7 +20,6 @@ export type PlayRuntimeProviderDescriptor = {
21
20
  id: PlayRuntimeProviderId;
22
21
  scheduler: PlaySchedulerBackendId;
23
22
  runner: PlayRuntimeBackendId;
24
- dedup: PlayDedupBackendId;
25
23
  artifactKind: PlayArtifactKind;
26
24
  label: string;
27
25
  };
@@ -37,10 +35,9 @@ export const PLAY_RUNTIME_PROVIDERS: Record<
37
35
  // axis to local_process (same as the local profile) via an explicit
38
36
  // runtimeBackend override at submit while tests drive local_process.
39
37
  runner: PLAY_RUNTIME_BACKENDS.daytona,
40
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
41
38
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
42
39
  label:
43
- 'Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup',
40
+ 'Absurd (Postgres-native durable) scheduler + one-shot Daytona runner',
44
41
  },
45
42
  };
46
43
 
@@ -269,17 +269,6 @@ export type PlayRunLedgerEvent =
269
269
  | (PlayRunLedgerBaseEvent & {
270
270
  type: 'activity.observed';
271
271
  observation: PlayActivityObservation;
272
- })
273
- | (PlayRunLedgerBaseEvent & {
274
- /**
275
- * @deprecated Mixed-version deploy seam only. Owner: Play Runtime.
276
- * Remove after 2026-07-19, once pre-dataset-lifecycle workers have
277
- * exceeded the maximum run duration plus the seven-day drain window.
278
- */
279
- type: 'sheet.summary.updated';
280
- tableNamespace: string;
281
- deltaCursor?: number;
282
- summary?: unknown;
283
272
  });
284
273
 
285
274
  export type PlayRunLedgerStatusPatch = {
@@ -1502,12 +1491,6 @@ export function reducePlayRunLedgerEvent(
1502
1491
  : event.observation.activityId,
1503
1492
  });
1504
1493
  }
1505
- case 'sheet.summary.updated':
1506
- return withTiming({
1507
- ...base,
1508
- resultTableNamespace:
1509
- base.resultTableNamespace ?? event.tableNamespace ?? null,
1510
- });
1511
1494
  }
1512
1495
  }
1513
1496
 
@@ -0,0 +1,2 @@
1
+ /** Label that identifies sandboxes owned by the play runner fleet. */
2
+ export const DAYTONA_PLAY_RUNNER_LABEL_SOURCE = 'deepline-play-runner';
@@ -10,6 +10,7 @@ import {
10
10
  validatePlaySandboxRuntimeLimits,
11
11
  } from '@shared_libs/play-runtime/sandbox-runtime-limits';
12
12
  import type { PlayRunnerRuntimeLifecycleEvent } from '../types';
13
+ import { DAYTONA_PLAY_RUNNER_LABEL_SOURCE } from './daytona-labels';
13
14
 
14
15
  const DAYTONA_CREATE_TIMEOUT_SECONDS = 10;
15
16
  const DAYTONA_CREATE_RETRY_DELAYS_MS = [0, 500, 1_500] as const;
@@ -20,7 +21,6 @@ const DAYTONA_TIMED_OUT_CREATE_RECONCILE_DELAYS_MS = [
20
21
  // inactivity stop is a wider crash backstop measured from sandbox creation, so
21
22
  // setup time cannot consume the terminal-flush grace.
22
23
  const DAYTONA_AUTO_ARCHIVE_INTERVAL_MINUTES = 15;
23
- const DAYTONA_SANDBOX_LABEL_SOURCE = 'deepline-play-runner';
24
24
  // Daytona's Deepline-managed default snapshot is the only admitted prebuilt.
25
25
  // Resources are verified during acquisition, before customer code or billing.
26
26
  export const DAYTONA_SANDBOX_CPU = STANDARD_PLAY_SANDBOX_RUNTIME_LIMITS.cpu;
@@ -260,7 +260,7 @@ async function createOneShotDaytonaSandbox(input: {
260
260
  playId?: string;
261
261
  runId?: string;
262
262
  } = {
263
- source: DAYTONA_SANDBOX_LABEL_SOURCE,
263
+ source: DAYTONA_PLAY_RUNNER_LABEL_SOURCE,
264
264
  };
265
265
  if (orgId) labels.orgId = orgId;
266
266
  if (workflowId) labels.workflowId = workflowId;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Scheduler-backend interface — owns play workflow lifecycle.
3
3
  *
4
- * One of two pluggable axes (alongside runner-backends and dedup-backends).
4
+ * Durable scheduling Interface for Play Runs.
5
5
  * Selected per-run via PlayExecutionProfile.
6
6
  *
7
7
  * Absurd is the only durable production scheduler. In-process exists only for
@@ -126,8 +126,6 @@ export type PlaySchedulerSubmitInput = {
126
126
  * historical meaning.
127
127
  */
128
128
  runtimeSandboxPlacementPolicyId?: RuntimeSandboxPlacementPolicyId | null;
129
- /** dedup backend for cross-attempt cross-process idempotency */
130
- dedupBackend: string;
131
129
  /** If known at submit time, total input rows (for partition decisions). */
132
130
  totalRows?: number;
133
131
  /** Internal scheduler/coordinator URL for Worker-side capabilities. */
package/dist/cli/index.js CHANGED
@@ -1044,7 +1044,7 @@ var SDK_RELEASE = {
1044
1044
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
1045
1045
  // exposed storage-dependent synchronous access. This deliberate minor
1046
1046
  // release keeps lazy paging semantics independent of row residency.
1047
- version: "0.2.36",
1047
+ version: "0.2.38",
1048
1048
  contracts: {
1049
1049
  api: {
1050
1050
  name: "sdk-http-api",
@@ -16495,13 +16495,6 @@ function extractDefinedPlayMetadata(sourceCode, exportName) {
16495
16495
  return null;
16496
16496
  }
16497
16497
 
16498
- // ../shared_libs/play-runtime/dedup-backend.ts
16499
- var PLAY_DEDUP_BACKENDS = {
16500
- inMemory: "in_memory",
16501
- neonTable: "neon_table",
16502
- durableObject: "durable_object"
16503
- };
16504
-
16505
16498
  // ../shared_libs/play-runtime/scheduler-backend.ts
16506
16499
  var PLAY_SCHEDULER_BACKENDS = {
16507
16500
  /**
@@ -16525,9 +16518,8 @@ var PLAY_RUNTIME_PROVIDERS = {
16525
16518
  // axis to local_process (same as the local profile) via an explicit
16526
16519
  // runtimeBackend override at submit while tests drive local_process.
16527
16520
  runner: PLAY_RUNTIME_BACKENDS.daytona,
16528
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
16529
16521
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
16530
- label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
16522
+ label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner"
16531
16523
  }
16532
16524
  };
16533
16525
  function defaultPlayRuntimeProvider() {
@@ -24848,6 +24840,9 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
24848
24840
  ];
24849
24841
  }
24850
24842
  function compileEnrichConfigToPlaySource(config, options = {}) {
24843
+ if (options.maxCreditsPerRun !== void 0 && (!Number.isFinite(options.maxCreditsPerRun) || options.maxCreditsPerRun <= 0)) {
24844
+ throw new Error("maxCreditsPerRun must be a number greater than 0.");
24845
+ }
24851
24846
  const compatibility = buildEnrichCompatibilityPlan(options);
24852
24847
  const { playName, mapName } = compatibility;
24853
24848
  const inlineRunJavascript = options.inlineRunJavascript ?? false;
@@ -24899,6 +24894,10 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
24899
24894
  const metadataColumnSource = renderMetadataColumnStep(config);
24900
24895
  const generatedAliases = collectGeneratedAliases(config.commands);
24901
24896
  const runOptionsSource = options.failFast ? `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart), onRowError: 'fail' as const }` : `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart) }`;
24897
+ const playOptionsSource = [
24898
+ `description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")}`,
24899
+ ...options.maxCreditsPerRun === void 0 ? [] : [`billing: { maxCreditsPerRun: ${String(options.maxCreditsPerRun)} }`]
24900
+ ].join(", ");
24902
24901
  const body = [
24903
24902
  `function __dlRunInlinePlay<TContext, TInput, TOutput>(handler: (ctx: TContext, input: TInput) => Promise<TOutput>, scope: TContext, payload: TInput, force: boolean): Promise<TOutput> {`,
24904
24903
  ` if (!force) return handler(scope, payload);`,
@@ -24932,7 +24931,7 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
24932
24931
  ...metadataColumnSource ? [metadataColumnSource] : [],
24933
24932
  ` .run(${runOptionsSource});`,
24934
24933
  ` return { rows: enriched, count: await enriched.count() };`,
24935
- `}, { description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")} });`
24934
+ `}, { ${playOptionsSource} });`
24936
24935
  ];
24937
24936
  const helpers = idiomaticGetters ? selectUsedHelpers(helperSource(), body.join("\n")) : helperSource();
24938
24937
  const typeImports = idiomaticGetters ? inlineTypeImports : [.../* @__PURE__ */ new Set([...inlineTypeImports, "DeeplinePlayRuntimeContext"])].sort();
@@ -26133,7 +26132,8 @@ async function buildPlanArgs(args) {
26133
26132
  "--rows",
26134
26133
  "--with-force",
26135
26134
  "--timeout",
26136
- "--profile"
26135
+ "--profile",
26136
+ "--max-credits-per-run"
26137
26137
  ]);
26138
26138
  const localBooleanOptions = /* @__PURE__ */ new Set([
26139
26139
  "--dry-run",
@@ -26292,6 +26292,16 @@ function parseRows(value, all) {
26292
26292
  }
26293
26293
  return { rowStart: single, rowEnd: single };
26294
26294
  }
26295
+ function parseMaxCreditsPerRun(value) {
26296
+ if (value === void 0) {
26297
+ return void 0;
26298
+ }
26299
+ const parsed = Number(value.trim());
26300
+ if (!Number.isFinite(parsed) || parsed <= 0) {
26301
+ throw new Error("--max-credits-per-run must be a number greater than 0.");
26302
+ }
26303
+ return parsed;
26304
+ }
26295
26305
  function summarizePlan(config, playSource) {
26296
26306
  const steps = [];
26297
26307
  for (const command of config.commands) {
@@ -29158,6 +29168,9 @@ function registerEnrichCommand(program) {
29158
29168
  ).option(
29159
29169
  "--fail-fast",
29160
29170
  "Fail the generated play when any selected row errors, while preserving recovered runtime-sheet rows for export."
29171
+ ).option(
29172
+ "--max-credits-per-run <credits>",
29173
+ "Set a hard Deepline-credit ceiling enforced by the runtime for this run."
29161
29174
  ).action(async (options, _command) => {
29162
29175
  if (currentEnrichArgs().some(
29163
29176
  (arg) => arg === "--no-open" || arg.startsWith("--no-open=")
@@ -29182,6 +29195,7 @@ function registerEnrichCommand(program) {
29182
29195
  }
29183
29196
  const client2 = new DeeplineClient();
29184
29197
  const args = currentEnrichArgs();
29198
+ const maxCreditsPerRun = parseMaxCreditsPerRun(options.maxCreditsPerRun);
29185
29199
  const config = await compileConfig({ client: client2, args, options });
29186
29200
  emitEnrichDebugValidationLines(config);
29187
29201
  if (options.dryRun) {
@@ -29190,7 +29204,8 @@ function registerEnrichCommand(program) {
29190
29204
  forceAliases: forceAliases2,
29191
29205
  playName: options.name,
29192
29206
  inlineRunJavascript: true,
29193
- failFast: options.failFast
29207
+ failFast: options.failFast,
29208
+ maxCreditsPerRun
29194
29209
  });
29195
29210
  const summary = summarizePlan(config, playSource2);
29196
29211
  if (options.json) {
@@ -29222,7 +29237,8 @@ function registerEnrichCommand(program) {
29222
29237
  forceAliases,
29223
29238
  playName: options.name,
29224
29239
  inlineRunJavascript: true,
29225
- failFast: options.failFast
29240
+ failFast: options.failFast,
29241
+ maxCreditsPerRun
29226
29242
  });
29227
29243
  const selectedRange = selectedSourceCsvRange(sourceCsvPath, rows);
29228
29244
  const sdkEnrichTelemetry = createSdkEnrichTelemetryContext({
@@ -36951,11 +36967,26 @@ function parseSetupPhases(value) {
36951
36967
  }
36952
36968
  const record = phase;
36953
36969
  if (!isSetupPhaseStatus(record.status)) return null;
36954
- phases[name] = {
36955
- status: record.status,
36956
- ...typeof record.outcome === "string" ? { outcome: record.outcome } : {},
36957
- ...typeof record.code === "string" ? { code: record.code } : {}
36958
- };
36970
+ switch (record.status) {
36971
+ case "pending":
36972
+ case "in_progress":
36973
+ phases[name] = { status: record.status };
36974
+ break;
36975
+ case "complete":
36976
+ phases[name] = {
36977
+ status: "complete",
36978
+ ...typeof record.outcome === "string" ? { outcome: record.outcome } : {}
36979
+ };
36980
+ break;
36981
+ case "waiting":
36982
+ if (typeof record.outcome !== "string") return null;
36983
+ phases[name] = { status: "waiting", outcome: record.outcome };
36984
+ break;
36985
+ case "failed":
36986
+ if (typeof record.code !== "string") return null;
36987
+ phases[name] = { status: "failed", code: record.code };
36988
+ break;
36989
+ }
36959
36990
  }
36960
36991
  return phases;
36961
36992
  }
@@ -38066,7 +38097,6 @@ var import_node_child_process6 = require("child_process");
38066
38097
  var import_node_fs22 = require("fs");
38067
38098
  var import_node_path25 = require("path");
38068
38099
  var CHECK_TIMEOUT_MS2 = 3e3;
38069
- var attemptedSync = false;
38070
38100
  function shouldSkipSkillsSync() {
38071
38101
  if (detectAgentRuntime() === "claude_cowork") {
38072
38102
  return true;
@@ -38370,8 +38400,7 @@ function writeSdkSkillsStatusLine(line) {
38370
38400
  `);
38371
38401
  }
38372
38402
  async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
38373
- if (attemptedSync || shouldSkipSkillsSync()) return;
38374
- attemptedSync = true;
38403
+ if (shouldSkipSkillsSync()) return;
38375
38404
  const usingPluginSkills = Boolean(activePluginSkillsDir());
38376
38405
  if (usingPluginSkills) {
38377
38406
  return;
@@ -1030,7 +1030,7 @@ var SDK_RELEASE = {
1030
1030
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
1031
1031
  // exposed storage-dependent synchronous access. This deliberate minor
1032
1032
  // release keeps lazy paging semantics independent of row residency.
1033
- version: "0.2.36",
1033
+ version: "0.2.38",
1034
1034
  contracts: {
1035
1035
  api: {
1036
1036
  name: "sdk-http-api",
@@ -16532,13 +16532,6 @@ function extractDefinedPlayMetadata(sourceCode, exportName) {
16532
16532
  return null;
16533
16533
  }
16534
16534
 
16535
- // ../shared_libs/play-runtime/dedup-backend.ts
16536
- var PLAY_DEDUP_BACKENDS = {
16537
- inMemory: "in_memory",
16538
- neonTable: "neon_table",
16539
- durableObject: "durable_object"
16540
- };
16541
-
16542
16535
  // ../shared_libs/play-runtime/scheduler-backend.ts
16543
16536
  var PLAY_SCHEDULER_BACKENDS = {
16544
16537
  /**
@@ -16562,9 +16555,8 @@ var PLAY_RUNTIME_PROVIDERS = {
16562
16555
  // axis to local_process (same as the local profile) via an explicit
16563
16556
  // runtimeBackend override at submit while tests drive local_process.
16564
16557
  runner: PLAY_RUNTIME_BACKENDS.daytona,
16565
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
16566
16558
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
16567
- label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
16559
+ label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner"
16568
16560
  }
16569
16561
  };
16570
16562
  function defaultPlayRuntimeProvider() {
@@ -24892,6 +24884,9 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
24892
24884
  ];
24893
24885
  }
24894
24886
  function compileEnrichConfigToPlaySource(config, options = {}) {
24887
+ if (options.maxCreditsPerRun !== void 0 && (!Number.isFinite(options.maxCreditsPerRun) || options.maxCreditsPerRun <= 0)) {
24888
+ throw new Error("maxCreditsPerRun must be a number greater than 0.");
24889
+ }
24895
24890
  const compatibility = buildEnrichCompatibilityPlan(options);
24896
24891
  const { playName, mapName } = compatibility;
24897
24892
  const inlineRunJavascript = options.inlineRunJavascript ?? false;
@@ -24943,6 +24938,10 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
24943
24938
  const metadataColumnSource = renderMetadataColumnStep(config);
24944
24939
  const generatedAliases = collectGeneratedAliases(config.commands);
24945
24940
  const runOptionsSource = options.failFast ? `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart), onRowError: 'fail' as const }` : `{ key: (row, index) => __dlEnrichRowKey(row, index + rowStart) }`;
24941
+ const playOptionsSource = [
24942
+ `description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")}`,
24943
+ ...options.maxCreditsPerRun === void 0 ? [] : [`billing: { maxCreditsPerRun: ${String(options.maxCreditsPerRun)} }`]
24944
+ ].join(", ");
24946
24945
  const body = [
24947
24946
  `function __dlRunInlinePlay<TContext, TInput, TOutput>(handler: (ctx: TContext, input: TInput) => Promise<TOutput>, scope: TContext, payload: TInput, force: boolean): Promise<TOutput> {`,
24948
24947
  ` if (!force) return handler(scope, payload);`,
@@ -24976,7 +24975,7 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
24976
24975
  ...metadataColumnSource ? [metadataColumnSource] : [],
24977
24976
  ` .run(${runOptionsSource});`,
24978
24977
  ` return { rows: enriched, count: await enriched.count() };`,
24979
- `}, { description: ${stringLiteral("Read a CSV file, run the configured Deepline enrich commands, and return enriched rows.")} });`
24978
+ `}, { ${playOptionsSource} });`
24980
24979
  ];
24981
24980
  const helpers = idiomaticGetters ? selectUsedHelpers(helperSource(), body.join("\n")) : helperSource();
24982
24981
  const typeImports = idiomaticGetters ? inlineTypeImports : [.../* @__PURE__ */ new Set([...inlineTypeImports, "DeeplinePlayRuntimeContext"])].sort();
@@ -26177,7 +26176,8 @@ async function buildPlanArgs(args) {
26177
26176
  "--rows",
26178
26177
  "--with-force",
26179
26178
  "--timeout",
26180
- "--profile"
26179
+ "--profile",
26180
+ "--max-credits-per-run"
26181
26181
  ]);
26182
26182
  const localBooleanOptions = /* @__PURE__ */ new Set([
26183
26183
  "--dry-run",
@@ -26336,6 +26336,16 @@ function parseRows(value, all) {
26336
26336
  }
26337
26337
  return { rowStart: single, rowEnd: single };
26338
26338
  }
26339
+ function parseMaxCreditsPerRun(value) {
26340
+ if (value === void 0) {
26341
+ return void 0;
26342
+ }
26343
+ const parsed = Number(value.trim());
26344
+ if (!Number.isFinite(parsed) || parsed <= 0) {
26345
+ throw new Error("--max-credits-per-run must be a number greater than 0.");
26346
+ }
26347
+ return parsed;
26348
+ }
26339
26349
  function summarizePlan(config, playSource) {
26340
26350
  const steps = [];
26341
26351
  for (const command of config.commands) {
@@ -29202,6 +29212,9 @@ function registerEnrichCommand(program) {
29202
29212
  ).option(
29203
29213
  "--fail-fast",
29204
29214
  "Fail the generated play when any selected row errors, while preserving recovered runtime-sheet rows for export."
29215
+ ).option(
29216
+ "--max-credits-per-run <credits>",
29217
+ "Set a hard Deepline-credit ceiling enforced by the runtime for this run."
29205
29218
  ).action(async (options, _command) => {
29206
29219
  if (currentEnrichArgs().some(
29207
29220
  (arg) => arg === "--no-open" || arg.startsWith("--no-open=")
@@ -29226,6 +29239,7 @@ function registerEnrichCommand(program) {
29226
29239
  }
29227
29240
  const client2 = new DeeplineClient();
29228
29241
  const args = currentEnrichArgs();
29242
+ const maxCreditsPerRun = parseMaxCreditsPerRun(options.maxCreditsPerRun);
29229
29243
  const config = await compileConfig({ client: client2, args, options });
29230
29244
  emitEnrichDebugValidationLines(config);
29231
29245
  if (options.dryRun) {
@@ -29234,7 +29248,8 @@ function registerEnrichCommand(program) {
29234
29248
  forceAliases: forceAliases2,
29235
29249
  playName: options.name,
29236
29250
  inlineRunJavascript: true,
29237
- failFast: options.failFast
29251
+ failFast: options.failFast,
29252
+ maxCreditsPerRun
29238
29253
  });
29239
29254
  const summary = summarizePlan(config, playSource2);
29240
29255
  if (options.json) {
@@ -29266,7 +29281,8 @@ function registerEnrichCommand(program) {
29266
29281
  forceAliases,
29267
29282
  playName: options.name,
29268
29283
  inlineRunJavascript: true,
29269
- failFast: options.failFast
29284
+ failFast: options.failFast,
29285
+ maxCreditsPerRun
29270
29286
  });
29271
29287
  const selectedRange = selectedSourceCsvRange(sourceCsvPath, rows);
29272
29288
  const sdkEnrichTelemetry = createSdkEnrichTelemetryContext({
@@ -37031,11 +37047,26 @@ function parseSetupPhases(value) {
37031
37047
  }
37032
37048
  const record = phase;
37033
37049
  if (!isSetupPhaseStatus(record.status)) return null;
37034
- phases[name] = {
37035
- status: record.status,
37036
- ...typeof record.outcome === "string" ? { outcome: record.outcome } : {},
37037
- ...typeof record.code === "string" ? { code: record.code } : {}
37038
- };
37050
+ switch (record.status) {
37051
+ case "pending":
37052
+ case "in_progress":
37053
+ phases[name] = { status: record.status };
37054
+ break;
37055
+ case "complete":
37056
+ phases[name] = {
37057
+ status: "complete",
37058
+ ...typeof record.outcome === "string" ? { outcome: record.outcome } : {}
37059
+ };
37060
+ break;
37061
+ case "waiting":
37062
+ if (typeof record.outcome !== "string") return null;
37063
+ phases[name] = { status: "waiting", outcome: record.outcome };
37064
+ break;
37065
+ case "failed":
37066
+ if (typeof record.code !== "string") return null;
37067
+ phases[name] = { status: "failed", code: record.code };
37068
+ break;
37069
+ }
37039
37070
  }
37040
37071
  return phases;
37041
37072
  }
@@ -38152,7 +38183,6 @@ import {
38152
38183
  } from "fs";
38153
38184
  import { dirname as dirname18, join as join21 } from "path";
38154
38185
  var CHECK_TIMEOUT_MS2 = 3e3;
38155
- var attemptedSync = false;
38156
38186
  function shouldSkipSkillsSync() {
38157
38187
  if (detectAgentRuntime() === "claude_cowork") {
38158
38188
  return true;
@@ -38456,8 +38486,7 @@ function writeSdkSkillsStatusLine(line) {
38456
38486
  `);
38457
38487
  }
38458
38488
  async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
38459
- if (attemptedSync || shouldSkipSkillsSync()) return;
38460
- attemptedSync = true;
38489
+ if (shouldSkipSkillsSync()) return;
38461
38490
  const usingPluginSkills = Boolean(activePluginSkillsDir());
38462
38491
  if (usingPluginSkills) {
38463
38492
  return;
package/dist/index.js CHANGED
@@ -763,7 +763,7 @@ var SDK_RELEASE = {
763
763
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
764
764
  // exposed storage-dependent synchronous access. This deliberate minor
765
765
  // release keeps lazy paging semantics independent of row residency.
766
- version: "0.2.36",
766
+ version: "0.2.38",
767
767
  contracts: {
768
768
  api: {
769
769
  name: "sdk-http-api",
package/dist/index.mjs CHANGED
@@ -689,7 +689,7 @@ var SDK_RELEASE = {
689
689
  // 0.2.0 makes Dataset Handles uniformly async-only after 0.1.320 briefly
690
690
  // exposed storage-dependent synchronous access. This deliberate minor
691
691
  // release keeps lazy paging semantics independent of row residency.
692
- version: "0.2.36",
692
+ version: "0.2.38",
693
693
  contracts: {
694
694
  api: {
695
695
  name: "sdk-http-api",
@@ -43,7 +43,6 @@
43
43
  "dist/bundling-sources/shared_libs/play-runtime/context.ts",
44
44
  "dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts",
45
45
  "dist/bundling-sources/shared_libs/play-runtime/csv-rename.ts",
46
- "dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts",
47
46
  "dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts",
48
47
  "dist/bundling-sources/shared_libs/play-runtime/dataset-id.ts",
49
48
  "dist/bundling-sources/shared_libs/play-runtime/dataset-lifecycle-log.ts",
@@ -51,7 +50,6 @@
51
50
  "dist/bundling-sources/shared_libs/play-runtime/db-session-crypto.ts",
52
51
  "dist/bundling-sources/shared_libs/play-runtime/db-session-plan.ts",
53
52
  "dist/bundling-sources/shared_libs/play-runtime/db-session.ts",
54
- "dist/bundling-sources/shared_libs/play-runtime/dedup-backend.ts",
55
53
  "dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts",
56
54
  "dist/bundling-sources/shared_libs/play-runtime/durability-store.ts",
57
55
  "dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts",
@@ -116,6 +114,7 @@
116
114
  "dist/bundling-sources/shared_libs/play-runtime/run-lifecycle-policy.ts",
117
115
  "dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts",
118
116
  "dist/bundling-sources/shared_libs/play-runtime/run-terminal-source.ts",
117
+ "dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-labels.ts",
119
118
  "dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts",
120
119
  "dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-modal-fallback.ts",
121
120
  "dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts",
@@ -5220,13 +5220,6 @@ authoring-contract-edition:${PLAY_AUTHORING_CONTRACT_EDITION}`
5220
5220
  }
5221
5221
  }
5222
5222
 
5223
- // ../shared_libs/play-runtime/dedup-backend.ts
5224
- var PLAY_DEDUP_BACKENDS = {
5225
- inMemory: "in_memory",
5226
- neonTable: "neon_table",
5227
- durableObject: "durable_object"
5228
- };
5229
-
5230
5223
  // ../shared_libs/play-runtime/scheduler-backend.ts
5231
5224
  var PLAY_SCHEDULER_BACKENDS = {
5232
5225
  /**
@@ -5250,9 +5243,8 @@ var PLAY_RUNTIME_PROVIDERS = {
5250
5243
  // axis to local_process (same as the local profile) via an explicit
5251
5244
  // runtimeBackend override at submit while tests drive local_process.
5252
5245
  runner: PLAY_RUNTIME_BACKENDS.daytona,
5253
- dedup: PLAY_DEDUP_BACKENDS.inMemory,
5254
5246
  artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
5255
- label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner + receipt-backed in-process dedup"
5247
+ label: "Absurd (Postgres-native durable) scheduler + one-shot Daytona runner"
5256
5248
  }
5257
5249
  };
5258
5250
  function defaultPlayRuntimeProvider() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.2.36",
3
+ "version": "0.2.38",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -1,268 +0,0 @@
1
- export interface BatchResult {
2
- rowId: number;
3
- rowKey?: string | null;
4
- result: unknown | null;
5
- }
6
-
7
- export interface MapExecutionFrame {
8
- mapInvocationId: string;
9
- mapNodeId?: string | null;
10
- logicalNamespace: string;
11
- artifactTableNamespace: string;
12
- status: 'running' | 'suspended' | 'completed' | 'failed';
13
- totalRows: number;
14
- completedRowKeys: string[];
15
- pendingRowKeys: string[];
16
- completedRowsCount?: number;
17
- pendingRowsCount?: number;
18
- failedRowsCount?: number;
19
- activeBoundaryId?: string | null;
20
- startedAt: number;
21
- updatedAt: number;
22
- }
23
-
24
- export interface PlayRowUpdate {
25
- key: string;
26
- rowId: number;
27
- tableNamespace?: string | null;
28
- status?: 'running' | 'completed' | 'failed';
29
- stage?: string | null;
30
- provider?: string | null;
31
- error?: string | null;
32
- dataPatch?: Record<string, unknown>;
33
- cellMetaPatch?: Record<
34
- string,
35
- {
36
- status:
37
- | 'queued'
38
- | 'running'
39
- | 'completed'
40
- | 'failed'
41
- | 'cached'
42
- | 'missed'
43
- | 'skipped';
44
- stage?: string | null;
45
- provider?: string | null;
46
- error?: string | null;
47
- producer?: {
48
- kind: 'play' | 'tool' | 'code';
49
- id?: string | null;
50
- displayName?: string | null;
51
- playId?: string | null;
52
- toolId?: string | null;
53
- runId?: string | null;
54
- } | null;
55
- reused?: boolean;
56
- completedAt?: number;
57
- staleAt?: number | null;
58
- staleAfterSeconds?: number | null;
59
- }
60
- >;
61
- }
62
-
63
- export type PlayExecutionEvent =
64
- | PlayActivityEvent
65
- | {
66
- type: 'map.preparing';
67
- mapInvocationId: string;
68
- mapNodeId?: string | null;
69
- logicalNamespace: string;
70
- artifactTableNamespace: string;
71
- totalRows: number;
72
- completedRows: number;
73
- pendingRows: number;
74
- at: number;
75
- }
76
- | {
77
- type: 'map.started';
78
- mapInvocationId: string;
79
- mapNodeId?: string | null;
80
- logicalNamespace: string;
81
- artifactTableNamespace: string;
82
- totalRows: number;
83
- completedRows: number;
84
- pendingRows: number;
85
- at: number;
86
- }
87
- | {
88
- type: 'map.progress';
89
- mapInvocationId: string;
90
- mapNodeId?: string | null;
91
- logicalNamespace: string;
92
- artifactTableNamespace: string;
93
- completedRows: number;
94
- failedRows: number;
95
- totalRows?: number;
96
- at: number;
97
- }
98
- | {
99
- type: 'map.row.updated';
100
- mapInvocationId: string;
101
- mapNodeId?: string | null;
102
- logicalNamespace: string;
103
- artifactTableNamespace: string;
104
- rowKey: string;
105
- rowStatus?: PlayRowUpdate['status'];
106
- fieldName?: string | null;
107
- stage?: string | null;
108
- provider?: string | null;
109
- at: number;
110
- }
111
- | {
112
- type: 'map.completed' | 'map.suspended' | 'map.resumed' | 'map.failed';
113
- mapInvocationId: string;
114
- mapNodeId?: string | null;
115
- logicalNamespace: string;
116
- artifactTableNamespace: string;
117
- completedRows: number;
118
- failedRows: number;
119
- totalRows?: number;
120
- at: number;
121
- };
122
-
123
- export interface PlayCheckpoint {
124
- completedBatches: Record<string, BatchResult[]>;
125
- completedToolBatches: Record<
126
- string,
127
- Record<string, { done: true; result: unknown | null }>
128
- >;
129
- resolvedWaterfalls: Record<string, Record<string, unknown>>;
130
- resolvedBoundaries?: Record<
131
- string,
132
- | {
133
- kind: 'sleep';
134
- delayMs: number;
135
- completedAt?: number;
136
- scope?: {
137
- type: 'workflow' | 'map_row';
138
- tableNamespace?: string;
139
- rowKey?: string;
140
- rowIndex?: number;
141
- fieldName?: string;
142
- };
143
- }
144
- | {
145
- kind: 'integration_event';
146
- eventKey: string;
147
- timeoutMs: number;
148
- provider?: string;
149
- toolId?: string;
150
- messageRef?: {
151
- channel: string;
152
- ts: string;
153
- };
154
- output?: unknown;
155
- completedAt?: number;
156
- }
157
- | {
158
- kind: 'fetch';
159
- url: string;
160
- method: string;
161
- output?: unknown;
162
- completedAt?: number;
163
- }
164
- | {
165
- kind: 'step';
166
- stepId: string;
167
- output?: unknown;
168
- completedAt?: number;
169
- }
170
- >;
171
- mapFrames?: Record<string, MapExecutionFrame>;
172
- }
173
-
174
- export interface PlayStepRowResult {
175
- rowId: number;
176
- status: 'completed' | 'failed' | 'missed' | 'skipped';
177
- success: boolean;
178
- provider?: string;
179
- value?: unknown;
180
- error?: string | null;
181
- }
182
-
183
- export type PlayStep =
184
- | { type: 'start'; trigger?: string; description?: string }
185
- | { type: 'csv_load'; arg?: string; rows?: number; description?: string }
186
- | {
187
- type: 'dataset';
188
- items: number;
189
- fields?: string[];
190
- substeps: PlayDatasetSubstep[];
191
- description?: string;
192
- }
193
- | {
194
- type: 'waterfall';
195
- tool?: string;
196
- providers?: string[];
197
- id?: string;
198
- output?: string;
199
- minResults?: number;
200
- steps?: Array<{
201
- id: string;
202
- kind?: 'tool' | 'code';
203
- toolId?: string;
204
- results: PlayStepRowResult[];
205
- }>;
206
- results: PlayStepRowResult[];
207
- description?: string;
208
- }
209
- | {
210
- type: 'tool';
211
- toolId: string;
212
- results: PlayStepRowResult[];
213
- description?: string;
214
- }
215
- | {
216
- type: 'play_call';
217
- playId: string;
218
- execution?: 'inline';
219
- results?: PlayStepRowResult[];
220
- nestedSteps: PlayStep[];
221
- description?: string;
222
- }
223
- | {
224
- type: 'run_javascript';
225
- alias: string;
226
- results: PlayStepRowResult[];
227
- description?: string;
228
- }
229
- | { type: 'return'; outputRows: number; description?: string };
230
-
231
- export type PlayDatasetSubstep =
232
- | {
233
- type: 'waterfall';
234
- tool?: string;
235
- providers?: string[];
236
- id?: string;
237
- output?: string;
238
- minResults?: number;
239
- steps?: Array<{
240
- id: string;
241
- kind?: 'tool' | 'code';
242
- toolId?: string;
243
- results: PlayStepRowResult[];
244
- }>;
245
- results: PlayStepRowResult[];
246
- description?: string;
247
- }
248
- | {
249
- type: 'tool';
250
- toolId: string;
251
- results: PlayStepRowResult[];
252
- description?: string;
253
- }
254
- | {
255
- type: 'play_call';
256
- playId: string;
257
- execution?: 'inline';
258
- results?: PlayStepRowResult[];
259
- nestedSteps: PlayStep[];
260
- description?: string;
261
- }
262
- | {
263
- type: 'run_javascript';
264
- alias: string;
265
- results: PlayStepRowResult[];
266
- description?: string;
267
- };
268
- import type { PlayActivityEvent } from './activity-observation';