deepline 0.3.88 → 0.3.89

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.
Files changed (121) hide show
  1. package/dist/bundling-sources/sdk/src/client.ts +534 -4
  2. package/dist/bundling-sources/sdk/src/config.ts +77 -0
  3. package/dist/bundling-sources/sdk/src/http.ts +76 -30
  4. package/dist/bundling-sources/sdk/src/index.ts +6 -0
  5. package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +1 -1
  6. package/dist/bundling-sources/sdk/src/play.ts +15 -1
  7. package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +2 -2
  8. package/dist/bundling-sources/sdk/src/release.ts +1 -1
  9. package/dist/bundling-sources/sdk/src/types.ts +83 -4
  10. package/dist/bundling-sources/shared_libs/integration-contracts/AGENTS.md +9 -0
  11. package/dist/bundling-sources/shared_libs/integration-contracts/README.md +3 -0
  12. package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +2 -0
  13. package/dist/bundling-sources/shared_libs/monitors/analytics-install-guides.ts +77 -0
  14. package/dist/bundling-sources/shared_libs/monitors/billing/charges.ts +125 -0
  15. package/dist/bundling-sources/shared_libs/monitors/billing/policy-builders.ts +686 -0
  16. package/dist/bundling-sources/shared_libs/monitors/billing/pricing.ts +54 -0
  17. package/dist/bundling-sources/shared_libs/monitors/billing/public-pricing.ts +72 -0
  18. package/dist/bundling-sources/shared_libs/monitors/billing/session.ts +45 -0
  19. package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +454 -0
  20. package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +260 -0
  21. package/dist/bundling-sources/shared_libs/monitors/billing/types.ts +215 -0
  22. package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +333 -0
  23. package/dist/bundling-sources/shared_libs/monitors/cursor-page.ts +42 -0
  24. package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
  25. package/dist/bundling-sources/shared_libs/monitors/framework-managed-payload-fields.ts +71 -0
  26. package/dist/bundling-sources/shared_libs/monitors/generated/provider-monitor-callback-admission-targets.ts +16 -0
  27. package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +267 -0
  28. package/dist/bundling-sources/shared_libs/monitors/inbound-publish-key.ts +39 -0
  29. package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +82 -0
  30. package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +473 -0
  31. package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +1 -1
  32. package/dist/bundling-sources/shared_libs/monitors/package.json +29 -0
  33. package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +1125 -0
  34. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +263 -0
  35. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +964 -0
  36. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +56 -0
  37. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +131 -0
  38. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +535 -0
  39. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-legacy-aliases.ts +16 -0
  40. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-priority-execution.ts +56 -0
  41. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +28 -0
  42. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-runtime-read-eligibility.ts +38 -0
  43. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
  44. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-status.ts +10 -0
  45. package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +112 -0
  46. package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +300 -0
  47. package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +22 -0
  48. package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +93 -0
  49. package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +332 -0
  50. package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +221 -0
  51. package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +105 -0
  52. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-guidance.ts +73 -0
  53. package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +81 -0
  54. package/dist/bundling-sources/shared_libs/monitors/tsconfig.json +10 -0
  55. package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
  56. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +90 -12
  57. package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +78 -0
  58. package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
  59. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +407 -53
  60. package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
  61. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +57 -0
  62. package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
  63. package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +6 -0
  64. package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
  65. package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
  66. package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
  67. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
  68. package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -0
  69. package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
  70. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +18 -4
  71. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
  72. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +2 -0
  73. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -0
  74. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +10 -8
  75. package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
  76. package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
  77. package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
  78. package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +24 -0
  79. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +30 -1
  80. package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
  81. package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +1 -1
  82. package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +6 -3
  83. package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +454 -17
  84. package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
  85. package/dist/bundling-sources/shared_libs/plays/contracts.ts +6 -14
  86. package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
  87. package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
  88. package/dist/bundling-sources/shared_libs/plays/email-status.ts +1 -1
  89. package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
  90. package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
  91. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +44 -14
  92. package/dist/bundling-sources/shared_libs/plays/tool-category-descriptions.ts +2 -2
  93. package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
  94. package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
  95. package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +560 -0
  96. package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
  97. package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +59 -0
  98. package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
  99. package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
  100. package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
  101. package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
  102. package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
  103. package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
  104. package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +28 -0
  105. package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
  106. package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +267 -0
  107. package/dist/cli/index.js +1070 -193
  108. package/dist/cli/index.mjs +1057 -180
  109. package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-DsLbQaew.d.mts} +132 -8
  110. package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-DsLbQaew.d.ts} +132 -8
  111. package/dist/index.d.mts +834 -12
  112. package/dist/index.d.ts +834 -12
  113. package/dist/index.js +469 -40
  114. package/dist/index.mjs +469 -40
  115. package/dist/install-integrity.json +65 -4
  116. package/dist/plays/bundle-play-file.d.mts +8 -3
  117. package/dist/plays/bundle-play-file.d.ts +8 -3
  118. package/dist/plays/bundle-play-file.mjs +100 -20
  119. package/package.json +3 -1
  120. /package/dist/bundling-sources/shared_libs/{integrations/bettercontact-execution-policy.ts → integration-contracts/bettercontact/execution-policy.ts} +0 -0
  121. /package/dist/bundling-sources/shared_libs/{integrations/theirstack-execution-policy.ts → integration-contracts/theirstack/execution-policy.ts} +0 -0
@@ -0,0 +1,73 @@
1
+ import type { ProviderMonitorPostDeployGuidance } from '@deepline/monitors/provider-monitor-capability';
2
+
3
+ // Client-safe provider setup metadata. Provider monitor definitions reference
4
+ // these exact objects, while the integrations dialog reads them directly.
5
+ export const VECTOR_POST_DEPLOY_GUIDANCE = {
6
+ title: 'Connect Vector to this monitor',
7
+ steps: [
8
+ 'In Vector, open the segment named in this monitor setup.',
9
+ 'Add a webhook endpoint using {{callback_url}}, then select contact.visited.',
10
+ 'Enable the webhook action on the segment and send a Vector test event.',
11
+ ],
12
+ event_type: 'contact.visited',
13
+ documentation: [
14
+ {
15
+ label: 'Vector SiteID action integration guide',
16
+ url: 'https://learn.vector.co/articles/2260541690-building-an-action-integration-for-siteid',
17
+ },
18
+ ],
19
+ payload_example: {
20
+ type: 'contact.visited',
21
+ externalId: 'contact_123',
22
+ companyDomain: 'example.com',
23
+ },
24
+ } as const satisfies ProviderMonitorPostDeployGuidance;
25
+
26
+ export const RB2B_POST_DEPLOY_GUIDANCE = {
27
+ title: 'Connect RB2B to this monitor',
28
+ steps: [
29
+ 'In RB2B, open Integrations and choose Webhook.',
30
+ 'Paste {{callback_url}} as the single webhook URL and save.',
31
+ "Use RB2B's Send a Test Event action to verify the connection.",
32
+ ],
33
+ documentation: [
34
+ {
35
+ label: 'RB2B webhook setup guide',
36
+ url: 'https://support.rb2b.com/en/articles/8976614-setup-guide-webhook',
37
+ },
38
+ ],
39
+ payload_example: {
40
+ 'LinkedIn URL': 'https://www.linkedin.com/in/example',
41
+ Website: 'https://example.com',
42
+ },
43
+ } as const satisfies ProviderMonitorPostDeployGuidance;
44
+
45
+ export const SNITCHER_POST_DEPLOY_GUIDANCE = {
46
+ title: 'Install Deepline Analytics',
47
+ steps: [
48
+ 'Create the tracker code in Deepline, then paste it in your site’s document head.',
49
+ 'Confirm cookie consent before persistent tracking when your privacy policy requires it.',
50
+ ],
51
+ documentation: [
52
+ {
53
+ label: 'Deepline Analytics setup guide',
54
+ url: 'https://docs.snitcher.com/powered-by-snitcher/radar/installation',
55
+ },
56
+ ],
57
+ payload_example: {
58
+ session_uuid: '00000000-0000-4000-8000-000000000001',
59
+ start_time: '2026-01-01T00:00:00.000Z',
60
+ last_activity: '2026-01-01T00:01:00.000Z',
61
+ engagement_time: 60,
62
+ user_properties: { $uuid: 'deepline-test-visitor' },
63
+ events: [
64
+ { event_name: '$pageview', created_at: '2026-01-01T00:00:00.000Z' },
65
+ ],
66
+ },
67
+ } as const satisfies ProviderMonitorPostDeployGuidance;
68
+
69
+ export const TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE = {
70
+ vector: VECTOR_POST_DEPLOY_GUIDANCE,
71
+ rb2b: RB2B_POST_DEPLOY_GUIDANCE,
72
+ snitcher: SNITCHER_POST_DEPLOY_GUIDANCE,
73
+ } as const;
@@ -0,0 +1,81 @@
1
+ import { TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE } from '@deepline/monitors/tracking-provider-guidance';
2
+ import {
3
+ ANALYTICS_INTEGRATION_SLUG,
4
+ ANALYTICS_PUBLIC_TOOL,
5
+ } from '@/lib/analytics/public';
6
+
7
+ export const TRACKING_PROVIDER_INTEGRATIONS = {
8
+ vector: {
9
+ provider: 'vector',
10
+ displayName: 'Vector',
11
+ tool: 'vector.visitor_events',
12
+ monitorKey: 'vector-high-intent-visitors',
13
+ },
14
+ rb2b: {
15
+ provider: 'rb2b',
16
+ displayName: 'RB2B',
17
+ tool: 'rb2b.visitor_events',
18
+ monitorKey: 'rb2b-website-visitors',
19
+ },
20
+ [ANALYTICS_INTEGRATION_SLUG]: {
21
+ provider: 'snitcher',
22
+ displayName: 'Deepline Analytics',
23
+ // Used only by the server-side monitor adapter to resolve upstream wiring.
24
+ tool: 'snitcher.website_sessions',
25
+ publicTool: ANALYTICS_PUBLIC_TOOL,
26
+ monitorKey: 'snitcher-website-sessions',
27
+ },
28
+ } as const;
29
+
30
+ export type TrackingProviderIntegration =
31
+ (typeof TRACKING_PROVIDER_INTEGRATIONS)[keyof typeof TRACKING_PROVIDER_INTEGRATIONS] & {
32
+ docsUrl: string;
33
+ docsLabel: string;
34
+ };
35
+
36
+ export function getTrackingProviderIntegration(
37
+ provider: string,
38
+ ): TrackingProviderIntegration | null {
39
+ const integration =
40
+ TRACKING_PROVIDER_INTEGRATIONS[
41
+ provider as keyof typeof TRACKING_PROVIDER_INTEGRATIONS
42
+ ];
43
+ if (!integration) return null;
44
+ const docs =
45
+ TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE[
46
+ integration.provider as keyof typeof TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE
47
+ ]?.documentation[0];
48
+ if (!docs) return null;
49
+ return { ...integration, docsUrl: docs.url, docsLabel: docs.label };
50
+ }
51
+
52
+ export function trackingProviderWebhookSetup(
53
+ provider: string,
54
+ webhookEndpoint: string,
55
+ ): {
56
+ webhook_endpoint: string;
57
+ event_type?: 'contact.visited';
58
+ instructions: string[];
59
+ } | null {
60
+ const integration = getTrackingProviderIntegration(
61
+ provider === 'snitcher' ? ANALYTICS_INTEGRATION_SLUG : provider,
62
+ );
63
+ const guidance = integration
64
+ ? TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE[
65
+ integration.provider as keyof typeof TRACKING_PROVIDER_POST_DEPLOY_GUIDANCE
66
+ ]
67
+ : null;
68
+ if (!guidance) return null;
69
+ return {
70
+ webhook_endpoint: webhookEndpoint,
71
+ ...('event_type' in guidance && guidance.event_type === 'contact.visited'
72
+ ? { event_type: guidance.event_type }
73
+ : {}),
74
+ // The dialog shows the URL in a dedicated copy target, so retain its
75
+ // compact `webhook_endpoint` wording while deriving every step from the
76
+ // same metadata used by CLI/API guidance.
77
+ instructions: guidance.steps.map((step) =>
78
+ step.replaceAll('{{callback_url}}', 'webhook_endpoint'),
79
+ ),
80
+ };
81
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "incremental": false,
5
+ "noEmit": true,
6
+ "types": ["node"]
7
+ },
8
+ "include": ["./**/*.ts"],
9
+ "exclude": ["node_modules"]
10
+ }
@@ -101,7 +101,11 @@ export type PlayActivityState =
101
101
  };
102
102
 
103
103
  export type PlayActivityObservation = {
104
- schemaVersion: 1;
104
+ /**
105
+ * Retired marker. Producers stopped writing it; envelopes still in flight
106
+ * from an older producer carry `1`, so readers tolerate both shapes.
107
+ */
108
+ schemaVersion?: 1;
105
109
  /** Stable within one run, for example `tool:discover_ctos` or `dataset:leads`. */
106
110
  activityId: string;
107
111
  /** Optional owning play step. */
@@ -126,7 +130,7 @@ export function isPlayActivityObservation(
126
130
  ): value is PlayActivityObservation {
127
131
  if (
128
132
  !isRecord(value) ||
129
- value.schemaVersion !== 1 ||
133
+ (value.schemaVersion !== undefined && value.schemaVersion !== 1) ||
130
134
  typeof value.activityId !== 'string' ||
131
135
  !value.activityId.trim() ||
132
136
  typeof value.observedAt !== 'number' ||
@@ -316,7 +320,6 @@ export function createPlayActivityReporter(input: {
316
320
  type: 'activity.observed',
317
321
  observation: {
318
322
  ...observation,
319
- schemaVersion: 1,
320
323
  observedAt: observation.observedAt ?? input.now?.() ?? Date.now(),
321
324
  },
322
325
  });
@@ -402,7 +405,6 @@ export function projectPlayRunActivity(input: {
402
405
  if (input.waitKind === 'detached_runner') {
403
406
  return projection(
404
407
  {
405
- schemaVersion: 1,
406
408
  activityId: 'runner:managed',
407
409
  target: {
408
410
  kind: 'runner',
@@ -418,7 +420,6 @@ export function projectPlayRunActivity(input: {
418
420
  if (input.waitKind === 'sleep') {
419
421
  return projection(
420
422
  {
421
- schemaVersion: 1,
422
423
  activityId: 'run:sleep',
423
424
  target: {
424
425
  kind: 'step',
@@ -441,7 +442,6 @@ export function projectPlayRunActivity(input: {
441
442
  ) {
442
443
  return projection(
443
444
  {
444
- schemaVersion: 1,
445
445
  activityId: `event:${input.activeNodeId ?? 'run'}`,
446
446
  stepId: input.activeNodeId ?? undefined,
447
447
  target: {
@@ -468,7 +468,6 @@ export function projectPlayRunActivity(input: {
468
468
  if (normalizedStatus === 'waiting') {
469
469
  return projection(
470
470
  {
471
- schemaVersion: 1,
472
471
  activityId: 'run:legacy-wait',
473
472
  target: {
474
473
  kind: 'step',
@@ -506,7 +505,6 @@ export function projectPlayRunActivity(input: {
506
505
  const datasetProgress = datasetStep?.progress ?? null;
507
506
  return projection(
508
507
  {
509
- schemaVersion: 1,
510
508
  activityId: `dataset:${pendingDataset.datasetId ?? pendingDataset.tableNamespace}`,
511
509
  target: {
512
510
  kind: 'dataset',
@@ -548,7 +546,6 @@ export function projectPlayRunActivity(input: {
548
546
  const provider = toolId?.split(/[._]/)[0]?.trim() || null;
549
547
  return projection(
550
548
  {
551
- schemaVersion: 1,
552
549
  activityId: `step:${activeStep.nodeId}`,
553
550
  stepId: activeStep.nodeId,
554
551
  target:
@@ -577,7 +574,6 @@ export function projectPlayRunActivity(input: {
577
574
  if (normalizedStatus === 'queued') {
578
575
  return projection(
579
576
  {
580
- schemaVersion: 1,
581
577
  activityId: 'capacity:worker',
582
578
  target: { kind: 'capacity', pool: 'worker' },
583
579
  state: { kind: 'queued', reason: 'capacity' },
@@ -588,7 +584,6 @@ export function projectPlayRunActivity(input: {
588
584
  }
589
585
 
590
586
  const fallback: PlayActivityObservation = {
591
- schemaVersion: 1,
592
587
  activityId: 'run:legacy',
593
588
  target: {
594
589
  kind: 'step',
@@ -4,6 +4,7 @@ import { stat } from 'node:fs/promises';
4
4
  import { Readable } from 'node:stream';
5
5
  import { pipeline } from 'node:stream/promises';
6
6
  import type { PlaySheetContract } from '../plays/static-pipeline';
7
+ import type { AsyncPlayRunRef } from '../plays/authoring-contract';
7
8
  import type { PlayRowUpdate } from './/ctx-types';
8
9
  import type { PlayRunTimelineEntry } from './/live-events';
9
10
  import type { PlayDatasetBornFrom } from './/cell-provenance';
@@ -179,6 +180,51 @@ type RuntimeApiRequest =
179
180
  runId: string;
180
181
  firstClaimLatencyMs: number;
181
182
  }
183
+ | {
184
+ action: 'launch_play_async';
185
+ key: string;
186
+ invocationKey: string;
187
+ playRef: string;
188
+ input: Record<string, unknown>;
189
+ description: string;
190
+ schedulerSchema?: string | null;
191
+ ancestryPlayIds: string[];
192
+ }
193
+ | {
194
+ action: 'project_run_created';
195
+ idempotencyKey: string;
196
+ playName: string;
197
+ playReference?: string | null;
198
+ workflowId: string;
199
+ runId: string;
200
+ workflowFamilyKey: string;
201
+ definitionScope?: 'org' | 'system';
202
+ revisionId?: string | null;
203
+ artifactStorageKey?: string | null;
204
+ artifactHash?: string | null;
205
+ graphHash?: string | null;
206
+ runtimeBackend?: string | null;
207
+ schedulerBackend?: string | null;
208
+ schedulerSchema?: string | null;
209
+ executionProfile?: string | null;
210
+ runtimeReleaseId?: string | null;
211
+ runtimeDeployVersion?: string | null;
212
+ runtimeCallbackBaseUrl?: string | null;
213
+ coordinatorUrl?: string | null;
214
+ coordinatorWorkerName?: string | null;
215
+ runtimeWorkflowName?: string | null;
216
+ runtimeHarnessWorkerName?: string | null;
217
+ maxCreditsPerRun?: number | null;
218
+ staticPipeline?: unknown;
219
+ source?: 'published' | 'ad_hoc' | 'draft';
220
+ triggerSource?: 'webhook' | 'cron' | 'sql_listener' | 'api';
221
+ inputFileId?: string;
222
+ inputBytes?: number;
223
+ inputSha256?: string;
224
+ replayedFromRunId?: string | null;
225
+ secretRefs?: unknown[];
226
+ inputSummary?: Record<string, unknown>;
227
+ }
182
228
  | ({
183
229
  action: 'save_results';
184
230
  } & RuntimeSaveResults)
@@ -719,7 +765,8 @@ function isRetryableAppRuntimeAction(
719
765
  action === 'release_runtime_step_receipt' ||
720
766
  action === 'save_results' ||
721
767
  action === 'skip_runtime_step_receipt' ||
722
- action === 'start_run'
768
+ action === 'start_run' ||
769
+ action === 'launch_play_async'
723
770
  );
724
771
  }
725
772
 
@@ -1073,7 +1120,8 @@ export class AppRuntimeApiResponseError extends Error {
1073
1120
  this.requestId = input.requestId?.trim() || null;
1074
1121
  this.retryable = input.retryable;
1075
1122
  this.retryAfterMs =
1076
- typeof input.retryAfterMs === 'number' && Number.isFinite(input.retryAfterMs)
1123
+ typeof input.retryAfterMs === 'number' &&
1124
+ Number.isFinite(input.retryAfterMs)
1077
1125
  ? Math.max(0, Math.floor(input.retryAfterMs))
1078
1126
  : null;
1079
1127
  this.detail = input.detail;
@@ -1963,16 +2011,14 @@ export async function appendRunEventsViaAppRuntime(
1963
2011
  let terminalBatchIndex = -1;
1964
2012
  for (let index = batches.length - 1; index >= 0; index -= 1) {
1965
2013
  if (
1966
- batches[index]!.some(
1967
- (event) => {
1968
- const key = event.key ?? event.type;
1969
- return (
1970
- key === 'run.completed' ||
1971
- key === 'run.failed' ||
1972
- key === 'run.cancelled'
1973
- );
1974
- },
1975
- )
2014
+ batches[index]!.some((event) => {
2015
+ const key = event.key ?? event.type;
2016
+ return (
2017
+ key === 'run.completed' ||
2018
+ key === 'run.failed' ||
2019
+ key === 'run.cancelled'
2020
+ );
2021
+ })
1976
2022
  ) {
1977
2023
  terminalBatchIndex = index;
1978
2024
  break;
@@ -2021,6 +2067,19 @@ export async function startRunViaAppRuntime(
2021
2067
  });
2022
2068
  }
2023
2069
 
2070
+ export async function projectRunCreatedViaAppRuntime(
2071
+ context: WorkerRuntimeApiContext,
2072
+ input: Omit<
2073
+ Extract<RuntimeApiRequest, { action: 'project_run_created' }>,
2074
+ 'action'
2075
+ >,
2076
+ ): Promise<void> {
2077
+ await postAppRuntimeApi<{ ok: true; status: 'queued' }>(context, {
2078
+ action: 'project_run_created',
2079
+ ...input,
2080
+ });
2081
+ }
2082
+
2024
2083
  export async function recordFirstClaimLatencyViaAppRuntime(
2025
2084
  context: WorkerRuntimeApiContext,
2026
2085
  input: { runId: string; firstClaimLatencyMs: number },
@@ -2031,6 +2090,25 @@ export async function recordFirstClaimLatencyViaAppRuntime(
2031
2090
  });
2032
2091
  }
2033
2092
 
2093
+ export async function launchPlayAsyncViaAppRuntime(
2094
+ context: WorkerRuntimeApiContext,
2095
+ input: {
2096
+ key: string;
2097
+ invocationKey: string;
2098
+ playRef: string;
2099
+ input: Record<string, unknown>;
2100
+ description: string;
2101
+ schedulerSchema?: string | null;
2102
+ ancestryPlayIds: readonly string[];
2103
+ },
2104
+ ): Promise<AsyncPlayRunRef> {
2105
+ return await postAppRuntimeApi<AsyncPlayRunRef>(context, {
2106
+ action: 'launch_play_async',
2107
+ ...input,
2108
+ ancestryPlayIds: [...input.ancestryPlayIds],
2109
+ });
2110
+ }
2111
+
2034
2112
  export async function saveResultsViaAppRuntime(
2035
2113
  context: WorkerRuntimeApiContext,
2036
2114
  input: RuntimeSaveResults,
@@ -0,0 +1,78 @@
1
+ import {
2
+ flattenStaticPipeline,
3
+ type PlayStaticPipeline,
4
+ } from '../plays/static-pipeline';
5
+ import { SHARED_EXECUTION_POLICY } from './governor/policy';
6
+
7
+ export const CTX_RUN_PLAY_ASYNC_TARGET_UNRESOLVED =
8
+ 'CTX_RUN_PLAY_ASYNC_TARGET_UNRESOLVED';
9
+ export const CTX_RUN_PLAY_ASYNC_DATASET_UNSUPPORTED =
10
+ 'CTX_RUN_PLAY_ASYNC_DATASET_UNSUPPORTED';
11
+ export const CTX_RUN_PLAY_ASYNC_RECURSIVE = 'CTX_RUN_PLAY_ASYNC_RECURSIVE';
12
+ export const CTX_RUN_PLAY_ASYNC_DEPTH_EXCEEDED =
13
+ 'CTX_RUN_PLAY_ASYNC_DEPTH_EXCEEDED';
14
+ export const MAX_ASYNC_PLAY_CALL_DEPTH =
15
+ SHARED_EXECUTION_POLICY.budgets.maxPlayCallDepth;
16
+
17
+ /**
18
+ * Assert that one independently scheduled Play closure may be admitted.
19
+ *
20
+ * Async children may suspend for sleep/HITL, but never own a Dataset, CSV, or
21
+ * Runtime Sheet. The checker and runtime both call this function so the same
22
+ * authored target cannot pass publish and fail differently at execution.
23
+ */
24
+ export function assertAsyncPlayInvocation(input: {
25
+ pipeline: PlayStaticPipeline | null | undefined;
26
+ childPlayName?: string | null;
27
+ }): void {
28
+ const childPlayName = input.childPlayName?.trim() || 'child';
29
+ if (!input.pipeline) {
30
+ throw new Error(
31
+ `${CTX_RUN_PLAY_ASYNC_TARGET_UNRESOLVED}: ctx.runPlayAsync("${childPlayName}") requires a statically resolved published Play contract. Publish the target with the current Deepline CLI before launching it.`,
32
+ );
33
+ }
34
+
35
+ const steps = flattenStaticPipeline(input.pipeline);
36
+ if (
37
+ input.pipeline.tableNamespace ||
38
+ input.pipeline.sheetContract ||
39
+ steps.some((step) => step.type === 'dataset' || step.type === 'csv')
40
+ ) {
41
+ throw new Error(
42
+ `${CTX_RUN_PLAY_ASYNC_DATASET_UNSUPPORTED}: ctx.runPlayAsync("${childPlayName}") launches one independent scalar or HITL Play Run, but the target owns ctx.dataset(), ctx.csv(), or a Runtime Sheet. Keep batch work in its top-level Play or extract a scalar per-record child.`,
43
+ );
44
+ }
45
+
46
+ }
47
+
48
+ /** Admit a child against the persisted root-to-parent Play lineage. */
49
+ export function admitAsyncPlayLineage(input: {
50
+ ancestryPlayIds: readonly string[];
51
+ childPlayName: string;
52
+ }): Readonly<{ ancestryPlayIds: readonly string[]; callDepth: number }> {
53
+ const childPlayName = input.childPlayName.trim();
54
+ const ancestryPlayIds = input.ancestryPlayIds
55
+ .map((playId) => playId.trim())
56
+ .filter(Boolean);
57
+ if (ancestryPlayIds.includes(childPlayName)) {
58
+ throw new Error(
59
+ `${CTX_RUN_PLAY_ASYNC_RECURSIVE}: Recursive play graph detected: ${[
60
+ ...ancestryPlayIds,
61
+ childPlayName,
62
+ ].join(' -> ')}`,
63
+ );
64
+ }
65
+ // The lineage includes the root Play, while call depth counts child edges.
66
+ // Appending this child therefore makes its depth equal to the current
67
+ // lineage length: [root] -> child is depth 1, not depth 2.
68
+ const callDepth = ancestryPlayIds.length;
69
+ if (callDepth > MAX_ASYNC_PLAY_CALL_DEPTH) {
70
+ throw new Error(
71
+ `${CTX_RUN_PLAY_ASYNC_DEPTH_EXCEEDED}: Play-call depth exceeded (${callDepth}/${MAX_ASYNC_PLAY_CALL_DEPTH}).`,
72
+ );
73
+ }
74
+ return {
75
+ ancestryPlayIds: [...ancestryPlayIds, childPlayName],
76
+ callDepth,
77
+ };
78
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Durable checkpoint boundary kinds — the one list every checkpoint reader
3
+ * narrows against.
4
+ *
5
+ * Compatibility contract (`docs/runtime-compatibility-contract.md`): a parked
6
+ * run's checkpoint is written by one build and read by a newer-or-same build.
7
+ * Adding a boundary KIND is therefore not an additive change: a build that does
8
+ * not know the kind falls through every `existing?.kind === '...'` narrow and
9
+ * silently re-arms the wait or re-executes the side effect the boundary already
10
+ * resolved. That is a duplicate durable wait or a duplicate external effect,
11
+ * with no trace of what happened.
12
+ *
13
+ * So an unknown kind FAILS LOUD here instead. Recovery is roll-forward: deploy a
14
+ * build that understands the kind, and the parked run resumes.
15
+ */
16
+ import type { PlayCheckpoint } from './ctx-types';
17
+
18
+ /** One entry of `PlayCheckpoint.resolvedBoundaries`. */
19
+ export type PlayResolvedBoundary = NonNullable<
20
+ PlayCheckpoint['resolvedBoundaries']
21
+ >[string];
22
+
23
+ /** Every boundary kind this build can replay. */
24
+ export const PLAY_RESOLVED_BOUNDARY_KINDS = [
25
+ 'sleep',
26
+ 'integration_event',
27
+ 'fetch',
28
+ 'step',
29
+ ] as const satisfies readonly PlayResolvedBoundary['kind'][];
30
+
31
+ /**
32
+ * Compile fence in the other direction: adding a kind to `PlayCheckpoint`
33
+ * without listing it above resolves to `never` and fails the build, rather than
34
+ * shipping a kind that every reader would then reject at runtime.
35
+ */
36
+ type UnlistedBoundaryKind = Exclude<
37
+ PlayResolvedBoundary['kind'],
38
+ (typeof PLAY_RESOLVED_BOUNDARY_KINDS)[number]
39
+ >;
40
+ const ALL_BOUNDARY_KINDS_LISTED: UnlistedBoundaryKind extends never
41
+ ? true
42
+ : never = true;
43
+ void ALL_BOUNDARY_KINDS_LISTED;
44
+
45
+ /**
46
+ * Return the checkpoint entry for `boundaryId`, or throw when it carries a kind
47
+ * this build cannot replay. Absent (`undefined`/`null`) stays absent — an
48
+ * unresolved boundary is normal and simply re-arms.
49
+ */
50
+ export function assertKnownResolvedBoundary(
51
+ boundaryId: string,
52
+ entry: PlayResolvedBoundary | null | undefined,
53
+ ): PlayResolvedBoundary | undefined {
54
+ if (entry === null || entry === undefined) return undefined;
55
+ const kind = (entry as { kind?: unknown }).kind;
56
+ if (
57
+ typeof kind !== 'string' ||
58
+ !(PLAY_RESOLVED_BOUNDARY_KINDS as readonly string[]).includes(kind)
59
+ ) {
60
+ throw new Error(
61
+ `Play checkpoint boundary "${boundaryId}" is resolved with unknown kind ` +
62
+ `"${String(kind)}". This build only replays ` +
63
+ `${PLAY_RESOLVED_BOUNDARY_KINDS.join(', ')}. The checkpoint was written ` +
64
+ `by a newer runtime build; continuing would re-arm the wait or re-run ` +
65
+ `the effect this boundary already resolved. Roll forward to a build ` +
66
+ `that understands "${String(kind)}".`,
67
+ );
68
+ }
69
+ return entry;
70
+ }