deepline 0.1.55 → 0.1.57

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.
@@ -161,10 +161,20 @@ export type {
161
161
  ToolResultTargetAccessor as ToolExtractedValue,
162
162
  } from '../../shared_libs/play-runtime/tool-result-types.js';
163
163
 
164
+ /**
165
+ * Keyword-style request object for `ctx.tools.execute(...)`.
166
+ *
167
+ * The `tool` value comes from live tool discovery. The `id` is the stable
168
+ * logical call name inside this play and participates in replay/idempotency.
169
+ */
164
170
  export type ToolExecutionRequest = {
171
+ /** Stable logical id for this tool call within the play. */
165
172
  id: string;
173
+ /** Current tool id from `deepline tools search` / `deepline tools describe`. */
166
174
  tool: string;
175
+ /** JSON-serializable provider/tool input object. */
167
176
  input: Record<string, unknown>;
177
+ /** Human-readable description for logs and run inspection. */
168
178
  description?: string;
169
179
  staleAfterSeconds?: number;
170
180
  };
@@ -226,10 +236,32 @@ export type MapStepBuilder<
226
236
  InputRow extends object,
227
237
  OutputRow extends object,
228
238
  > = {
239
+ /**
240
+ * Define one output column for every row in this map dataset.
241
+ *
242
+ * The `name` becomes a field on each output row. For example,
243
+ * `.step('contact', ...)` creates `row.contact` in later map stages; it does
244
+ * not spread returned object fields such as `contact.email` into `row.email`.
245
+ * Add a later column resolver when you want a top-level export field:
246
+ * `.step('email', row => row.contact?.email ?? null)`.
247
+ *
248
+ * @param name - Output column name.
249
+ * @param resolver - Computes the value for one row.
250
+ * @returns The same map builder with the new column type.
251
+ */
229
252
  step<Name extends string, Value>(
230
253
  name: Name,
231
254
  resolver: MapStepResolver<OutputRow, Value>,
232
255
  ): MapStepBuilder<InputRow, OutputRow & Record<Name, Value>>;
256
+ /**
257
+ * Execute the row-column program and return a durable dataset handle.
258
+ *
259
+ * The returned {@link PlayDataset} preserves one output row per input row,
260
+ * with original fields merged with the columns produced by `.step(...)`.
261
+ *
262
+ * @param options - Run options.
263
+ * @returns Output rows as a dataset handle.
264
+ */
233
265
  run(options?: {
234
266
  description?: string;
235
267
  staleAfterSeconds?: number;
@@ -270,10 +302,15 @@ export type ColumnMap<TRow extends object> = Partial<
270
302
  Record<Extract<keyof TRow, string>, string | readonly string[]>
271
303
  >;
272
304
 
305
+ /** Options for loading a staged CSV with `ctx.csv(...)`. */
273
306
  export type CsvOptions = {
307
+ /** Human-readable description for runtime logs and inspection. */
274
308
  description?: string;
309
+ /** Canonical field-to-header aliases, e.g. `{ domain: ['domain', 'Company Domain'] }`. */
275
310
  columns?: CsvRenameMap;
311
+ /** Header rename map; use `columns` for new code. */
276
312
  rename?: CsvRenameMap;
313
+ /** Canonical fields that must be present after header normalization. */
277
314
  required?: readonly string[];
278
315
  };
279
316
 
@@ -324,17 +361,22 @@ export type CsvOptions = {
324
361
  */
325
362
  export interface DeeplinePlayRuntimeContext {
326
363
  /**
327
- * Load a CSV file as a dataset handle.
364
+ * Load a staged CSV file as a durable dataset handle.
328
365
  *
329
- * The CSV must be staged or available at the given path. Each row becomes
330
- * an object keyed by column headers.
366
+ * Use this when a play receives a CSV path from the CLI or API and row work
367
+ * should continue through {@link DeeplinePlayRuntimeContext.map}. The path is
368
+ * normally an input field such as `input.csv`, populated by
369
+ * `deepline plays run my.play.ts --csv rows.csv`.
370
+ *
371
+ * Each CSV row becomes an object keyed by canonical column names. Use
372
+ * `options.columns` / `options.rename` to map user headers such as
373
+ * `"Company Domain"` to stable code fields such as `domain`.
331
374
  *
332
375
  * @typeParam T - Row type (defaults to `Record<string, unknown>`)
333
- * @param path - Relative path to the CSV file
334
- * The returned dataset supports `for await`, `peek()`, `count()`, and
335
- * explicit `materialize()` for small result sets.
376
+ * @param path - Staged CSV path.
377
+ * @param options - CSV load options.
336
378
  *
337
- * @returns Parsed dataset rows
379
+ * @returns A {@link PlayDataset} whose rows should usually flow directly into `ctx.map(...)`.
338
380
  */
339
381
  csv<T = Record<string, unknown>>(
340
382
  path: string,
@@ -342,27 +384,28 @@ export interface DeeplinePlayRuntimeContext {
342
384
  ): Promise<PlayDataset<T>>;
343
385
 
344
386
  /**
345
- * Fan-out: process each item through one or more named columns.
387
+ * Create a persisted row dataset/table from input rows.
346
388
  *
347
- * Each key in `columns` becomes an output column. Each value is an async
348
- * callback `(row, ctx) => result` that receives the current row and the
349
- * play context call tools, run waterfalls, do arbitrary logic.
389
+ * `ctx.map` is Deepline's row-work primitive. It records row identity,
390
+ * progress, retries, table output, and idempotency for a collection of rows.
391
+ * Use `.step(name, resolver)` on the returned builder to define output
392
+ * columns, then `.run(...)` to execute the row program.
350
393
  *
351
- * Items are processed in parallel (paced by the rate-limit scheduler).
352
- * `key` identifies the logical output dataset/table. Row identity is derived
353
- * automatically from item content unless advanced run options override it.
354
- * `options.staleAfterSeconds` intentionally partitions the durable cache on a
355
- * relative time window. Use `86400` for daily reruns; retries inside the same
356
- * window still replay safely.
394
+ * The `key` identifies the logical dataset/table. Renaming it is a persistence
395
+ * migration: existing rows may no longer be reused. Row identity is derived
396
+ * automatically from input row content unless `.run({ key: ... })` overrides
397
+ * it with stable business fields such as `domain`, `email`, or `linkedin_url`.
357
398
  *
358
- * Returns a dataset handle containing the original rows merged with the new
359
- * columns. Input may be a normal array, iterable, async iterable, or another
360
- * play dataset handle.
399
+ * By default, `ctx.map` is row-preserving: one input row produces one output
400
+ * row, with original fields merged with the columns produced by
401
+ * `.step(...)`. If one input entity must become many output rows, use the
402
+ * documented expand/flatten recipe instead of assuming `ctx.map` changes
403
+ * row cardinality.
361
404
  *
362
405
  * @typeParam T - Row type
363
- * @param key - Logical output dataset/table name (e.g. `'companies'`, `'email_lookup'`)
364
- * @param items - Input rows or dataset handle
365
- * @returns Dataset of rows merged with the computed column values
406
+ * @param key - Dataset/table name.
407
+ * @param items - Input rows.
408
+ * @returns A builder. Calling `.run()` returns a `PlayDataset` of rows plus computed columns.
366
409
  *
367
410
  * @example Single tool per row
368
411
  * ```typescript
@@ -405,25 +448,78 @@ export interface DeeplinePlayRuntimeContext {
405
448
  /**
406
449
  * Execute a single tool with a keyword-style request object.
407
450
  *
408
- * @param request.id - Stable step key for idempotent execution
409
- * @param request.tool - Tool identifier (e.g. `'test_company_search'`)
410
- * @param request.input - Tool-specific input parameters
411
- * @returns The tool's output
451
+ * @param request - Tool call request.
452
+ * @returns Tool execution result.
412
453
  */
413
454
  execute<TOutput = LoosePlayObject>(
414
455
  request: ToolExecutionRequest & { staleAfterSeconds?: number },
415
456
  ): Promise<ToolExecuteResult<TOutput>>;
416
457
  };
458
+ /**
459
+ * Execute a single tool by stable step key and tool ID.
460
+ *
461
+ * Shorthand for `ctx.tools.execute(...)`; this is the preferred spelling in
462
+ * row-level step programs.
463
+ */
464
+ tool<TOutput = LoosePlayObject>(
465
+ key: string,
466
+ toolId: string,
467
+ input: Record<string, unknown>,
468
+ options?: { description?: string },
469
+ ): Promise<ToolExecuteResult<TOutput>>;
470
+ /**
471
+ * Run a reusable step program against one scalar input object.
472
+ *
473
+ * `steps().step(...)` is a composable mini-pipeline. Use `ctx.runSteps(...)`
474
+ * when that mini-pipeline should execute outside a row dataset. Inside a
475
+ * `ctx.map` column resolver, pass the step program directly to
476
+ * `.step(name, program)` instead.
477
+ *
478
+ * @param program - Step program.
479
+ * @param input - Program input.
480
+ * @param options - Run options.
481
+ * @returns Program output.
482
+ */
417
483
  runSteps<TInput extends Record<string, unknown>, TOutput>(
418
484
  program: StepProgram<TInput, unknown, TOutput>,
419
485
  input: TInput,
420
486
  options?: { description?: string },
421
487
  ): Promise<TOutput>;
488
+ /**
489
+ * Create one scalar checkpoint for the whole play run.
490
+ *
491
+ * Use `ctx.step` when a value is nondeterministic, expensive, external, or
492
+ * useful to inspect as a named boundary. The first execution stores the
493
+ * JSON-serializable output under `id`; replay and retries return the stored
494
+ * value instead of running `run` again.
495
+ *
496
+ * Plain deterministic assignment does not need `ctx.step`. Use
497
+ * `ctx.map(...).step(...)`, not `ctx.step`, when the value should become a
498
+ * field on each exported row.
499
+ *
500
+ * @param id - Checkpoint id.
501
+ * @param run - Computes the value once.
502
+ * @param options - Checkpoint options.
503
+ * @returns Checkpoint value.
504
+ */
422
505
  step<T>(
423
506
  id: string,
424
507
  run: () => T | Promise<T>,
425
508
  options?: { staleAfterSeconds?: number },
426
509
  ): Promise<T>;
510
+ /**
511
+ * Durable HTTP fetch.
512
+ *
513
+ * Use this for non-provider HTTP calls that must replay safely. The response
514
+ * is recorded under `key` so workflow replay sees the same value. Prefer
515
+ * `ctx.tools.execute(...)` for Deepline-managed provider APIs because tools
516
+ * handle auth, retries, rate limits, extraction metadata, and spend tracking.
517
+ *
518
+ * @param key - Checkpoint id.
519
+ * @param url - URL to fetch.
520
+ * @param init - Fetch options.
521
+ * @returns Recorded response.
522
+ */
427
523
  fetch(
428
524
  key: string,
429
525
  url: string | URL,
@@ -438,6 +534,22 @@ export interface DeeplinePlayRuntimeContext {
438
534
  bodyText: string;
439
535
  json: unknown | null;
440
536
  }>;
537
+ /**
538
+ * Invoke another registered or file-backed play as a child workflow.
539
+ *
540
+ * Use this for real composition boundaries, especially when a fitting
541
+ * scalar prebuilt play already encodes provider order, fallbacks,
542
+ * normalization, and no-result behavior. Do not invoke plays through
543
+ * `ctx.tools.execute`; tools and plays are separate namespaces.
544
+ *
545
+ * `key` is the stable child-call identity for idempotency and traceability.
546
+ *
547
+ * @param key - Child call id.
548
+ * @param playRef - Play name or handle.
549
+ * @param input - Child input.
550
+ * @param options - Run options.
551
+ * @returns Child play output.
552
+ */
441
553
  runPlay(
442
554
  key: string,
443
555
  playRef: string | PlayReferenceLike,
@@ -646,11 +758,24 @@ export type PlayInputContract<TInput> = {
646
758
  readonly __inputType?: TInput;
647
759
  };
648
760
 
761
+ /**
762
+ * Object-form play definition accepted by `definePlay(config)`.
763
+ *
764
+ * Use this form when the input contract should be explicit at definition time
765
+ * through `defineInput<T>(schema)`, or when configuration reads clearer as one
766
+ * object. The shorthand `definePlay(name, fn, bindings?)` is equivalent for
767
+ * simple file-backed plays.
768
+ */
649
769
  export type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = {
770
+ /** Play id/name. */
650
771
  id: string;
772
+ /** Input schema. */
651
773
  input: PlayInputContract<TInput>;
774
+ /** Play function. */
652
775
  run: (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>;
776
+ /** Trigger bindings. */
653
777
  bindings?: PlayBindings;
778
+ /** Billing options. */
654
779
  billing?: PlayBindings['billing'];
655
780
  };
656
781
 
@@ -1184,9 +1309,10 @@ export function defineInput<TInput>(
1184
1309
  *
1185
1310
  * @typeParam TInput - The input type accepted by the play
1186
1311
  * @typeParam TOutput - The return type of the play
1187
- * @param name - Unique play name (used for publishing, running by name, and CLI reference)
1188
- * @param fn - Async function that receives a {@link DeeplinePlayRuntimeContext} and typed input
1189
- * @param bindings - Optional trigger bindings (cron schedule, webhook with HMAC)
1312
+ * @param config - Object-form play config.
1313
+ * @param name - Play name.
1314
+ * @param fn - Play function.
1315
+ * @param bindings - Trigger bindings.
1190
1316
  * @returns A {@link DefinedPlay} that is both callable and has lifecycle methods
1191
1317
  *
1192
1318
  * @example Basic play
@@ -1207,9 +1333,9 @@ export function defineInput<TInput>(
1207
1333
  *
1208
1334
  * @example CSV processing play
1209
1335
  * ```typescript
1210
- * export default definePlay('bulk-enrich', async (ctx) => {
1211
- * const leads = await ctx.csv('leads.csv');
1212
- * ctx.log(`Processing ${leads.length} rows`);
1336
+ * export default definePlay('bulk-enrich', async (ctx, input: { csv: string }) => {
1337
+ * const leads = await ctx.csv(input.csv);
1338
+ * ctx.log(`Processing ${await leads.count()} rows`);
1213
1339
  * const results = await ctx
1214
1340
  * .map('companies', leads)
1215
1341
  * .step('company', (row, ctx) =>
@@ -1256,6 +1382,14 @@ export function defineInput<TInput>(
1256
1382
  export function definePlay<TInput, TOutput extends PlayReturnObject>(
1257
1383
  config: DefinePlayConfig<TInput, TOutput>,
1258
1384
  ): DefinedPlay<TInput, TOutput>;
1385
+ /**
1386
+ * Define a play with a name and function.
1387
+ *
1388
+ * @param name - Play name.
1389
+ * @param fn - Play function.
1390
+ * @param bindings - Trigger bindings.
1391
+ * @returns Play handle.
1392
+ */
1259
1393
  export function definePlay<TInput, TOutput extends PlayReturnObject>(
1260
1394
  name: string,
1261
1395
  fn: (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>,
@@ -50,10 +50,10 @@ export type SdkRelease = {
50
50
  };
51
51
 
52
52
  export const SDK_RELEASE = {
53
- version: '0.1.55',
54
- apiContract: '2026-05-run-response-package',
53
+ version: '0.1.57',
54
+ apiContract: '2026-05-play-tool-describe-starters',
55
55
  supportPolicy: {
56
- latest: '0.1.55',
56
+ latest: '0.1.57',
57
57
  minimumSupported: '0.1.53',
58
58
  deprecatedBelow: '0.1.53',
59
59
  },
@@ -125,6 +125,22 @@ export interface ToolDefinition {
125
125
  /** Copyable play-runtime guidance for V2 tool execution results. */
126
126
  usageGuidance?: {
127
127
  execute?: string;
128
+ prefer?: string[];
129
+ access?: {
130
+ extractedLists?: {
131
+ expression?: string;
132
+ meaning?: string;
133
+ };
134
+ extractedValues?: {
135
+ expression?: string;
136
+ meaning?: string;
137
+ };
138
+ rawToolResponse?: {
139
+ expression?: string;
140
+ meaning?: string;
141
+ };
142
+ invalidGetterHint?: string;
143
+ };
128
144
  toolExecutionResult?: {
129
145
  type?: 'ToolExecutionResult';
130
146
  toolResponse?: {
@@ -637,6 +653,11 @@ export interface PlayDescription {
637
653
  rowOutputSchema?: Record<string, unknown> | null;
638
654
  runCommand: string;
639
655
  examples: string[];
656
+ cloneEditStarter?: {
657
+ path: string;
658
+ command: string;
659
+ checkCommand: string;
660
+ };
640
661
  currentPublishedVersion?: number | null;
641
662
  isDraftDirty?: boolean;
642
663
  latestRunId?: string | null;
@@ -8,10 +8,12 @@ export type CsvRenameOptions = {
8
8
 
9
9
  const CSV_PROJECTED_FIELDS = Symbol.for('deepline.play.csv.projected_fields');
10
10
  const CSV_PROJECTED_FIELDS_KEY = '__deeplineCsvProjectedFields';
11
+ const CSV_PROJECTED_VALUES_KEY = '__deeplineCsvProjectedValues';
11
12
 
12
13
  type ProjectedRow = Record<string, unknown> & {
13
14
  [CSV_PROJECTED_FIELDS]?: ReadonlySet<string>;
14
15
  [CSV_PROJECTED_FIELDS_KEY]?: readonly string[];
16
+ [CSV_PROJECTED_VALUES_KEY]?: Record<string, unknown>;
15
17
  };
16
18
 
17
19
  function normalizeCsvHeader(header: string): string {
@@ -58,6 +60,7 @@ export function applyCsvRenameProjection<T extends Record<string, unknown>>(
58
60
  return rows.map((row, index) => {
59
61
  const lookup = buildRowLookup(row);
60
62
  const projectedFields = new Set<string>();
63
+ const projectedValues: Record<string, unknown> = {};
61
64
  const projected: Record<string, unknown> = { ...row };
62
65
 
63
66
  for (const [target, sourceNames] of Object.entries(aliases)) {
@@ -81,6 +84,7 @@ export function applyCsvRenameProjection<T extends Record<string, unknown>>(
81
84
  writable: true,
82
85
  });
83
86
  projectedFields.add(target);
87
+ projectedValues[target] = selected;
84
88
  } else {
85
89
  projected[target] = selected;
86
90
  }
@@ -96,6 +100,20 @@ export function applyCsvRenameProjection<T extends Record<string, unknown>>(
96
100
  enumerable: false,
97
101
  configurable: true,
98
102
  });
103
+ if (projectedFields.size > 0) {
104
+ Object.defineProperty(projected, CSV_PROJECTED_FIELDS_KEY, {
105
+ value: [...projectedFields],
106
+ enumerable: true,
107
+ configurable: true,
108
+ writable: true,
109
+ });
110
+ Object.defineProperty(projected, CSV_PROJECTED_VALUES_KEY, {
111
+ value: projectedValues,
112
+ enumerable: true,
113
+ configurable: true,
114
+ writable: true,
115
+ });
116
+ }
99
117
  return projected as T & Record<string, unknown>;
100
118
  });
101
119
  }
@@ -111,6 +129,7 @@ export function cloneCsvAliasedRow<T extends Record<string, unknown>>(
111
129
  }
112
130
 
113
131
  const clonedProjectedFields = new Set<string>();
132
+ const serializedValues = getCsvProjectedValues(row);
114
133
  for (const field of projectedFields) {
115
134
  if (Object.prototype.hasOwnProperty.call(cloned, field)) {
116
135
  continue;
@@ -124,7 +143,7 @@ export function cloneCsvAliasedRow<T extends Record<string, unknown>>(
124
143
  });
125
144
  } else {
126
145
  Object.defineProperty(cloned, field, {
127
- value: row[field],
146
+ value: serializedValues?.[field] ?? row[field],
128
147
  enumerable: false,
129
148
  configurable: true,
130
149
  writable: true,
@@ -139,6 +158,20 @@ export function cloneCsvAliasedRow<T extends Record<string, unknown>>(
139
158
  enumerable: false,
140
159
  configurable: true,
141
160
  });
161
+ Object.defineProperty(cloned, CSV_PROJECTED_FIELDS_KEY, {
162
+ value: [...clonedProjectedFields],
163
+ enumerable: true,
164
+ configurable: true,
165
+ writable: true,
166
+ });
167
+ Object.defineProperty(cloned, CSV_PROJECTED_VALUES_KEY, {
168
+ value: Object.fromEntries(
169
+ [...clonedProjectedFields].map((field) => [field, cloned[field]]),
170
+ ),
171
+ enumerable: true,
172
+ configurable: true,
173
+ writable: true,
174
+ });
142
175
  }
143
176
  return cloned;
144
177
  }
@@ -153,6 +186,7 @@ export function stripCsvProjectedFields<T extends Record<string, unknown>>(
153
186
  delete stripped[field];
154
187
  }
155
188
  delete stripped[CSV_PROJECTED_FIELDS_KEY];
189
+ delete stripped[CSV_PROJECTED_VALUES_KEY];
156
190
  return stripped as T;
157
191
  }
158
192
 
@@ -168,13 +202,31 @@ export function getCsvProjectedFields(
168
202
  return new Set(serializedFields.filter((field) => typeof field === 'string'));
169
203
  }
170
204
 
205
+ function getCsvProjectedValues(
206
+ row: Record<string, unknown>,
207
+ ): Record<string, unknown> | null {
208
+ const serializedValues = (row as ProjectedRow)[CSV_PROJECTED_VALUES_KEY];
209
+ if (
210
+ !serializedValues ||
211
+ typeof serializedValues !== 'object' ||
212
+ Array.isArray(serializedValues)
213
+ ) {
214
+ return null;
215
+ }
216
+ return serializedValues;
217
+ }
218
+
171
219
  export function stripCsvProjectionMetadata<T extends Record<string, unknown>>(
172
220
  row: T,
173
221
  ): T {
174
- if (!Object.prototype.hasOwnProperty.call(row, CSV_PROJECTED_FIELDS_KEY)) {
222
+ if (
223
+ !Object.prototype.hasOwnProperty.call(row, CSV_PROJECTED_FIELDS_KEY) &&
224
+ !Object.prototype.hasOwnProperty.call(row, CSV_PROJECTED_VALUES_KEY)
225
+ ) {
175
226
  return row;
176
227
  }
177
- const stripped = { ...row };
228
+ const stripped = cloneCsvAliasedRow(row) as T;
178
229
  delete stripped[CSV_PROJECTED_FIELDS_KEY];
230
+ delete stripped[CSV_PROJECTED_VALUES_KEY];
179
231
  return stripped as T;
180
232
  }
@@ -55,14 +55,34 @@ export type PlayDatasetInput<T> =
55
55
  | AsyncIterable<T>
56
56
  | PlayDataset<T>;
57
57
 
58
+ /**
59
+ * Durable handle for rows produced by `ctx.csv(...)` or `ctx.map(...).run()`.
60
+ *
61
+ * A `PlayDataset` is not a normal in-memory array. It points at runtime-managed
62
+ * rows, usually backed by persisted sheet storage, and carries metadata such as
63
+ * dataset kind, dataset id, table namespace, count, and preview rows.
64
+ *
65
+ * Pass dataset handles directly into later `ctx.map(...)` stages by default so
66
+ * Deepline keeps row progress, retries, memory use, and table output under
67
+ * runtime control. Use `count()` and `peek()` for bounded inspection. Use
68
+ * `materialize(limit)` or async iteration only when the dataset is intentionally
69
+ * small and bounded.
70
+ */
58
71
  export interface PlayDataset<T> extends AsyncIterable<T> {
59
72
  readonly [PLAY_DATASET_BRAND]: true;
73
+ /** Dataset kind. */
60
74
  readonly datasetKind: PlayDatasetKind;
75
+ /** Dataset id. */
61
76
  readonly datasetId: string;
77
+ /** Backing store info. */
62
78
  readonly backing?: PlayDatasetBacking;
79
+ /** Display label. */
63
80
  readonly sourceLabel?: string | null;
81
+ /** Runtime table name. */
64
82
  readonly tableNamespace?: string | null;
83
+ /** Row count. */
65
84
  count(): Promise<number>;
85
+ /** Preview rows. */
66
86
  peek(limit?: number): Promise<T[]>;
67
87
  /**
68
88
  * Explicit escape hatch for bounded result sets.
@@ -310,7 +330,11 @@ export async function materializePlayDatasetInput<T>(
310
330
  input: PlayDatasetInput<T>,
311
331
  ): Promise<T[]> {
312
332
  if (isPlayDataset(input)) {
313
- return await input.materialize();
333
+ const rows: T[] = [];
334
+ for await (const row of input) {
335
+ rows.push(row);
336
+ }
337
+ return rows;
314
338
  }
315
339
 
316
340
  if (Array.isArray(input)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deepline",
3
- "version": "0.1.55",
3
+ "version": "0.1.57",
4
4
  "description": "Deepline SDK + CLI — B2B data enrichment powered by durable cloud execution",
5
5
  "license": "MIT",
6
6
  "repository": {