deepline 0.1.185 → 0.1.187

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.
@@ -650,6 +650,7 @@ type DynamicWorkflowMetadata = {
650
650
  artifactStorageKey: string;
651
651
  artifactHash?: string | null;
652
652
  dynamicWorkerCode?: string | null;
653
+ dynamicWorkerCodeHash?: string | null;
653
654
  integrationMode?: 'live' | 'eval_stub' | 'fixture' | null;
654
655
  packagedFiles?: Array<{
655
656
  playPath: string;
@@ -682,12 +683,18 @@ function normalizeIntegrationMode(
682
683
  function buildDynamicWorkflowMetadata(
683
684
  params: PlayWorkflowParams,
684
685
  ): DynamicWorkflowMetadata {
686
+ const dynamicWorkerCodeHash =
687
+ typeof params.dynamicWorkerCode === 'string' &&
688
+ params.dynamicWorkerCode.length > 0
689
+ ? stableHash(params.dynamicWorkerCode)
690
+ : null;
685
691
  return {
686
692
  runId: params.runId ?? null,
687
693
  graphHash: params.graphHash,
688
694
  artifactStorageKey: params.artifactStorageKey,
689
695
  artifactHash: params.artifactHash ?? null,
690
696
  dynamicWorkerCode: null,
697
+ dynamicWorkerCodeHash,
691
698
  integrationMode: normalizeIntegrationMode(params.integrationMode),
692
699
  packagedFiles: normalizePackagedFiles(params.packagedFiles),
693
700
  };
@@ -3684,6 +3691,10 @@ export class DynamicWorkflow extends WorkflowEntrypoint<
3684
3691
  typeof metadata.dynamicWorkerCode === 'string'
3685
3692
  ? metadata.dynamicWorkerCode
3686
3693
  : null,
3694
+ dynamicWorkerCodeHash:
3695
+ typeof metadata.dynamicWorkerCodeHash === 'string'
3696
+ ? metadata.dynamicWorkerCodeHash
3697
+ : null,
3687
3698
  integrationMode: normalizeIntegrationMode(
3688
3699
  metadata.integrationMode,
3689
3700
  ),
@@ -5287,6 +5298,36 @@ function dynamicPlayWorkerCacheKey(input: {
5287
5298
  ].join(':');
5288
5299
  }
5289
5300
 
5301
+ function dynamicPlayWorkerArtifactIdentity(
5302
+ metadata: Pick<
5303
+ DynamicWorkflowMetadata,
5304
+ | 'artifactHash'
5305
+ | 'artifactStorageKey'
5306
+ | 'dynamicWorkerCode'
5307
+ | 'dynamicWorkerCodeHash'
5308
+ >,
5309
+ ): string {
5310
+ const artifactHash = metadata.artifactHash?.trim();
5311
+ const inlineCodeHash =
5312
+ typeof metadata.dynamicWorkerCodeHash === 'string' &&
5313
+ metadata.dynamicWorkerCodeHash.length > 0
5314
+ ? metadata.dynamicWorkerCodeHash
5315
+ : typeof metadata.dynamicWorkerCode === 'string' &&
5316
+ metadata.dynamicWorkerCode.length > 0
5317
+ ? stableHash(metadata.dynamicWorkerCode)
5318
+ : null;
5319
+ if (artifactHash && inlineCodeHash) {
5320
+ return `${artifactHash}:inline=${inlineCodeHash}`;
5321
+ }
5322
+ if (artifactHash) {
5323
+ return artifactHash;
5324
+ }
5325
+ if (inlineCodeHash) {
5326
+ return `inline=${inlineCodeHash}`;
5327
+ }
5328
+ return stableHash(metadata.artifactStorageKey);
5329
+ }
5330
+
5290
5331
  function dynamicWorkerBundledCodeCacheKey(input: {
5291
5332
  artifactStorageKey: string;
5292
5333
  artifactHash?: string | null;
@@ -5350,8 +5391,7 @@ function loadDynamicPlayWorkerSync(
5350
5391
  'Dynamic play worker requires artifactStorageKey metadata.',
5351
5392
  );
5352
5393
  }
5353
- const artifactIdentity =
5354
- metadata.artifactHash?.trim() || stableHash(artifactStorageKey);
5394
+ const artifactIdentity = dynamicPlayWorkerArtifactIdentity(metadata);
5355
5395
  const workerCacheKey = dynamicPlayWorkerCacheKey({
5356
5396
  env,
5357
5397
  graphHash,
@@ -5439,8 +5479,7 @@ async function loadDynamicPlayWorker(
5439
5479
  'Dynamic play worker requires artifactStorageKey metadata.',
5440
5480
  );
5441
5481
  }
5442
- const artifactIdentity =
5443
- metadata.artifactHash?.trim() || stableHash(artifactStorageKey);
5482
+ const artifactIdentity = dynamicPlayWorkerArtifactIdentity(metadata);
5444
5483
  const workerCacheKey = dynamicPlayWorkerCacheKey({
5445
5484
  env,
5446
5485
  graphHash,
@@ -540,8 +540,8 @@ type WorkerEnv = {
540
540
  /**
541
541
  * In-process Fetcher constructed by the coordinator and handed to the
542
542
  * per-graphHash play Worker. When present, runtime callbacks
543
- * (`/api/v2/internal/play-runtime`,
544
- * `/api/v2/internal/play-runtime/*`,
543
+ * (`/api/v2/plays/internal/runtime`,
544
+ * `/api/v2/plays/internal/*`,
545
545
  * `/api/v2/plays/runtime-tools/*`) skip the public callback URL and route
546
546
  * directly through the coordinator's process to the configured app — saves
547
547
  * the *.workers.dev → CF edge → cloudflared → localhost chain on every
@@ -117,9 +117,16 @@ import type { ToolExecution } from './client.js';
117
117
  /**
118
118
  * Optional trigger bindings for a play.
119
119
  *
120
- * Plays can be triggered by webhooks (with HMAC signature verification)
121
- * or cron schedules. Bindings are declared as the third argument to
122
- * {@link definePlay}.
120
+ * A play can be triggered three ways, declared as the third argument to
121
+ * {@link definePlay}:
122
+ * - `webhook` — an inbound HTTP call (with optional HMAC signature verification);
123
+ * - `cron` — a schedule; or
124
+ * - `sqlListeners` — a **monitor**: the play runs whenever a monitor writes a new
125
+ * row to its output stream. This is how you build a play "on top of" a monitor
126
+ * (e.g. run enrichment every time a watched company posts a new job). Each
127
+ * listener binds to a monitor tool id + one of its output stream keys (see
128
+ * `deepline monitors available <id>` for a tool's streams and row columns).
129
+ * The changed row is delivered to the handler as the listener event's `after`.
123
130
  *
124
131
  * @example Webhook with HMAC verification
125
132
  * ```typescript
@@ -141,6 +148,20 @@ import type { ToolExecution } from './client.js';
141
148
  * });
142
149
  * ```
143
150
  *
151
+ * @example Monitor-triggered (run a play on a monitor's output)
152
+ * ```typescript
153
+ * definePlay('on-new-job-opening', handler, {
154
+ * sqlListeners: [
155
+ * {
156
+ * id: 'jobs',
157
+ * tool: 'tamradar.company_radar',
158
+ * stream: 'company_job_openings',
159
+ * operations: ['INSERT'],
160
+ * },
161
+ * ],
162
+ * });
163
+ * ```
164
+ *
144
165
  * @sdkReference runtime 030
145
166
  */
146
167
  export type PlayBindings = {
@@ -105,10 +105,10 @@ export const SDK_RELEASE = {
105
105
  // 0.1.154 removes the short-lived generated enrich StepOptions recompute
106
106
  // fields shipped in 0.1.153.
107
107
  // 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
108
- version: '0.1.185',
108
+ version: '0.1.187',
109
109
  apiContract: '2026-06-dataset-handle-results-hard-cutover',
110
110
  supportPolicy: {
111
- latest: '0.1.185',
111
+ latest: '0.1.187',
112
112
  minimumSupported: '0.1.53',
113
113
  deprecatedBelow: '0.1.53',
114
114
  commandMinimumSupported: [
@@ -922,10 +922,98 @@ export interface PlayCheckResult {
922
922
  warnings?: string[];
923
923
  staticPipeline?: Record<string, unknown> | null;
924
924
  toolGetterHints?: PlayCheckToolGetterHint[];
925
+ /**
926
+ * Recognized trigger bindings parsed from the play source (`sqlListeners` /
927
+ * cron / webhook). Present only when the play declares at least one trigger,
928
+ * so an author can confirm the binding was recognized rather than silently
929
+ * dropped. Field names mirror the `definePlay` binding contract.
930
+ */
931
+ triggers?: PlayCheckTriggersSummary | null;
932
+ /**
933
+ * Structured, machine-actionable issues surfaced by the check. An ADDITIVE
934
+ * channel alongside `errors[]`: every `error`-severity issue is also present
935
+ * in `errors[]` (so string-level tooling keeps working), while an agent can
936
+ * read `code` / `validOptions` / `docsHint` to self-correct. `warning`
937
+ * severity issues do NOT make the check invalid.
938
+ */
939
+ issues?: PlayCheckIssue[];
940
+ /**
941
+ * Affirmative echo of what Deepline recognized — triggers, tools,
942
+ * datasets/columns, inputs, outputs — so a valid check reflects the parsed
943
+ * shape rather than a bare "ok".
944
+ */
945
+ recognized?: PlayCheckRecognizedSummary;
946
+ /**
947
+ * Human one-liner over {@link PlayCheckResult.recognized}, e.g.
948
+ * `1 trigger · 2 tools · 1 dataset · 14 columns`.
949
+ */
950
+ summary?: string;
925
951
  artifactHash?: string | null;
926
952
  graphHash?: string | null;
927
953
  }
928
954
 
955
+ /** Severity of a {@link PlayCheckIssue}. `error` fails the check; `warning` does not. */
956
+ export type PlayCheckIssueSeverity = 'error' | 'warning';
957
+
958
+ /**
959
+ * One structured, machine-actionable issue surfaced by `deepline plays check`.
960
+ * Mirrors the server-side `PlayCheckIssue` contract. `code` is a stable machine
961
+ * code from a closed server-side set; `validOptions` enumerates the valid values
962
+ * (tool ids / stream keys / columns / operators) so an agent self-corrects by
963
+ * reading the structure instead of brute-forcing the compiler.
964
+ */
965
+ export interface PlayCheckIssue {
966
+ code: string;
967
+ severity: PlayCheckIssueSeverity;
968
+ message: string;
969
+ path?: string;
970
+ hint?: string;
971
+ validOptions?: string[];
972
+ docsHint?: string;
973
+ }
974
+
975
+ /**
976
+ * Affirmative "here's what Deepline recognized" echo returned alongside a
977
+ * check's issues. Field names reuse the public play binding contract.
978
+ */
979
+ export interface PlayCheckRecognizedSummary {
980
+ triggers?: PlayCheckTriggersSummary;
981
+ tools?: string[];
982
+ datasets?: { name: string; columns?: string[] }[];
983
+ inputs?: string[];
984
+ outputs?: string[];
985
+ }
986
+
987
+ /**
988
+ * One recognized SQL-listener trigger echoed back by {@link DeeplineClient.checkPlayArtifact}.
989
+ */
990
+ export interface PlayCheckSqlListenerTrigger {
991
+ id: string;
992
+ tool?: string;
993
+ stream?: string;
994
+ operations: string[];
995
+ /**
996
+ * The recognized `sqlListeners.where` row filter, echoed back so an author can
997
+ * confirm Deepline bound it. Mirrors the server `StoredSqlListenerWhere` shape
998
+ * (`before` / `after` maps of column → operator filter). Absent when the
999
+ * listener declares no `where`.
1000
+ */
1001
+ where?: {
1002
+ before?: Record<string, Record<string, unknown>>;
1003
+ after?: Record<string, Record<string, unknown>>;
1004
+ };
1005
+ }
1006
+
1007
+ /**
1008
+ * Concise summary of the trigger bindings the server recognized for a play.
1009
+ * Only present triggers are populated.
1010
+ */
1011
+ export interface PlayCheckTriggersSummary {
1012
+ sqlListeners?: PlayCheckSqlListenerTrigger[];
1013
+ cron?: { schedule: string; timezone?: string };
1014
+ webhook?: true;
1015
+ }
1016
+
929
1017
  export interface PlayCheckToolGetterHint {
930
1018
  toolId: string;
931
1019
  lists: Array<{