Documentation Index
Fetch the complete documentation index at: https://deepline.com/docs/llms.txt
Use this file to discover all available pages before exploring further.
SDK Reference
Generated from SDK source comments by scripts/generate-play-sdk-reference.ts. Do not edit this file manually.
Generated from SDK source comments by scripts/generate-play-sdk-reference.ts. Do not edit this file manually.
This reference covers the play-authoring SDK surface: definePlay, runtime ctx.* primitives, PlayDataset, and tool result accessors. Use .sdk-skills/deepline-sdk/SKILL.md for agent workflow guidance and this page for exact signatures and return shapes.
Runtime Primitives
definePlay
Define a play — a composable TypeScript workflow for the Deepline platform.
The returned value is both:
- A callable function — invoked by the Temporal worker with a runtime context
- A named play handle — with
.run(), .versions(), .get(), .publish(), etc. for remote lifecycle management
Plays are the primary abstraction for building repeatable data pipelines.
They run on Temporal for durable execution with automatic retries and timeouts.
export function definePlay<TInput, TOutput extends PlayReturnObject>(
config: DefinePlayConfig<TInput, TOutput>,
): DefinedPlay<TInput, TOutput>;
export function definePlay<TInput, TOutput extends PlayReturnObject>(
name: string,
fn: (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>,
bindings?: PlayBindings,
): DefinedPlay<TInput, TOutput>;
Overload 1
Parameters
| Name | Type | Required | Description |
|---|
config | DefinePlayConfig<TInput, TOutput> | Yes | Object-form play config. |
Returns
DefinedPlay<TInput, TOutput>
Overload 2
Parameters
| Name | Type | Required | Description |
|---|
name | string | Yes | Play name. |
fn | (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput> | Yes | Play function. |
bindings | PlayBindings | No | Trigger bindings. |
Returns
DefinedPlay<TInput, TOutput>
DefinePlayConfig
Object-form play definition accepted by definePlay(config).
Use this form when the input contract should be explicit at definition time
through defineInput<T>(schema), or when configuration reads clearer as one
object. The shorthand definePlay(name, fn, bindings?) is equivalent for
simple file-backed plays.
export type DefinePlayConfig<TInput, TOutput extends PlayReturnObject> = {
id: string;
input: PlayInputContract<TInput>;
run: (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput>;
bindings?: PlayBindings;
billing?: PlayBindings['billing'];
};
Fields
| Name | Type | Required | Description |
|---|
id | string | Yes | Play id/name. |
input | PlayInputContract<TInput> | Yes | Input schema. |
run | (ctx: DeeplinePlayRuntimeContext, input: TInput) => Promise<TOutput> | Yes | Play function. |
bindings | PlayBindings | No | Trigger bindings. |
billing | PlayBindings['billing'] | No | Billing options. |
PlayBindings
Optional trigger bindings for a play.
Plays can be triggered by webhooks (with HMAC signature verification)
or cron schedules. Bindings are declared as the third argument to
definePlay.
export type PlayBindings = {
billing?: {
maxCreditsPerRun?: number;
};
webhook?: {
hmac?: {
algorithm?: 'sha256';
header?: string;
secretEnv: string;
};
};
cron?: {
schedule: string;
timezone?: string;
};
};
Fields
| Name | Type | Required | Description |
|---|
billing | { maxCreditsPerRun?: number; } | No | Optional per-run billing controls enforced by the runtime. |
webhook | { hmac?: { algorithm?: 'sha256'; header?: string; secretEnv: string; }; } | No | Webhook trigger with optional HMAC signature verification. |
cron | { schedule: string; timezone?: string; } | No | Cron schedule trigger. |
ctx.csv(path, options)
Load a staged CSV file as a durable dataset handle.
Use this when a play receives a CSV path from the CLI or API and row work
should continue through DeeplinePlayRuntimeContext.map. The path is
normally an input field such as input.csv, populated by
deepline plays run my.play.ts --csv rows.csv.
Each CSV row becomes an object keyed by canonical column names. Use
options.columns / options.rename to map user headers such as
"Company Domain" to stable code fields such as domain.
csv<T = Record<string, unknown>>(
path: string,
options?: CsvOptions,
): Promise<PlayDataset<T>>;
Parameters
| Name | Type | Required | Description |
|---|
path | string | Yes | Staged CSV path. |
options | CsvOptions | No | CSV load options. |
Returns
Promise<PlayDataset<T>>
CsvOptions
Options for loading a staged CSV with ctx.csv(...).
export type CsvOptions = {
description?: string;
columns?: CsvRenameMap;
rename?: CsvRenameMap;
required?: readonly string[];
};
Fields
| Name | Type | Required | Description |
|---|
description | string | No | Human-readable description for runtime logs and inspection. |
columns | CsvRenameMap | No | Canonical field-to-header aliases, e.g. { domain: ['domain', 'Company Domain'] }. |
rename | CsvRenameMap | No | Header rename map; use columns for new code. |
required | readonly string[] | No | Canonical fields that must be present after header normalization. |
ctx.map(key, items)
Create a persisted row dataset/table from input rows.
ctx.map is Deepline’s row-work primitive. It records row identity,
progress, retries, table output, and idempotency for a collection of rows.
Use .step(name, resolver) on the returned builder to define output
columns, then .run(...) to execute the row program.
The key identifies the logical dataset/table. Renaming it is a persistence
migration: existing rows may no longer be reused. Row identity is derived
automatically from input row content unless .run({ key: ... }) overrides
it with stable business fields such as domain, email, or linkedin_url.
By default, ctx.map is row-preserving: one input row produces one output
row, with original fields merged with the columns produced by
.step(...). If one input entity must become many output rows, use the
documented expand/flatten recipe instead of assuming ctx.map changes
row cardinality.
map<TItem extends object>(
key: string,
items: PlayDatasetInput<TItem>,
): MapStepBuilder<TItem, TItem>;
Parameters
| Name | Type | Required | Description |
|---|
key | string | Yes | Dataset/table name. |
items | PlayDatasetInput<TItem> | Yes | Input rows. |
Returns
MapStepBuilder<TItem, TItem>
.map(...).step(name, resolver).run(options)
Define one output column for every row in this map dataset.
The name becomes a field on each output row. For example,
.step('contact', ...) creates row.contact in later map stages; it does
not spread returned object fields such as contact.email into row.email.
Add a later column resolver when you want a top-level export field:
.step('email', row => row.contact?.email ?? null).
step<Name extends string, Value>(
name: Name,
resolver: MapStepResolver<OutputRow, Value>,
): MapStepBuilder<InputRow, OutputRow & Record<Name, Value>>;
run(options?: {
description?: string;
staleAfterSeconds?: number;
key?:
| (keyof InputRow & string)
| readonly (keyof InputRow & string)[]
| ((
row: InputRow,
index: number,
) => string | number | readonly unknown[]);
}): Promise<PlayDataset<OutputRow>>;
Step Parameters
| Name | Type | Required | Description |
|---|
name | Name | Yes | Output column name. |
resolver | MapStepResolver<OutputRow, Value> | Yes | Computes the value for one row. |
Step Returns
MapStepBuilder<InputRow, OutputRow & Record<Name, Value>>
Run Parameters
| Name | Type | Required | Description |
|---|
options | { description?: string; staleAfterSeconds?: number; key?: | (keyof InputRow & string) | readonly (keyof InputRow & string)[] | (( row: InputRow, index: number, ) => string | number | readonly unknown[]); } | No | Run options. |
Run Returns
Promise<PlayDataset<OutputRow>>
Execute the row-column program and return a durable dataset handle.
The returned PlayDataset preserves one output row per input row,
with original fields merged with the columns produced by .step(...).
ctx.step(id, fn)
Create one scalar checkpoint for the whole play run.
Use ctx.step when a value is nondeterministic, expensive, external, or
useful to inspect as a named boundary. The first execution stores the
JSON-serializable output under id; replay and retries return the stored
value instead of running run again.
Plain deterministic assignment does not need ctx.step. Use
ctx.map(...).step(...), not ctx.step, when the value should become a
field on each exported row.
step<T>(
id: string,
run: () => T | Promise<T>,
options?: { staleAfterSeconds?: number },
): Promise<T>;
Parameters
| Name | Type | Required | Description |
|---|
id | string | Yes | Checkpoint id. |
run | () => T | Promise<T> | Yes | Computes the value once. |
options | { staleAfterSeconds?: number } | No | Checkpoint options. |
Returns
Promise<T>
No source JSDoc yet.
runPlay<TOutput = unknown>(
key: string,
playRef: string | PlayReferenceLike,
input: Record<string, unknown>,
options: { description?: string; staleAfterSeconds?: number },
): Promise<TOutput>;
Parameters
| Name | Type | Required | Description |
|---|
key | string | Yes | |
playRef | string | PlayReferenceLike | Yes | |
input | Record<string, unknown> | Yes | |
options | { description?: string; staleAfterSeconds?: number } | Yes | |
Returns
Promise<TOutput>
Execute a single tool with a keyword-style request object.
execute<TOutput = LoosePlayObject>(
request: ToolExecutionRequest & { staleAfterSeconds?: number },
): Promise<ToolExecuteResult<TOutput>>;
Parameters
| Name | Type | Required | Description |
|---|
request | ToolExecutionRequest & { staleAfterSeconds?: number } | Yes | Tool call request. |
Returns
Promise<ToolExecuteResult<TOutput>>
Keyword-style request object for ctx.tools.execute(...).
The tool value comes from live tool discovery. The id is the stable
logical call name inside this play and participates in replay/idempotency.
export type ToolExecutionRequest = {
id: string;
tool: string;
input: Record<string, unknown>;
description?: string;
staleAfterSeconds?: number;
};
Fields
| Name | Type | Required | Description |
|---|
id | string | Yes | Stable logical id for this tool call within the play. |
tool | string | Yes | Current tool id from deepline tools search / deepline tools describe. |
input | Record<string, unknown> | Yes | JSON-serializable provider/tool input object. |
description | string | No | Human-readable description for logs and run inspection. |
staleAfterSeconds | number | No | |
ctx.fetch(key, url, init)
Durable HTTP fetch.
Use this for non-provider HTTP calls that must replay safely. The response
is recorded under key so workflow replay sees the same value. Prefer
ctx.tools.execute(...) for Deepline-managed provider APIs because tools
handle auth, retries, rate limits, extraction metadata, and spend tracking.
fetch(
key: string,
url: string | URL,
init?: RequestInit,
options?: { staleAfterSeconds?: number },
): Promise<{
ok: boolean;
status: number;
statusText: string;
url: string;
headers: Record<string, string>;
bodyText: string;
json: unknown | null;
}>;
Parameters
| Name | Type | Required | Description |
|---|
key | string | Yes | Checkpoint id. |
url | string | URL | Yes | URL to fetch. |
init | RequestInit | No | Fetch options. |
options | { staleAfterSeconds?: number } | No | |
Returns
Promise<{ ok: boolean; status: number; statusText: string; url: string; headers: Record<string, string>; bodyText: string; json: unknown | null; }>
Run a reusable step program against one scalar input object.
steps().step(...) is a composable mini-pipeline. Use ctx.runSteps(...)
when that mini-pipeline should execute outside a row dataset. Inside a
ctx.map column resolver, pass the step program directly to
.step(name, program) instead.
runSteps<TInput extends Record<string, unknown>, TOutput>(
program: StepProgram<TInput, unknown, TOutput>,
input: TInput,
options?: { description?: string },
): Promise<TOutput>;
Parameters
| Name | Type | Required | Description |
|---|
program | StepProgram<TInput, unknown, TOutput> | Yes | Step program. |
input | TInput | Yes | Program input. |
options | { description?: string } | No | Run options. |
Returns
Promise<TOutput>
PlayDataset
Durable handle for rows produced by ctx.csv(...) or ctx.map(...).run().
A PlayDataset is not a normal in-memory array. It points at runtime-managed
rows, usually backed by persisted sheet storage, and carries metadata such as
dataset kind, dataset id, table namespace, count, and preview rows.
Pass dataset handles directly into later ctx.map(...) stages by default so
Deepline keeps row progress, retries, memory use, and table output under
runtime control. Use count() and peek() for bounded inspection. Use
materialize(limit) or async iteration only when the dataset is intentionally
small and bounded.
export interface PlayDataset<T> extends AsyncIterable<T> {
readonly datasetKind: PlayDatasetKind;
readonly datasetId: string;
readonly backing?: PlayDatasetBacking;
readonly sourceLabel?: string | null;
readonly tableNamespace?: string | null;
count(): Promise<number>;
peek(limit?: number): Promise<T[]>;
map<U>(
mapper: (row: T, index: number) => U | Promise<U>,
options?: PlayDatasetTransformOptions,
): PlayDataset<U>;
filter(
predicate: (row: T, index: number) => boolean | Promise<boolean>,
options?: PlayDatasetTransformOptions,
): PlayDataset<T>;
slice(
start?: number,
end?: number,
options?: PlayDatasetTransformOptions,
): PlayDataset<T>;
take(limit: number, options?: PlayDatasetTransformOptions): PlayDataset<T>;
materialize(limit?: number): Promise<T[]>;
toJSON(): {
kind: 'dataset';
datasetKind: PlayDatasetKind;
datasetId: string;
count: number;
backing?: PlayDatasetBacking;
sourceLabel?: string | null;
tableNamespace?: string | null;
columns?: string[];
_metadata?: {
workProgress?: PlayDatasetWorkProgressSummary;
};
preview: T[];
};
}
Fields
| Name | Type | Required | Description |
|---|
datasetKind | PlayDatasetKind | Yes | Dataset kind. |
datasetId | string | Yes | Dataset id. |
backing | PlayDatasetBacking | No | Backing store info. |
sourceLabel | string | null | No | Display label. |
tableNamespace | string | null | No | Runtime table name. |
Canonical result returned by Deepline tool execution.
The top-level object is Deepline-owned execution metadata and semantic
extraction state. Raw tool/provider data lives under toolResponse.raw;
response metadata lives under toolResponse.meta. Semantic single-value
getters live under extractedValues.<name>.get(), and list getters live
under extractedLists.<name>.get().
Use extractors first when a tool contract exposes them. Drop to
toolResponse.raw when you need provider-specific fields or when debugging
from persisted run rows.
export type ToolExecuteResult<
TResult = unknown,
TMeta = Record<string, unknown>,
TExtracted extends Record<string, unknown> = Record<string, unknown>,
TLists extends Record<string, Record<string, unknown>> = Record<
string,
Record<string, unknown>
>,
> = ToolExecuteResultBase<TResult, TMeta> &
ToolExecuteResultAccessors<TExtracted, TLists>;