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.
- package/dist/bundling-sources/sdk/src/client.ts +534 -4
- package/dist/bundling-sources/sdk/src/config.ts +77 -0
- package/dist/bundling-sources/sdk/src/http.ts +76 -30
- package/dist/bundling-sources/sdk/src/index.ts +6 -0
- package/dist/bundling-sources/sdk/src/monitor-fleet-contract.ts +1 -1
- package/dist/bundling-sources/sdk/src/play.ts +15 -1
- package/dist/bundling-sources/sdk/src/plays/bundle-play-file.ts +2 -2
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/sdk/src/types.ts +83 -4
- package/dist/bundling-sources/shared_libs/integration-contracts/AGENTS.md +9 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/README.md +3 -0
- package/dist/bundling-sources/shared_libs/integration-contracts/index.ts +2 -0
- package/dist/bundling-sources/shared_libs/monitors/analytics-install-guides.ts +77 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/charges.ts +125 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/policy-builders.ts +686 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/pricing.ts +54 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/public-pricing.ts +72 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/session.ts +45 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/state.ts +454 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/tamradar.ts +260 -0
- package/dist/bundling-sources/shared_libs/monitors/billing/types.ts +215 -0
- package/dist/bundling-sources/shared_libs/monitors/callback-security.ts +333 -0
- package/dist/bundling-sources/shared_libs/monitors/cursor-page.ts +42 -0
- package/dist/bundling-sources/shared_libs/monitors/deactivation-reasons.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/framework-managed-payload-fields.ts +71 -0
- package/dist/bundling-sources/shared_libs/monitors/generated/provider-monitor-callback-admission-targets.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/http-error-response.ts +267 -0
- package/dist/bundling-sources/shared_libs/monitors/inbound-publish-key.ts +39 -0
- package/dist/bundling-sources/shared_libs/monitors/inbound-queue.ts +82 -0
- package/dist/bundling-sources/shared_libs/monitors/lifecycle-notifications.ts +473 -0
- package/dist/bundling-sources/shared_libs/monitors/org-monitor-limits.ts +1 -1
- package/dist/bundling-sources/shared_libs/monitors/package.json +29 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-callback-verification.ts +1125 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-batch-operation.ts +263 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-capability.ts +964 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-consumer-health.ts +56 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-errors.ts +131 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-identity-claims.ts +535 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-legacy-aliases.ts +16 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-priority-execution.ts +56 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-public-aliases.ts +28 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-runtime-read-eligibility.ts +38 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-state.ts +122 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-status.ts +10 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-monitor-upstream-identity.ts +112 -0
- package/dist/bundling-sources/shared_libs/monitors/provider-webhook-monitor-runtime.ts +300 -0
- package/dist/bundling-sources/shared_libs/monitors/quickstart-prompts.ts +22 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-install-validation.ts +93 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-ip2company.ts +332 -0
- package/dist/bundling-sources/shared_libs/monitors/snitcher-radar.ts +221 -0
- package/dist/bundling-sources/shared_libs/monitors/starter-templates.ts +105 -0
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-guidance.ts +73 -0
- package/dist/bundling-sources/shared_libs/monitors/tracking-provider-integrations.ts +81 -0
- package/dist/bundling-sources/shared_libs/monitors/tsconfig.json +10 -0
- package/dist/bundling-sources/shared_libs/play-runtime/activity-observation.ts +6 -11
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +90 -12
- package/dist/bundling-sources/shared_libs/play-runtime/async-play-invocation.ts +78 -0
- package/dist/bundling-sources/shared_libs/play-runtime/checkpoint-boundaries.ts +70 -0
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +407 -53
- package/dist/bundling-sources/shared_libs/play-runtime/coordinator-headers.ts +1 -32
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +57 -0
- package/dist/bundling-sources/shared_libs/play-runtime/default-batch-strategies.ts +20 -1
- package/dist/bundling-sources/shared_libs/play-runtime/execution-capabilities.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/execution-protocol.ts +7 -1
- package/dist/bundling-sources/shared_libs/play-runtime/lane-retirement-gate.ts +189 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-runtime-semantics.ts +28 -0
- package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-failure.ts +23 -0
- package/dist/bundling-sources/shared_libs/play-runtime/run-snapshot-stream.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +18 -4
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-start-admission.ts +68 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +2 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runtime-sandbox-reconciliation.ts +1 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +10 -8
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-capacity-policy.ts +20 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-scheduler-topology.ts +24 -0
- package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +30 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-http-errors.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/tool-result.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +6 -3
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +454 -17
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +19 -4
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +6 -14
- package/dist/bundling-sources/shared_libs/plays/core.ts +11 -6
- package/dist/bundling-sources/shared_libs/plays/docflow-binding-owner.ts +16 -11
- package/dist/bundling-sources/shared_libs/plays/email-status.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/resolve-static-pipeline.ts +1 -1
- package/dist/bundling-sources/shared_libs/plays/slug.ts +115 -0
- package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +44 -14
- package/dist/bundling-sources/shared_libs/plays/tool-category-descriptions.ts +2 -2
- package/dist/bundling-sources/shared_libs/product-notifications/catalog.ts +877 -0
- package/dist/bundling-sources/shared_libs/product-notifications/configuration-draft.ts +456 -0
- package/dist/bundling-sources/shared_libs/product-notifications/configuration.ts +560 -0
- package/dist/bundling-sources/shared_libs/product-notifications/content.ts +28 -0
- package/dist/bundling-sources/shared_libs/product-notifications/default-policy.ts +59 -0
- package/dist/bundling-sources/shared_libs/product-notifications/email.ts +246 -0
- package/dist/bundling-sources/shared_libs/product-notifications/evaluation.ts +280 -0
- package/dist/bundling-sources/shared_libs/product-notifications/events.ts +433 -0
- package/dist/bundling-sources/shared_libs/product-notifications/legacy-slack.ts +80 -0
- package/dist/bundling-sources/shared_libs/product-notifications/workspace.ts +38 -0
- package/dist/bundling-sources/shared_libs/runtime-env.ts +6 -0
- package/dist/bundling-sources/shared_libs/security/header-safe-env.ts +28 -0
- package/dist/bundling-sources/shared_libs/security/internal-actor.ts +50 -0
- package/dist/bundling-sources/shared_libs/security/secret-redaction.ts +267 -0
- package/dist/cli/index.js +1070 -193
- package/dist/cli/index.mjs +1057 -180
- package/dist/{compiler-manifest-Dbov16F7.d.mts → compiler-manifest-DsLbQaew.d.mts} +132 -8
- package/dist/{compiler-manifest-Dbov16F7.d.ts → compiler-manifest-DsLbQaew.d.ts} +132 -8
- package/dist/index.d.mts +834 -12
- package/dist/index.d.ts +834 -12
- package/dist/index.js +469 -40
- package/dist/index.mjs +469 -40
- package/dist/install-integrity.json +65 -4
- package/dist/plays/bundle-play-file.d.mts +8 -3
- package/dist/plays/bundle-play-file.d.ts +8 -3
- package/dist/plays/bundle-play-file.mjs +100 -20
- package/package.json +3 -1
- /package/dist/bundling-sources/shared_libs/{integrations/bettercontact-execution-policy.ts → integration-contracts/bettercontact/execution-policy.ts} +0 -0
- /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
|
+
}
|
|
@@ -101,7 +101,11 @@ export type PlayActivityState =
|
|
|
101
101
|
};
|
|
102
102
|
|
|
103
103
|
export type PlayActivityObservation = {
|
|
104
|
-
|
|
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' &&
|
|
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
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
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
|
+
}
|