deepline 0.1.38 → 0.1.39

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.
@@ -52,10 +52,7 @@ import {
52
52
  import {
53
53
  adaptV2ExecuteResponseToToolResult,
54
54
  createToolExecuteResult,
55
- deserializeToolExecuteResult,
56
- isSerializedToolExecuteResult,
57
55
  isToolExecuteResult,
58
- serializeToolExecuteResult,
59
56
  type ToolExecuteResult,
60
57
  type ToolResultMetadataInput,
61
58
  } from '../../../shared_libs/play-runtime/tool-result';
@@ -451,7 +448,7 @@ async function probeHarnessOnce(
451
448
  */
452
449
  const RUNTIME_API_TIMEOUT_MS = 30_000;
453
450
  const RUNTIME_API_PLAY_RUN_TIMEOUT_MS = 75_000;
454
- const RUNTIME_API_RETRY_DELAYS_MS = [250, 750, 1500, 3000, 5000, 10000] as const;
451
+ const RUNTIME_API_RETRY_DELAYS_MS = [250, 750, 1500] as const;
455
452
  let loggedMissingRuntimeApiBinding = false;
456
453
 
457
454
  async function fetchRuntimeApi(
@@ -464,17 +461,7 @@ async function fetchRuntimeApi(
464
461
  ? RUNTIME_API_PLAY_RUN_TIMEOUT_MS
465
462
  : RUNTIME_API_TIMEOUT_MS;
466
463
  const controller = new AbortController();
467
- let timeout: ReturnType<typeof setTimeout> | null = null;
468
- const timeoutPromise = new Promise<never>((_, reject) => {
469
- timeout = setTimeout(() => {
470
- controller.abort();
471
- reject(
472
- new Error(
473
- `[play-harness] runtime API call timed out after ${timeoutMs}ms. path=${path} baseUrl=${baseUrl}`,
474
- ),
475
- );
476
- }, timeoutMs);
477
- });
464
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
478
465
  try {
479
466
  const mergedInit: RequestInit = {
480
467
  ...init,
@@ -488,15 +475,11 @@ async function fetchRuntimeApi(
488
475
  `[play-harness] RUNTIME_API binding missing; using public runtime API transport. path=${path}`,
489
476
  );
490
477
  }
491
- return await Promise.race([
492
- fetch(`${baseUrl.replace(/\/$/, '')}${path}`, mergedInit),
493
- timeoutPromise,
494
- ]);
478
+ return await fetch(`${baseUrl.replace(/\/$/, '')}${path}`, mergedInit);
495
479
  }
496
- const responsePromise = cachedRuntimeApiBinding.fetch(
480
+ return await cachedRuntimeApiBinding.fetch(
497
481
  new Request(`${baseUrl.replace(/\/$/, '')}${path}`, mergedInit),
498
482
  );
499
- return await Promise.race([responsePromise, timeoutPromise]);
500
483
  } catch (err) {
501
484
  if (err instanceof Error && err.name === 'AbortError') {
502
485
  throw new Error(
@@ -505,7 +488,7 @@ async function fetchRuntimeApi(
505
488
  }
506
489
  throw err;
507
490
  } finally {
508
- if (timeout) clearTimeout(timeout);
491
+ clearTimeout(timer);
509
492
  }
510
493
  }
511
494
 
@@ -741,8 +724,7 @@ function isRetryableRuntimeApiResponse(status: number, body: string): boolean {
741
724
  status === 429 ||
742
725
  status === 502 ||
743
726
  status === 503 ||
744
- status === 504 ||
745
- status === 530
727
+ status === 504
746
728
  ) {
747
729
  return true;
748
730
  }
@@ -1472,21 +1454,6 @@ function executeSyntheticTransientRetry(
1472
1454
  function executeSyntheticTestRateLimit(
1473
1455
  input: Record<string, unknown>,
1474
1456
  ): Record<string, unknown> {
1475
- if (
1476
- typeof input.key === 'string' &&
1477
- input.key.startsWith('public-error-message-regression')
1478
- ) {
1479
- throw new ToolHttpError(
1480
- [
1481
- 'tool test_rate_limit 422 attempt 1/1:',
1482
- 'Synthetic public test error with a redacted token=[REDACTED].',
1483
- 'code=TEST_PUBLIC_ERROR.',
1484
- 'failure_description=The fake test provider intentionally raised a typed public error so V2 runner output preserves actionable details.',
1485
- 'operator_hint=Use this no-bill test provider fixture when verifying play runner error rendering.',
1486
- ].join(' '),
1487
- null,
1488
- );
1489
- }
1490
1457
  const rowNumber =
1491
1458
  typeof input.row_number === 'number' && Number.isInteger(input.row_number)
1492
1459
  ? input.row_number
@@ -1883,39 +1850,8 @@ type WorkerMapChunkSummary<T extends Record<string, unknown>> = {
1883
1850
  cachedRows?: T[];
1884
1851
  };
1885
1852
 
1886
- function serializeDurableStepValue<T>(value: T, depth = 0): T {
1887
- if (depth > 20 || value == null) return value;
1888
- if (isToolExecuteResult(value)) return serializeToolExecuteResult(value) as T;
1889
- if (isDatasetHandle(value)) return serializeValue(value, depth) as T;
1890
- if (Array.isArray(value)) {
1891
- return value.map((entry) => serializeDurableStepValue(entry, depth + 1)) as T;
1892
- }
1893
- if (typeof value !== 'object') return value;
1894
- return Object.fromEntries(
1895
- Object.entries(value as Record<string, unknown>).map(([key, child]) => [
1896
- key,
1897
- serializeDurableStepValue(child, depth + 1),
1898
- ]),
1899
- ) as T;
1900
- }
1901
-
1902
- function deserializeDurableStepValue<T>(value: T, depth = 0): T {
1903
- if (depth > 20 || value == null) return value;
1904
- if (isSerializedToolExecuteResult(value)) {
1905
- return deserializeToolExecuteResult(value) as T;
1906
- }
1907
- if (Array.isArray(value)) {
1908
- return value.map((entry) =>
1909
- deserializeDurableStepValue(entry, depth + 1),
1910
- ) as T;
1911
- }
1912
- if (typeof value !== 'object') return value;
1913
- return Object.fromEntries(
1914
- Object.entries(value as Record<string, unknown>).map(([key, child]) => [
1915
- key,
1916
- deserializeDurableStepValue(child, depth + 1),
1917
- ]),
1918
- ) as T;
1853
+ function toWorkflowSerializableValue<T>(value: T): T {
1854
+ return JSON.parse(JSON.stringify(serializeValue(value, 0))) as T;
1919
1855
  }
1920
1856
 
1921
1857
  type WorkerStepResolver = (
@@ -2037,8 +1973,8 @@ async function executeWorkerStepProgram(
2037
1973
  let currentRow: Record<string, unknown> = cloneCsvAliasedRow(inputRow);
2038
1974
  for (const step of program.steps) {
2039
1975
  const stepPath = [...(recorder?.path ?? []), step.name];
2040
- const runStep = async (): Promise<WorkerStepResolution> => {
2041
- const resolution = await executeWorkerStepResolver(
1976
+ const runStep = async () =>
1977
+ await executeWorkerStepResolver(
2042
1978
  step.resolver,
2043
1979
  currentRow,
2044
1980
  ctx,
@@ -2046,15 +1982,10 @@ async function executeWorkerStepProgram(
2046
1982
  recorder
2047
1983
  ? {
2048
1984
  ...recorder,
2049
- path: stepPath,
2050
- }
2051
- : undefined,
1985
+ path: stepPath,
1986
+ }
1987
+ : undefined,
2052
1988
  );
2053
- return {
2054
- value: serializeDurableStepValue(resolution.value),
2055
- ...(resolution.status ? { status: resolution.status } : {}),
2056
- };
2057
- };
2058
1989
  const resolution = workflowStep
2059
1990
  ? await (
2060
1991
  workflowStep.do as unknown as (
@@ -2063,7 +1994,7 @@ async function executeWorkerStepProgram(
2063
1994
  ) => Promise<WorkerStepResolution>
2064
1995
  )(stepPath.join('.'), runStep)
2065
1996
  : await runStep();
2066
- const value = deserializeDurableStepValue(resolution.value);
1997
+ const value = resolution.value;
2067
1998
  currentRow = cloneCsvAliasedRow(currentRow, { [step.name]: value });
2068
1999
  if (recorder) {
2069
2000
  const stepId = stepPath.join('.');
@@ -3622,10 +3553,10 @@ function createMinimalWorkerCtx(
3622
3553
  rowsSkipped,
3623
3554
  outputDatasetId: `map:${name}`,
3624
3555
  hash,
3625
- preview: serializeDurableStepValue(out.slice(0, 5)),
3556
+ preview: toWorkflowSerializableValue(out.slice(0, 5)),
3626
3557
  cachedRows:
3627
3558
  out.length <= WORKER_DATASET_IN_MEMORY_ROWS
3628
- ? serializeDurableStepValue(out)
3559
+ ? toWorkflowSerializableValue(out)
3629
3560
  : undefined,
3630
3561
  };
3631
3562
  };
@@ -3853,16 +3784,13 @@ function createMinimalWorkerCtx(
3853
3784
  ts: nowMs(),
3854
3785
  });
3855
3786
  }
3856
- // Static pipeline JS blocks already execute inside a Workflow step.
3857
- // Wrapping each generated waterfall step in another step.do can leave
3858
- // Workers preview runs parked after the last provider callback.
3859
3787
  return (await executeWorkerStepProgram(
3860
3788
  program,
3861
3789
  input,
3862
3790
  ctx,
3863
3791
  0,
3864
3792
  undefined,
3865
- undefined,
3793
+ workflowStep,
3866
3794
  )) as T;
3867
3795
  },
3868
3796
  async csv<T extends Record<string, unknown> = Record<string, unknown>>(
@@ -626,27 +626,10 @@ export interface PlayCheckResult {
626
626
  valid: boolean;
627
627
  errors: string[];
628
628
  staticPipeline?: Record<string, unknown> | null;
629
- toolGetterHints?: PlayCheckToolGetterHint[];
630
629
  artifactHash?: string | null;
631
630
  graphHash?: string | null;
632
631
  }
633
632
 
634
- export interface PlayCheckToolGetterHint {
635
- toolId: string;
636
- lists: Array<{
637
- name: string;
638
- expression: string;
639
- raw?: string;
640
- }>;
641
- values: Array<{
642
- name: string;
643
- expression: string;
644
- raw?: string;
645
- }>;
646
- raw?: string;
647
- unavailable?: string;
648
- }
649
-
650
633
  /**
651
634
  * Request body for starting a play run via {@link DeeplineClient.startPlayRun}.
652
635
  *
@@ -1,2 +1,2 @@
1
- export const SDK_VERSION = "0.1.38";
2
- export const SDK_API_CONTRACT = "2026-05-v2-tool-response-play-guardrails";
1
+ export const SDK_VERSION = "0.1.39";
2
+ export const SDK_API_CONTRACT = "2026-05-v2-play-live-definition";
@@ -1,5 +1,4 @@
1
1
  export type {
2
- SerializedToolExecuteResult,
3
2
  ToolExecuteResult,
4
3
  ToolResultExecutionMetadata,
5
4
  ToolResultMetadata,
@@ -11,7 +10,6 @@ export type {
11
10
  } from './tool-result-types';
12
11
 
13
12
  import type {
14
- SerializedToolExecuteResult,
15
13
  ToolExecuteResult,
16
14
  ToolResultExecutionMetadata,
17
15
  ToolResultListAccessor,
@@ -24,8 +22,6 @@ import type {
24
22
 
25
23
  type PathSegment = string | number | '*';
26
24
 
27
- const SERIALIZED_TOOL_EXECUTE_RESULT_KIND = 'deepline.tool_execute_result.v1';
28
-
29
25
  const TARGET_FALLBACK_KEYS: Record<string, readonly RegExp[]> = {
30
26
  email: [/^email$/i, /^address$/i, /email/i],
31
27
  phone: [/^phone$/i, /mobile/i, /phone/i, /telephone/i],
@@ -459,10 +455,11 @@ function buildTargets(
459
455
  }
460
456
 
461
457
  function buildLists(
462
- resolved: Record<string, { path: string; rows: Record<string, unknown>[] }>,
458
+ result: unknown,
463
459
  metadata: ToolResultMetadataInput,
464
460
  ): Record<string, ToolResultListMetadata> {
465
461
  const lists: Record<string, ToolResultListMetadata> = {};
462
+ const resolved = resolveListRows(result, metadata.listExtractorPaths);
466
463
  for (const [name, list] of Object.entries(resolved)) {
467
464
  lists[name] = {
468
465
  path: list.path,
@@ -502,12 +499,11 @@ function buildExtractedAccessors(
502
499
  }
503
500
 
504
501
  function buildListAccessors(
505
- resolved: Record<string, { path: string; rows: Record<string, unknown>[] }>,
502
+ result: unknown,
506
503
  lists: Record<string, ToolResultListMetadata>,
507
504
  ): Record<string, ToolResultListAccessor> {
508
505
  return Object.fromEntries(
509
506
  Object.entries(lists).map(([name, metadata]) => {
510
- const rows = resolved[name]?.rows ?? [];
511
507
  const accessor = {
512
508
  path: metadata.path,
513
509
  count: metadata.count,
@@ -515,7 +511,7 @@ function buildListAccessors(
515
511
  } as ToolResultListAccessor;
516
512
  Object.defineProperty(accessor, 'get', {
517
513
  value() {
518
- return rows;
514
+ return normalizeRows(getAtPath(result, metadata.path)) ?? [];
519
515
  },
520
516
  enumerable: false,
521
517
  });
@@ -543,11 +539,7 @@ export function createToolExecuteResult<TResult = unknown>(input: {
543
539
  resultRoot,
544
540
  input.metadata.resultIdentityGetters,
545
541
  );
546
- const resolvedLists = resolveListRows(
547
- resultRoot,
548
- input.metadata.listExtractorPaths,
549
- );
550
- const lists = buildLists(resolvedLists, input.metadata);
542
+ const lists = buildLists(resultRoot, input.metadata);
551
543
  const metadata = {
552
544
  toolId: input.metadata.toolId,
553
545
  execution: input.execution,
@@ -559,7 +551,7 @@ export function createToolExecuteResult<TResult = unknown>(input: {
559
551
  ...(result.meta ? { meta: result.meta } : {}),
560
552
  };
561
553
  const extractedValues = buildExtractedAccessors(targets);
562
- const extractedLists = buildListAccessors(resolvedLists, lists);
554
+ const extractedLists = buildListAccessors(resultRoot, lists);
563
555
  const wrapper = {
564
556
  status: input.status,
565
557
  ...(input.jobId ? { job_id: input.jobId } : {}),
@@ -594,70 +586,6 @@ export function isToolExecuteResult(
594
586
  );
595
587
  }
596
588
 
597
- function metadataInputFromToolExecuteResult(
598
- value: ToolExecuteResult,
599
- ): ToolResultMetadataInput {
600
- return {
601
- toolId: value._metadata.toolId,
602
- resultIdentityGetters: Object.fromEntries(
603
- Object.entries(value._metadata.targets).map(([target, info]) => [
604
- target,
605
- [info.path],
606
- ]),
607
- ),
608
- listExtractorPaths: Object.values(value._metadata.lists).map(
609
- (list) => list.path,
610
- ),
611
- listIdentityGetters: Object.fromEntries(
612
- Object.values(value._metadata.lists)
613
- .flatMap((list) => Object.entries(list.keys))
614
- .map(([target, path]) => [target, [path]]),
615
- ),
616
- };
617
- }
618
-
619
- export function serializeToolExecuteResult(
620
- value: ToolExecuteResult,
621
- ): SerializedToolExecuteResult {
622
- return {
623
- __kind: SERIALIZED_TOOL_EXECUTE_RESULT_KIND,
624
- status: value.status,
625
- toolResponse: {
626
- raw: value.toolResponse.raw,
627
- ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
628
- },
629
- metadata: metadataInputFromToolExecuteResult(value),
630
- execution: value._metadata.execution,
631
- };
632
- }
633
-
634
- export function isSerializedToolExecuteResult(
635
- value: unknown,
636
- ): value is SerializedToolExecuteResult {
637
- return (
638
- isRecord(value) &&
639
- value.__kind === SERIALIZED_TOOL_EXECUTE_RESULT_KIND &&
640
- typeof value.status === 'string' &&
641
- isRecord(value.toolResponse) &&
642
- isRecord(value.metadata) &&
643
- isRecord(value.execution)
644
- );
645
- }
646
-
647
- export function deserializeToolExecuteResult(
648
- value: SerializedToolExecuteResult,
649
- ): ToolExecuteResult {
650
- return createToolExecuteResult({
651
- status: value.status,
652
- result: {
653
- data: value.toolResponse.raw,
654
- ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
655
- },
656
- metadata: value.metadata,
657
- execution: value.execution,
658
- });
659
- }
660
-
661
589
  export function cloneToolExecuteResultWithExecution<TResult>(
662
590
  value: ToolExecuteResult<TResult>,
663
591
  execution: ToolResultExecutionMetadata,
@@ -672,7 +600,23 @@ export function cloneToolExecuteResultWithExecution<TResult>(
672
600
  data: value.toolResponse.raw,
673
601
  ...(value.toolResponse.meta ? { meta: value.toolResponse.meta } : {}),
674
602
  } as TResult,
675
- metadata: metadataInputFromToolExecuteResult(value),
603
+ metadata: {
604
+ toolId: value._metadata.toolId,
605
+ resultIdentityGetters: Object.fromEntries(
606
+ Object.entries(value._metadata.targets).map(([target, info]) => [
607
+ target,
608
+ [info.path],
609
+ ]),
610
+ ),
611
+ listExtractorPaths: Object.values(value._metadata.lists).map(
612
+ (list) => list.path,
613
+ ),
614
+ listIdentityGetters: Object.fromEntries(
615
+ Object.values(value._metadata.lists)
616
+ .flatMap((list) => Object.entries(list.keys))
617
+ .map(([target, path]) => [target, [path]]),
618
+ ),
619
+ },
676
620
  execution,
677
621
  meta: isRecord(value.meta) ? value.meta : undefined,
678
622
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.38",
3
+ "version": "0.1.39",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {