import type { PlayCompilerManifest } from '../../shared_libs/plays/compiler-manifest'; import type { PlayRuntimeSelection } from '../../shared_libs/play-runtime/runtime-environment'; import type { PlayActivityObservation, PlayActivityState, PlayActivityTarget, PlayRunActivityProjection, } from '../../shared_libs/play-runtime/activity-observation'; export type { PlayActivityObservation, PlayActivityState, PlayActivityTarget, PlayRunActivityProjection, }; import type { DeeplineToolCategory, PlayBootstrapFinderKind, PlayBootstrapEntityKind, PlayBootstrapStageKind, PlayBootstrapTemplate, } from '../../shared_libs/plays/bootstrap-routes'; // —————————————————————————————————————————————————————————— // Config // —————————————————————————————————————————————————————————— /** * Options for constructing a {@link DeeplineClient} or connecting via {@link Deepline.connect}. * * All fields are optional — the SDK resolves missing values from environment * variables and CLI-managed config files. See {@link resolveConfig} for the * full resolution order. * * @example * ```typescript * import { DeeplineClient } from 'deepline'; * * // Minimal — uses env vars / CLI config automatically: * const client = new DeeplineClient(); * * // Explicit overrides: * const client2 = new DeeplineClient({ * apiKey: 'dl_test_...', * baseUrl: 'http://localhost:3000', * timeout: 30_000, * maxRetries: 5, * }); * ``` */ export interface DeeplineClientOptions { /** API key. Overrides `DEEPLINE_API_KEY` env var and CLI-stored keys. */ apiKey?: string; /** Base URL of the Deepline API. Overrides `DEEPLINE_HOST_URL`. */ baseUrl?: string; /** Per-request timeout in milliseconds. Default: `60_000` (60 seconds). */ timeout?: number; /** Maximum retry attempts for transient failures (network errors, 429s). Default: `3`. */ maxRetries?: number; } /** * Fully resolved configuration used internally by the SDK. * * Produced by {@link resolveConfig} — all fields are guaranteed non-empty. */ export interface ResolvedConfig { /** Validated API key (non-empty string). */ apiKey: string; /** Normalized base URL (trailing slash stripped). */ baseUrl: string; /** Request timeout in milliseconds. */ timeout: number; /** Max retry count for transient failures. */ maxRetries: number; } /** Column metadata returned by a customer data query. */ export interface CustomerDbColumn { /** Column name as returned by the database. */ name: string; /** Internal table identifier when available. */ table_id: number | null; /** Internal data-type identifier when available. */ data_type_id: number | null; } /** * Result returned by {@link DeeplineClient.db.query}. * * Rows are intentionally untyped because the schema depends on the caller's SQL * query and selected customer tables. */ export interface CustomerDbQueryResult { /** This query reads the current mutable customer database, not one run snapshot. */ scope?: { kind: 'database'; mutability: 'current' }; /** Database command executed by the query endpoint. */ command: string; /** Total affected row count when reported by the database. */ row_count: number | null; /** Number of rows included in this response. */ row_count_returned: number; /** Whether server-side row limits truncated the result. */ truncated: boolean; /** Column metadata for the returned rows. */ columns: CustomerDbColumn[]; /** Result rows. */ rows: unknown[]; } export interface ToolPricingSummary { /** User-facing pricing text for quick discovery displays. */ displayText: string | null; /** User-facing unit the price applies to. */ unit: 'call' | 'result' | 'page' | 'usage' | null; /** Deepline credits charged per unit, when statically knowable. */ creditsPerUnit: number | null; /** USD equivalent charged per unit, when statically knowable. */ usdPerUnit: number | null; /** Currency for `usdPerUnit`. */ currency: 'USD'; /** Short user-facing pricing summary for variable pricing. */ summary: string | null; /** Additional user-facing pricing notes. */ details: string[]; } /** A discoverable provider, returned by {@link DeeplineClient.listProviders}. */ export interface ProviderDefinition { provider: string; displayName: string; toolCount: number; categories: string[]; /** Present for providers in the recent-additions ledger. */ version?: string; /** ISO-8601 date on which this provider was added. */ releasedAt?: string; } /** * Summary definition of a tool, returned by {@link DeeplineClient.listTools}. * * Contains everything needed to discover, describe, and call a tool. * * @example * ```typescript * const tools = await client.listTools(); * for (const tool of tools) { * console.log(`${tool.toolId} (${tool.provider}): ${tool.description}`); * } * ``` */ export type { DeeplineToolCategory, PlayBootstrapFinderKind, PlayBootstrapEntityKind, PlayBootstrapStageKind, PlayBootstrapTemplate, }; /** * Summary definition of a callable provider-backed tool. * * Returned by {@link DeeplineClient.listTools} and ranked tool search. Use * `getTool(toolId)` or the matching HTTP describe route for provider-specific * schema, examples, pricing, and extraction guidance before executing. */ export interface ToolDefinition { /** Unique tool identifier used in API calls (e.g. `"dropleads_search_people"`). */ toolId: string; /** Provider that backs this tool (e.g. `"hunter"`, `"dropleads"`, `"test"`). */ provider: string; /** Human-readable name for display. */ displayName: string; /** What this tool does — suitable for LLM tool descriptions. */ description: string; /** Categorization tags (e.g. `["people", "enrichment"]`). */ categories: DeeplineToolCategory[]; /** Searchable provider and account-signal tags. */ tags?: string[]; /** Operation slug within the provider. */ operation?: string; /** Normalized operation identifier. */ operationId?: string; /** Alternative names that resolve to this tool. */ operationAliases?: string[]; /** Explicit globally runnable play reference for play-backed catalog entries. */ playReference?: `prebuilt/${string}`; /** Whether detailed input schema is available from `tools describe`. */ hasInputSchema?: boolean; /** Whether detailed output schema is available from `tools describe`. */ hasOutputSchema?: boolean; /** JSON Schema describing the tool's input parameters. */ inputSchema?: Record; /** JSON Schema describing the tool's output shape. */ outputSchema?: Record; /** User-facing pricing summary. Internal provider/settlement costs are intentionally omitted. */ pricing?: ToolPricingSummary | null; /** Copyable play-runtime guidance for V2 tool execution results. */ usageGuidance?: { execute?: string; prefer?: string[]; access?: { extractedLists?: { expression?: string; meaning?: string; }; extractedValues?: { expression?: string; meaning?: string; }; rawToolResponse?: { expression?: string; meaning?: string; }; canonicalToolResponse?: { expression?: string; meaning?: string; }; invalidGetterHint?: string; }; toolExecutionResult?: { type?: 'ToolExecutionResult'; toolResponse?: { raw?: string; rawV2?: string; view?: string; responseMeta?: string; meta?: string; }; meta?: string; extractedLists?: | Array<{ name: string; expression: string; details?: { strategy?: string; rawToolOutputPaths?: string[]; candidatePaths?: string[]; }; }> | Record< string, { expression: string; details?: { strategy?: string; rawToolOutputPaths?: string[]; candidatePaths?: string[]; }; } >; extractedValues?: | Array<{ name: string; expression: string; details?: { strategy?: string; rawToolOutputPaths?: string[]; candidatePaths?: string[]; }; }> | Record< string, { expression: string; details?: { strategy?: string; rawToolOutputPaths?: string[]; candidatePaths?: string[]; }; } >; [key: string]: unknown; }; }; /** Search relevance score returned by ranked tool search. */ search_score?: number; /** Search match snippets returned by ranked tool search. */ search_matches?: Array<{ field: string; value: string; term?: string; }>; /** * Whether this tool is callable in the current workspace. `false` for a * bring-your-own-credential provider that has not been connected. */ connected?: boolean; /** Whether the tool can be executed. Exact lookup may return non-callable deprecated aliases. */ callable?: boolean; /** True when callers should migrate this exact tool id to its replacement. */ deprecated?: boolean; /** Deprecation reason, replacement, and compatibility execution behavior. */ deprecation?: { replacementToolId: string; message: string; execution?: 'terminal' | 'forward'; }; /** * Connection status for discovery: `managed` (Deepline-run credentials), * `connected` (your own credential is connected), or `requires_connection` * (BYO provider not yet connected in this workspace). `deprecated` means * connecting credentials will not make the tool callable. */ credentialStatus?: | 'managed' | 'connected' | 'requires_connection' | 'deprecated'; /** True when the tool requires a customer-provided credential to run. */ requiresOwnCredential?: boolean; /** Actionable message shown when a connection is required. */ connectionMessage?: string; } export interface ModelProviderOptionField { name: string; type: 'string' | 'number' | 'boolean' | 'object' | 'array'; enumValues?: string[]; description: string; caveat?: string; } export interface ModelProviderOptionNamespace { provider: string; sourcePackage: string; sourceSymbol: string; fields: ModelProviderOptionField[]; } export interface DeeplineAgentModelDescription { schemaVersion: 1; model: string; provider: string; modelMetadata: Record | null; providerOptions: { gateway: ModelProviderOptionNamespace; selectedProvider?: ModelProviderOptionNamespace; }; exampleInput: { model: string; providerOptions: Record; }; caveats: string[]; sources: string[]; inferencePricing: InferenceDynamicPricingCapability; } export interface InferenceDynamicPricingCapability { settlement: 'actual_usage'; staticUnitPrice: null; quoteEndpointTemplate: string; supportedQualities: Array<'bounded_max' | 'estimate_only' | 'unavailable'>; payloadFields: string[]; } export type InferenceQuoteAssumptions = { modelCallCount: number; planningModelCallCount: number; estimatedInputTokens: number; estimatedOutputTokens: number; maxOutputTokens: number | null; candidateRouteCount: number; pricedRouteCount: number; inputBound: 'proven_request_tokens' | 'catalog_context' | 'not_proven'; inputBoundProofId?: string; }; export type InferenceQuote = { quality: 'bounded_max' | 'estimate_only' | 'unavailable'; estimate: | { quality: 'estimate_only'; credits: number; assumptions: InferenceQuoteAssumptions; } | { quality: 'unavailable'; assumptions: InferenceQuoteAssumptions }; authorization: | { quality: 'bounded_max'; maximumCredits: number; assumptions: InferenceQuoteAssumptions; } | { quality: 'estimate_only' | 'unavailable'; assumptions: InferenceQuoteAssumptions; }; settlement: 'actual_usage'; }; /** * Query options for ranked tool/provider discovery. */ export interface ToolSearchOptions { /** Free-text search query. */ query?: string; /** Comma-separated category filter such as `company_search` or `email_finder`. */ categories?: string; /** Optional explicit search terms used by agent/CLI callers. */ searchTerms?: string; /** Search algorithm/version. Defaults to the current ranked mode. */ searchMode?: 'v1' | 'v2'; /** Include backend debug metadata in the search response. */ includeSearchDebug?: boolean; } /** * Ranked tool/provider discovery response. * * Includes matching tools plus render/action hints used by the CLI and agents. */ export interface ToolSearchResult { /** Ranked matching tools. */ tools: ToolDefinition[]; /** Count included in this response when available. */ count?: number; /** Total available count when the backend reports it. */ total?: number; /** Whether results were truncated by server-side limits. */ truncated?: boolean; /** Echoed query. */ query?: string; /** Parsed category filters. */ categories?: string[]; /** Parsed search terms. */ search_terms?: string[]; /** Search mode used. */ search_mode?: 'v1' | 'v2'; /** Whether search fell back to category matching. */ search_fallback_to_category?: boolean; /** Explanation and next commands when filters/search succeed but match zero tools. */ emptyResult?: { reason: string; message: string; suggestions: Array<{ label: string; command: string; }>; }; /** Hint explaining omitted play results when searching tools only. */ omitted_plays_hint?: string; /** Copyable CLI command templates for follow-up discovery/execution. */ commandTemplates?: { describe?: string; execute?: string; }; /** Pre-rendered sections and actions for CLI/agent display. */ render?: { sections?: Array<{ title: string; lines: string[]; }>; actions?: Array<{ label: string; command: string; }>; }; } /** * Extended tool metadata including pricing, samples, and failure modes. * * Returned by {@link DeeplineClient.getTool}. Extends {@link ToolDefinition} * with operational details needed for cost estimation and debugging. * * @example * ```typescript * const meta = await client.getTool('dropleads_search_people'); * console.log(meta.displayName); // "DropLeads People Search" * console.log(meta.estimatedCreditsRange); // "1-5" * console.log(meta.samples); // { input: {...}, output: {...} } * ``` */ export interface ToolMetadata extends ToolDefinition { /** Related async polling action, if this tool supports async execution. */ asyncGetAction?: string | null; /** Async job lifecycle: this tool starts it, then polling may lead to final rows. */ asyncFlow?: { startAction: string; pollActions: string[]; finishAction?: string | null; } | null; /** Known failure scenarios and their expected handling. */ failureMode?: Record | null; /** Sanitized pricing model for describe metadata. Provider internal prices are intentionally omitted. */ cost?: Record | null; /** Deepline credits charged for one user-visible pricing unit. */ deeplineCreditsPerPricingUnit?: number | null; /** Whether the customer pays with Deepline credits or their own connected account. */ billingSource?: string; /** Display label for the billing source. */ billingSourceLabel?: string; /** Play expansion config if this tool auto-expands in plays. */ playExpansion?: Record; /** Estimated credit range for a single call (e.g. `"1-5"`). */ estimatedCreditsRange?: string; /** Version of the cost estimation model used. */ estimateModelVersion?: string; /** Tools whose costs were used to build this estimate. */ estimateBasedOnTools?: string[]; /** Individual step cost contributions (for composite tools). */ stepContributions?: unknown[]; /** Example input/output pairs for documentation and testing. */ samples?: Record; } // —————————————————————————————————————————————————————————— // Play results // —————————————————————————————————————————————————————————— /** * Final result of a play execution, returned by {@link DeeplineClient.runPlay}. * * @example * ```typescript * const result = await client.runPlay(code, null, 'my-play'); * if (result.success) { * console.log('Run package:', result.result); * console.log(`Completed in ${result.durationMs}ms`); * } else { * console.error('Failed:', result.error); * console.log('Logs:', result.logs.join('\n')); * } * ``` */ export interface PlayRunResult { /** `true` if the play completed successfully (`status === 'completed'`). */ success: boolean; /** Public play-run identifier. */ runId: string; /** Canonical run package for current play runs; legacy clients may receive a raw result. */ result?: unknown; /** Canonical compact run package when returned by the server. */ package?: PlayRunPackage; /** All log lines emitted via `ctx.log()` during execution. */ logs: string[]; /** Wall-clock duration from submission to completion, in milliseconds. */ durationMs: number; /** Error message if the play failed, was cancelled, or timed out. */ error?: string; } /** * Progress snapshot from a running play, nested inside {@link PlayStatus}. */ export interface PlayProgressStatus { /** Human-readable description of the current step. */ status: string; /** Total row count for row-based processing (e.g. CSV enrichment). */ totalRows?: number; /** Accumulated log lines from `ctx.log()`. Grows monotonically. */ logs: string[]; /** Error message if the play has failed. */ error?: string; } export type PlayRunActionPackage = | { kind: 'deepline_run_inspect'; runId: string; command?: string; api: { method: 'GET'; path: string }; } | { kind: 'deepline_run_full'; runId: string; command?: string; api: { method: 'GET'; path: string }; } | { kind: 'deepline_run_billing'; runId: string; command?: string; api: { method: 'GET'; path: string }; } | { kind: 'deepline_db_query'; datasetPath: string; tableNamespace?: string; sqlTableName?: string; sqlQualifiedTableName?: string; sql: string; maxRows: number; command?: string; scope?: | { kind: 'database'; mutability: 'current' } | { kind: 'run'; runId: string }; note?: string; deprecated?: { replacement: 'queryCurrentTable'; removeAfter: string; reason: string; }; api: { method: 'POST'; path: '/api/v2/db/query'; }; } | { kind: 'deepline_run_export'; runId: string; datasetPath: string; format: 'csv'; command?: string; scope?: { kind: 'run'; runId: string }; note?: string; deprecated?: { replacement: 'datasets[].actions.exportCsv'; removeAfter: string; reason: string; }; } | { kind: 'deepline_run_logs'; runId: string; view: 'failed' | 'tail'; limit: number; command: string; api: { method: 'GET'; path: string }; }; type PlayRunDbQueryAction = Extract< PlayRunActionPackage, { kind: 'deepline_db_query' } >; type PlayRunExportAction = Extract< PlayRunActionPackage, { kind: 'deepline_run_export' } >; export type PlayRunDatasetActions = { /** @deprecated Use queryCurrentTable or exportCsv. Removed after 2026-08-18. */ query?: PlayRunDbQueryAction & { scope?: { kind: 'run'; runId: string } }; queryCurrentTable?: PlayRunDbQueryAction & { scope?: { kind: 'database'; mutability: 'current' }; }; exportCsv?: PlayRunExportAction & { scope?: { kind: 'run'; runId: string }; }; }; /** * Compact canonical package for an inspected play run. * * This object is designed for SDK/CLI/API consumers that need stable run * metadata, output handles, and follow-up actions without reading dashboard * internals. */ export interface PlayRunPackage { /** Package schema version. */ schemaVersion: 1; /** Package discriminator. */ kind: 'play_run'; /** Run identity, status, timing, and dashboard metadata. */ run: { id: string; playName: string; status: string; dashboardUrl?: string; updatedAt?: number | null; startedAt?: number | null; finishedAt?: number | null; durationMs?: number | null; error?: string; /** Canonical explanation of what this run is doing or waiting on. */ activity?: PlayRunActivityProjection | null; }; /** Bounded customer-safe warnings about output projection or availability. */ warnings?: string[]; /** Step-level summaries emitted by the runtime. */ steps: Array>; /** Named output summaries, including dataset handles and scalar outputs. */ outputs: Record>; /** Every durable Dataset Handle explicitly registered by this run. */ datasets?: Array<{ kind: 'dataset'; datasetId?: string; path: string; tableNamespace?: string; rowCount?: number; sqlTableName?: string; sqlQualifiedTableName?: string; recovered?: true; exportUnavailable?: { reason: 'empty_dataset' | 'shared_table_namespace'; message: string; }; preview?: Record; actions?: PlayRunDatasetActions; }>; /** Small retained tail of customer and runtime logs; fetch the full stream through `runs.logs`. */ logs?: { tail: string[]; totalCount: number; returnedCount: number; truncated?: boolean; }; /** Follow-up actions a caller can perform against the run. */ next?: { inspect?: PlayRunActionPackage; full?: PlayRunActionPackage; billing?: PlayRunActionPackage; export?: PlayRunActionPackage; query?: PlayRunActionPackage; logs?: PlayRunActionPackage; }; } /** * Current status of a play execution, returned by {@link DeeplineClient.getPlayStatus}. * * Poll this until `status` reaches a terminal state: * `'completed'` | `'failed'` | `'cancelled'`. * * @example * ```typescript * const status = await client.getPlayStatus(runId); * if (status.status === 'completed') { * console.log('Done:', status.result); * } else if (status.status === 'running' || status.status === 'waiting') { * console.log('Logs so far:', status.progress?.logs); * } * ``` */ export interface PlayStatus { /** Public play-run identifier. */ runId: string; /** Public Deepline play-run API version. */ apiVersion?: number; /** Saved play name for this run, when available. */ name?: string; /** Exact saved revision launched for this run, when applicable. */ revisionId?: string; /** Alias for `name` used by run/result APIs. */ playName?: string; /** Dashboard URL for inspecting the play and its run output in the app. */ dashboardUrl?: string; /** Product-level play-run state. */ status: | 'queued' | 'running' | 'waiting' | 'completed' | 'failed' | 'cancelled'; /** Execution progress with logs and error details. */ progress?: PlayProgressStatus; /** Partial or final result. Available once the play returns. */ result?: unknown; /** Compact typed run package returned by current run status endpoints. */ package?: PlayRunPackage; /** Compact typed output summaries, mirrored from the run package when present. */ outputs?: PlayRunPackage['outputs']; /** Scheduler-backed run metadata when returned by the status endpoint. */ run?: { id?: string; startTime?: string | null; closeTime?: string | null; [key: string]: unknown; } | null; /** Server-rendered result view metadata for CLI/UI summaries. */ resultView?: unknown; /** Canonical run contract snapshot metadata, when available. */ contract?: Record | null; /** If the run is blocked on a durable boundary, expose the public wait state. */ wait?: { kind: 'integration_event' | 'sleep'; boundaryId?: string; eventKey?: string; until?: number; } | null; /** Structured follow-up actions for inspect/query/export. */ next?: PlayRunPackage['next'] | Record; /** Bounded terminal-failure log window requested by `runs.get`. */ failedLogs?: { runId: string; totalCount: number; returnedCount: number; firstSequence: number | null; lastSequence: number | null; truncated: boolean; hasMore: boolean; entries: string[]; view?: 'failed'; association?: 'terminal_failure_window' | 'retained_before_truncation'; warning?: string; next?: { logs: string }; logsTruncated?: boolean; }; /** Exact ordinary `plays run` command that can rerun a failed execution. */ rerunCommand?: string; /** * Projected settled-charge billing for the run. Returned by `runs.get`. * `totalCredits`/`providerEvents` describe THIS run only; `rollup` (present * with `--full`) carries the true subtree cost including ctx.runPlay children. * Deepline credits only — provider spend is never exposed. */ billing?: RunBillingSummary; /** * True subtree cost in Deepline credits (this run + every descendant run), * mirrored to the top level for convenience. Present only with `--full`. */ billingTotalCreditsRollup?: number; /** Deepline credits attributable to descendant runs only. Present with `--full`. */ billingChildCredits?: number; /** True when the child-run billing rollup could not be fully resolved. */ billingRollupIncomplete?: boolean; /** Durable summaries of ctx.runPlay children, returned by `runs.get --full`. */ childRuns?: ChildRunSummary[]; } /** One ctx.runPlay child run exposed on the parent's `--full` payload. */ export interface ChildRunSummary { runId: string; playName?: string | null; status: string; parentRunId?: string | null; rootRunId?: string | null; createdAt?: number | null; startedAt?: number | null; finishedAt?: number | null; } /** * Rolled-up billing for a run subtree, projected from settled Charge Lifecycle * facts. Deepline credits only — never provider spend. */ export interface RunBillingSummary { runId: string; /** THIS run's own charges (parent-only; excludes descendant runs). */ totalCalls: number; totalCredits: number; providerEvents: number; computeEvents: number; /** Subtree rollup including descendant ctx.runPlay runs. Present with `--full`. */ rollup?: { totalCreditsRollup: number; childCredits: number; ownCredits: number; totalCallsRollup: number; providerEventsRollup: number; computeEventsRollup: number; childProviderEvents: number; childComputeEvents: number; descendantRunCount: number; rollupComplete: boolean; rollupError?: string; }; [key: string]: unknown; } export type LiveEventScope = 'play' | 'agent'; export interface LiveEventEnvelope { cursor: string; streamId: string; scope: LiveEventScope; type: string; at: string; payload: TPayload; } export type PlayLiveEvent = LiveEventEnvelope & { scope: 'play'; }; /** * Result returned by {@link DeeplineClient.stopPlay}. */ export interface StopPlayRunResult { /** Public play-run identifier the stop request targeted. */ runId: string; /** Whether the server confirmed the run was stopped. */ stopped: boolean; /** Number of open HITL interactions marked cancelled. */ hitlCancelledCount: number; /** * True when the scheduler state for the run was stale and the stop could * not be confirmed. Absent on older servers (treated as confirmed). */ staleSchedulerState?: boolean; /** Server-side error detail when the stop was not confirmed. */ error?: string; } export interface StopAllPlayRunsResult { stopped: number; failed: number; skipped: number; partial?: boolean; runs: Array; } /** * Summary of a single play run, returned by {@link DeeplineClient.listPlayRuns}. */ export interface PlayRunListItem { /** Public Deepline play-run id. */ workflowId: string; /** Saved play name for this run, when available. */ playName?: string | null; /** Backend run attempt id, when exposed. */ runId: string; /** Parent play-run id when this run was launched through ctx.runPlay. */ parentRunId?: string | null; /** Root play-run id for nested ctx.runPlay descendants. */ rootRunId?: string | null; /** Workflow type (typically `'Workflow'`). */ type: string; /** Human-readable status (e.g. `'Completed'`, `'Failed'`). */ status: string; /** ISO 8601 timestamp when the run started. */ startTime?: string | null; /** Unix epoch milliseconds when the run started, returned by normalized V2 run summaries. */ startedAt?: number | string | null; /** ISO 8601 timestamp when the run finished. */ closeTime?: string | null; /** Unix epoch milliseconds when the run finished, returned by normalized V2 run summaries. */ finishedAt?: number | string | null; /** Duration string (e.g. `'2.5s'`). */ executionTime: string | null; /** Total Deepline credits charged for the run, when available. */ billingTotalCredits?: number; /** Configured per-run Deepline credit cap, when available. */ billingMaxCreditsPerRun?: number | null; /** Metadata attached to the workflow. */ memo: { /** Organization that owns this run. */ orgId: string; /** Play name. */ playName: string; /** User who triggered the run, if known. */ userId: string | null; }; } /** * A single revision (version) of a play's code and configuration. */ export interface PlayRevisionSummary { /** Convex revision document ID used for exact-version runs and live promotion. */ _id?: string; /** Monotonically increasing version number. */ version: number; /** R2 storage reference for the bundled code artifact. */ artifactStorageKey?: string | null; /** Immutable artifact hash for the revision. */ artifactHash?: string | null; /** Static dependency graph hash for the revision. */ graphHash?: string | null; /** Hash of the original source file. */ sourceHash?: string | null; /** Original TypeScript source code. */ sourceCode?: string | null; /** Primary key column for CSV-based plays. */ tableNamespace?: string | null; /** Static pipeline definition (for declarative plays). */ staticPipeline?: unknown; /** Extracted binding metadata. */ bindings?: unknown; /** Human-readable description of this revision. */ description?: string | null; /** Unix timestamp (ms) when this revision was created. */ createdAt?: number; /** Unix timestamp (ms) of last update. */ updatedAt?: number; /** True when this is the revision currently serving live triggers. */ isLive?: boolean; /** True when this is the newest saved working revision. */ isWorking?: boolean; } /** * Aggregate row-processing stats for a play's sheet. */ export interface PlaySheetStats { total: number; queued: number; running: number; completed: number; failed: number; stale: number; } /** * Per-column processing stats within a play's sheet. */ export interface PlaySheetColumnStats { queued: number; running: number; completed: number; failed: number; cached: number; missed: number; skipped: number; } /** * Summary of a play's data sheet state. */ export interface PlaySheetSummary { /** Aggregate stats across all rows. */ stats: PlaySheetStats; /** Per-column breakdown of processing state. */ columns: Record; } /** * Full play definition with revision history and run stats. * * Returned by {@link DeeplineClient.getPlay}. */ export interface PlayDefinitionDetail { /** Convex document ID. */ _id: string; /** Stable registry key. */ playKey?: string; /** Canonical owner-qualified play reference. */ reference?: string; /** Play name (unique within an org). */ name: string; /** Human-friendly display name for UI surfaces. */ displayName?: string; /** Whether this Play sorts before unpinned Plays. */ pinned?: boolean; /** Canonical categories declared by tools used in this Play. */ toolCategories?: string[]; /** Whether this entry comes from the Deepline prebuilt registry or the org-owned catalog. */ origin?: 'prebuilt' | 'owned'; /** Ownership class used for permissions and badges. */ ownerType?: 'deepline' | 'org'; /** Slug of the owning workspace, or `deepline` for system plays. */ ownerSlug?: string; /** Scope in the control plane. */ scope?: 'org' | 'system'; /** Whether the current actor can edit this play in place. */ canEdit?: boolean; /** Whether the current actor can clone this play into their org. */ canClone?: boolean; /** Organization ID that owns this play. */ orgId: string; /** User ID that created the play. */ userId: string; /** Total number of times this play has been executed. */ runCount: number; /** Primary key column for CSV-based plays. */ tableNamespace?: string | null; /** Public Deepline id of the latest run. */ latestRunId?: string | null; /** Unix timestamp (ms). */ createdAt: number; /** Unix timestamp (ms). */ updatedAt: number; /** Source code of the current revision. */ sourceCode?: string | null; /** Static pipeline, if applicable. */ staticPipeline?: unknown; /** Serialized input schema contract for rendering / validation help. */ inputSchema?: Record | null; /** Serialized output schema contract for rendering / validation help. */ outputSchema?: Record | null; /** Alternate names that resolve to this play. */ aliases?: string[]; /** The revision that run-by-name resolves to. */ currentRevision?: PlayRevisionSummary | null; /** The current working revision (may differ from live). */ workingRevision?: PlayRevisionSummary | null; /** The live revision that executes for named runs. */ liveRevision?: PlayRevisionSummary | null; /** `true` if the working revision differs from the live revision. */ isDraftDirty?: boolean; /** Compatibility field for older readers. */ currentPublishedVersion?: number | null; } export interface PlayListItem { playKey?: string; reference?: string; name: string; displayName?: string; description?: string | null; pinned?: boolean; toolCategories?: string[]; origin?: 'prebuilt' | 'owned'; ownerType?: 'deepline' | 'org'; ownerSlug?: string; canEdit?: boolean; canClone?: boolean; orgId: string; userId: string; runCount: number; updatedAt: number; createdAt: number; currentPublishedVersion?: number | null; tableNamespace?: string | null; isDraftDirty?: boolean; hasInputSchema?: boolean; inputSchema?: Record | null; outputSchema?: Record | null; staticPipeline?: unknown; currentRevision?: PlayRevisionSummary | null; liveRevision?: PlayRevisionSummary | null; aliases?: string[]; triggerStatus?: { cron: string | null; webhook: string | null; blockedReason: string | null; }; } export interface ProductNotificationEventDefinition { id: string; label: string; description: string; source: 'cron' | 'webhook'; outcome: 'succeeded' | 'failed'; defaultEnabled: boolean; } export interface ProductNotificationSettings { contractVersion: number; catalog: ProductNotificationEventDefinition[]; notifications?: ProductNotification[]; providers?: Array<{ kind: string; targetLabel: string }>; destinations: Array>; subscriptions: Array<{ eventType: string; enabled: boolean; destinationId: string; }>; dlq: { count: number; capped: boolean }; slackConnection?: { connected: boolean; status: string }; } export interface ProductNotification { id: string; name: string; provider: string; target: { id: string; name: string; kind?: 'channel' | 'member' }; enabled: boolean; status: string; eventTypes: string[]; lastTestedAt?: number; lastTestStatus?: string; lastErrorMessage?: string; } export interface PlayDescription { name: string; /** Stable registry key. Same value `plays list` reports for this play. */ playKey?: string; reference?: string; displayName?: string; description?: string | null; pinned?: boolean; toolCategories?: string[]; origin?: 'prebuilt' | 'owned'; ownerType?: 'deepline' | 'org'; canEdit?: boolean; canClone?: boolean; aliases: string[]; inputSchema?: Record | null; outputSchema?: Record | null; staticPipeline?: Record | null; csvInput?: Record | null; rowOutputSchema?: Record | null; runCommand: string; examples: string[]; cloneEditStarter?: { path: string; command: string; checkCommand: string; }; currentPublishedVersion?: number | null; /** * Version currently serving runs by name, from the live revision. Null when * the play has never been published. */ liveVersion?: number | null; /** Whether this play's cron and webhook triggers are armed. */ triggerStatus?: { cron: string | null; webhook: string | null; blockedReason: string | null; }; isDraftDirty?: boolean; latestRunId?: string | null; } /** * Complete play detail including definition, recent runs, and sheet state. * * Returned by {@link DeeplineClient.getPlay}. * * @example * ```typescript * const detail = await client.getPlay('email-waterfall'); * console.log(`${detail.play.name} — ${detail.play.runCount} runs`); * console.log(`Live: v${detail.play.liveRevision?.version}`); * console.log(`Latest runs:`, detail.latestRuns.map(r => r.status)); * ``` */ export interface PlayDetail { /** Full play definition with revisions. */ play: PlayDefinitionDetail; /** Most recent runs (newest first). */ latestRuns: PlayRunListItem[]; /** Sheet processing summary. */ sheetSummary: PlaySheetSummary; /** Neon database URL for this play's customer data. */ customerDbUrl: string; /** Change cursor for incremental sync. */ deltaCursor: number; /** * Present only when requested through `getPlay(..., { source: ... })`. * `files` is the complete authored source tree, keyed by logical path. */ source?: { selector: 'working' | 'live' | `version:${number}`; revision: { id: string; version: number }; entryFile: string; files: Record; }; } export interface ClearPlayHistoryRequest { /** Optional explicit ctx.dataset keys to clear. Omit to clear all discovered sheets for the play. */ tableNamespaces?: string[]; } export interface ClearPlayHistoryResult { playName: string; deletedRuns: number; droppedTables: string[]; } /** * Response from starting a play run. * * Internal/advanced payload returned by low-level play submission primitives. * Most callers should prefer `deepline plays run`, {@link DeeplineClient.runPlay}, * or {@link PlayJob.get}. * * @example * ```typescript * const started = await client.startPlayRun({ name: 'my-play', input: { domain: 'stripe.com' } }); * console.log(`Started: ${started.workflowId}`); * console.log(`Dashboard: ${started.dashboardUrl}`); * ``` */ export interface PlayRunStart { /** Public Deepline play-run id for tracking this execution. */ workflowId: string; /** Public Deepline play-run API version. */ apiVersion?: number; /** Play name (echoed back from the request). */ name?: string; /** Initial status (typically `'RUNNING'`). */ status?: string; /** Resolved runtime backend used for this run. */ runtimeBackend?: string; /** Canonical run contract compatibility metadata. */ contract?: Record | null; /** Dashboard URL for the named play. */ dashboardUrl?: string; /** Terminal status returned when the start request used a short completion wait. */ finalStatus?: unknown; /** Canonical compact run package returned by current SDK/API responses. */ package?: PlayRunPackage; } /** * Result returned by {@link DeeplineClient.checkPlayArtifact}. * * This is the check-only version of play artifact registration: the server runs * the same preflight compiler and static-analysis pass without storing, * publishing, or starting a play run. */ export interface PlayCheckResult { valid: boolean; errors: string[]; warnings?: string[]; staticPipeline?: Record | null; toolGetterHints?: PlayCheckToolGetterHint[]; /** * Recognized trigger bindings parsed from the play source (`sqlListeners` / * cron / webhook). Present only when the play declares at least one trigger, * so an author can confirm the binding was recognized rather than silently * dropped. Field names mirror the `definePlay` binding contract. */ triggers?: PlayCheckTriggersSummary | null; /** * Structured, machine-actionable issues surfaced by the check. An ADDITIVE * channel alongside `errors[]`: every `error`-severity issue is also present * in `errors[]` (so string-level tooling keeps working), while an agent can * read `code` / `validOptions` / `docsHint` to self-correct. `warning` * severity issues do NOT make the check invalid. */ issues?: PlayCheckIssue[]; /** * Affirmative echo of what Deepline recognized — triggers, tools, * datasets/columns, inputs, outputs — so a valid check reflects the parsed * shape rather than a bare "ok". */ recognized?: PlayCheckRecognizedSummary; /** * Human one-liner over {@link PlayCheckResult.recognized}, e.g. * `1 trigger · 2 tools · 1 dataset · 14 columns`. */ summary?: string; artifactHash?: string | null; graphHash?: string | null; /** SHA-256 of the exact source bytes checked by Deepline. */ sourceHash?: string | null; /** * Per-export results, present ONLY when the checked file exports more than * one play. Single-play files keep the exact flat shape they always had. * Entry 0 is the default export and mirrors the top-level fields; the * top-level `valid` is the AND over every entry, so an agent that reads only * `valid` can never ship a file whose second play fails. */ exports?: PlayCheckExportResult[]; /** Enforceable byte budgets measured during cloud preflight. */ limits?: { revisionStorage: { usedBytes: number; limitBytes: number; withinLimit: boolean; breakdown: { sourceCodeBytes: number; staticPipelineBytes: number; bindingsBytes: number; descriptionBytes: number; }; }; bundle: { usedBytes: number; limitBytes: number; withinLimit: boolean; }; }; } /** * One exported play's check result inside a multi-play file. Carries the same * per-play fields as {@link PlayCheckResult}, unprefixed and unaggregated, so a * consumer can attribute an error to the export that produced it. */ export interface PlayCheckExportResult { /** Canonical export name: `default`, or the named export (`batch`). */ exportName: string; /** The `definePlay` name this export declares. */ name?: string | null; valid: boolean; errors: string[]; warnings?: string[]; issues?: PlayCheckIssue[]; staticPipeline?: Record | null; artifactHash?: string | null; graphHash?: string | null; sourceHash?: string | null; summary?: string; recognized?: PlayCheckRecognizedSummary; triggers?: PlayCheckTriggersSummary | null; } /** Severity of a {@link PlayCheckIssue}. `error` fails the check; `warning` does not. */ export type PlayCheckIssueSeverity = 'error' | 'warning'; /** * One structured, machine-actionable issue surfaced by `deepline plays check`. * Mirrors the server-side `PlayCheckIssue` contract. `code` is a stable machine * code from a closed server-side set; `validOptions` enumerates the valid values * (tool ids / stream keys / columns / operators) so an agent self-corrects by * reading the structure instead of brute-forcing the compiler. */ export interface PlayCheckIssue { code: string; severity: PlayCheckIssueSeverity; message: string; /** * Which exported play raised this issue, when the checked file exports more * than one and this is not the default export. Absent everywhere else, so * the structured channel stays byte-identical for single-play files. */ exportName?: string; path?: string; hint?: string; validOptions?: string[]; docsHint?: string; } /** * Affirmative "here's what Deepline recognized" echo returned alongside a * check's issues. Field names reuse the public play binding contract. */ export interface PlayCheckRecognizedSummary { triggers?: PlayCheckTriggersSummary; tools?: string[]; /** * Durable datasets the play produces. `undrawnColumns` echoes the columns the * author declared out of an authored `@mermaid` diagram with * `.run({ undrawnColumns: [...] })`, so an opt-out is visible in check output. */ datasets?: { name: string; columns?: string[]; undrawnColumns?: string[] }[]; inputs?: string[]; outputs?: string[]; } /** * One recognized SQL-listener trigger echoed back by {@link DeeplineClient.checkPlayArtifact}. */ export interface PlayCheckSqlListenerTrigger { id: string; tool?: string; stream?: string; operations: string[]; /** * The recognized `sqlListeners.where` row filter, echoed back so an author can * confirm Deepline bound it. Mirrors the server `StoredSqlListenerWhere` shape * (`before` / `after` maps of column → operator filter). Absent when the * listener declares no `where`. */ where?: { before?: Record>; after?: Record>; }; } /** * The input delivered to a SQL-listener Play invocation. One changed Customer * DB row starts one run with this top-level event object; it is not an events * array or a polling batch. */ export interface PlayCheckSqlListenerEventSummary { delivery: 'one_event_per_matched_row'; fields: Array< | 'tool' | 'stream' | 'operation' | 'before' | 'after' | 'changedAt' | 'metadata' >; } /** * Concise summary of the trigger bindings the server recognized for a play. * Only present triggers are populated. */ export interface PlayCheckTriggersSummary { sqlListeners?: PlayCheckSqlListenerTrigger[]; sqlListenerEvent?: PlayCheckSqlListenerEventSummary; cron?: { schedule: string; timezone?: string }; webhook?: true; } export interface PlayCheckToolGetterHint { toolId: string; lists: Array<{ name: string; expression: string; raw?: string; }>; values: Array<{ name: string; expression: string; raw?: string; }>; raw?: string; unavailable?: string; } /** * Request body for starting a play run via {@link DeeplineClient.startPlayRun}. * * Internal/advanced request shape for low-level submission primitives. * Most callers should prefer `deepline plays run`, {@link DeeplineClient.runPlay}, * or {@link Deepline.connect}. * * Either `name` (for live plays) or `artifactStorageKey` (for packaged ad hoc runs) is required. * * @example * ```typescript * // Run a live play by name: * await client.startPlayRun({ name: 'email-waterfall', input: { domain: 'stripe.com' } }); * * // Run a packaged ad hoc play by registered artifact: * await client.startPlayRun({ * artifactStorageKey: 'plays/artifacts/org/acme/my-play/playgraph_abc123.json', * input: { domain: 'stripe.com' }, * }); * ``` */ export interface StartPlayRunRequest { /** Play name for registered revisions. */ name?: string; /** Explicit revision ID when the caller wants a specific saved version. */ revisionId?: string; /** R2 artifact key for ad hoc artifact-backed runs. */ artifactStorageKey?: string; /** Source snapshot already validated while registering this artifact. */ sourceCode?: string; /** Source graph snapshots for local helper files included in cloud preflight. */ sourceFiles?: Record; /** Human-readable one-line description for the revision created by file-backed runs. */ description?: string; /** Static pipeline already produced while registering this artifact. */ staticPipeline?: unknown; /** Artifact content hash already validated while registering this artifact. */ artifactHash?: string; /** Static graph hash already validated while registering this artifact. */ graphHash?: string; /** Optional preloaded artifact snapshot for immediate ad hoc execution. */ runtimeArtifact?: Record; /** Compiler manifest for ad hoc graph runs, including imported play dependencies. */ compilerManifest?: PlayCompilerManifest; /** Primary input file bytes for one-shot server-side staging. */ inputFileUpload?: unknown; /** Packaged file bytes for one-shot server-side staging. */ packagedFileUploads?: unknown[]; /** Runtime input passed to the play function as its second argument. */ input?: Record; /** Staged file reference for the primary input file (e.g. CSV). */ inputFile?: unknown; /** Additional staged file references (dependencies, data files). */ packagedFiles?: unknown[]; /** Compatibility flag; active sibling runs are allowed. */ force?: boolean; /** Explicit cache-bypass flag for durable dataset and tool-call reuse. */ forceToolRefresh?: boolean; /** * Per-run ceiling for concurrently resident provider-tool executions and * direct ctx.fetch calls. The server validates the supported range. */ maxConcurrentExternalCalls?: number; /** Run-wide default and ceiling for live dataset-map row resolvers. */ maxConcurrentRows?: number; /** Optionally let the start request wait briefly and return a terminal result. */ waitForCompletionMs?: number; /** * Per-run execution profile override. The server defaults to absurd. The * Only `absurd` is accepted; most callers should leave this unset. */ profile?: string; /** Optional per-run provider execution mode for eval/smoke runs. */ integrationMode?: 'live' | 'eval_stub' | 'fixture'; /** Fixture-only provider response timing and outcome simulation. */ fixtureBehavior?: import('../../shared_libs/play-runtime/fixture-behavior').FixtureBehavior; /** Internal runtime estate selection. The app host remains unchanged. */ runtime?: PlayRuntimeSelection; /** Internal/dev-only runtime policy overrides for black-box durability tests. */ testPolicyOverrides?: Record; } /** * Request body for making a play revision live. * * If omitted, the server promotes the current working revision. */ export interface PublishPlayVersionRequest { /** Explicit revision ID to make live. */ revisionId?: string; } /** * Result returned after making a play revision live. */ export interface PublishPlayVersionResult { success: boolean; name: string; liveVersion?: number; triggerMetadata?: unknown; triggerBindings?: unknown; } /** * Result returned after moving an org-owned play to Trash. * * `deletePlay` is retained as the SDK method name for compatibility, but play * deletion is soft: revisions and run history remain available if the play is * restored. */ export interface DeletePlayResult { archived: boolean; alreadyArchived: boolean; name: string; archivedBindingCount: number; } /** Result returned after restoring an org-owned play from Trash. */ export interface RestorePlayResult { restored: boolean; alreadyActive?: boolean; name: string; } // —————————————————————————————————————————————————————————— // Shareable play pages // —————————————————————————————————————————————————————————— /** Owner-facing view of a play's public share page. */ export interface SharePageOwnerView { shareSlug: string; /** Org URL handle; the public page lives at `/p/{orgSlug}/{playName}`. */ orgSlug: string; publishedRevisionId: string; publishedVersion: number; visibility: string; seoIndexing: 'index' | 'noindex'; showAverageDeeplineCost: boolean; showAverageLatency: boolean; /** Stable public path, e.g. `/p/{orgSlug}/{playName}`. */ publicPath: string; /** Version-pinned canonical path, e.g. `/p/{orgSlug}/{playName}/v/{version}`. */ canonicalPath: string; createdAt: number; updatedAt: number; } /** One row in the owner-facing revision picker for sharing. */ export interface SharePageRevisionOption { revisionId: string; version: number; isLive: boolean; isWorking: boolean; isPublished: boolean; hasMap: boolean; hasCard: boolean; createdAt: number; } /** * Status payload from `GET/POST/PATCH /api/v2/plays/:name/share`. * The revision picker is bounded to recent and state-bearing revisions. Pass a * selected revision id to `getSharePage` to retain any older selection. */ export interface SharePageStatus { playName: string; share: SharePageOwnerView | null; publishedCopy: unknown | null; revisions: SharePageRevisionOption[]; /** Present on publish responses when share-card generation was non-strict. */ warning?: string | null; } export interface PublishSharePageRequest { /** The revision to publish/repoint the public page to. */ revisionId: string; /** Must be true — acknowledges the page is publicly viewable. */ acknowledgedUnlisted: true; showAverageDeeplineCost?: boolean; showAverageLatency?: boolean; seoIndexing?: 'index' | 'noindex'; } export interface UpdateSharePageRequest { showAverageDeeplineCost?: boolean; showAverageLatency?: boolean; seoIndexing?: 'index' | 'noindex'; }