deepline 0.2.13 → 0.2.15
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/index.ts +3 -0
- package/dist/bundling-sources/sdk/src/play.ts +150 -691
- package/dist/bundling-sources/sdk/src/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/child-execution-strategy.ts +7 -1
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +249 -51
- package/dist/bundling-sources/shared_libs/play-runtime/csv-rename.ts +10 -6
- package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +32 -51
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts +11 -22
- package/dist/bundling-sources/shared_libs/play-runtime/durable-call-policy.ts +34 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-call-execution.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/run-ledger-projection-contract.ts +95 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +11 -6
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-receipt-store-adapter.ts +38 -9
- package/dist/bundling-sources/shared_libs/play-runtime/secret-capability.ts +23 -15
- package/dist/bundling-sources/shared_libs/plays/artifact-types.ts +3 -0
- package/dist/bundling-sources/shared_libs/plays/authoring-contract.ts +2222 -0
- package/dist/bundling-sources/shared_libs/plays/bundling/index.ts +3 -2
- package/dist/bundling-sources/shared_libs/plays/compiler-manifest.ts +2 -0
- package/dist/bundling-sources/shared_libs/plays/contracts.ts +16 -0
- package/dist/bundling-sources/shared_libs/plays/input-contract-definition.ts +28 -0
- package/dist/bundling-sources/shared_libs/plays/input-contract.ts +3 -3
- package/dist/cli/index.js +5074 -829
- package/dist/cli/index.mjs +5019 -759
- package/dist/compiler-manifest-xFkbJX2B.d.mts +2517 -0
- package/dist/compiler-manifest-xFkbJX2B.d.ts +2517 -0
- package/dist/index.d.mts +36 -1011
- package/dist/index.d.ts +36 -1011
- package/dist/index.js +25 -7
- package/dist/index.mjs +25 -7
- package/dist/plays/bundle-play-file.d.mts +5 -8
- package/dist/plays/bundle-play-file.d.ts +5 -8
- package/dist/plays/bundle-play-file.mjs +3844 -3
- package/package.json +1 -1
- package/dist/bundling-sources/shared_libs/plays/source-metadata.ts +0 -240
- package/dist/tool-execution-error-4-rhemLQ.d.mts +0 -446
- package/dist/tool-execution-error-4-rhemLQ.d.ts +0 -446
|
@@ -3,6 +3,18 @@ import type { PlayBundleArtifact } from '../plays/artifact-types';
|
|
|
3
3
|
import type { PlayRunContractSnapshot } from '../plays/contracts';
|
|
4
4
|
import type { PlayStructuredDefinition } from '../plays/definition';
|
|
5
5
|
import type { PlayStaticPipeline } from '../plays/static-pipeline';
|
|
6
|
+
import type {
|
|
7
|
+
DurableCallStaleAfterSeconds,
|
|
8
|
+
PlayAuthoringCallOptions,
|
|
9
|
+
PlayAuthoringCsvOptions,
|
|
10
|
+
PlayAuthoringFetchOptions,
|
|
11
|
+
PlayAuthoringRuntimeStepOptions,
|
|
12
|
+
PlayAuthoringContractEdition,
|
|
13
|
+
PlayToolCallOptions,
|
|
14
|
+
PlayToolExecutionRequest,
|
|
15
|
+
PlayReceiptWaitMs,
|
|
16
|
+
PlayRuntimeTimeoutMs,
|
|
17
|
+
} from '../plays/authoring-contract';
|
|
6
18
|
import type {
|
|
7
19
|
PlayDataset,
|
|
8
20
|
PlayDatasetInput,
|
|
@@ -208,14 +220,9 @@ export interface HeartbeatRuntimeStepReceiptsInput {
|
|
|
208
220
|
leaseIds?: string[];
|
|
209
221
|
}
|
|
210
222
|
|
|
211
|
-
export
|
|
212
|
-
description?: string;
|
|
213
|
-
columns?: Record<string, string | readonly string[]>;
|
|
214
|
-
rename?: Record<string, string | readonly string[]>;
|
|
215
|
-
required?: readonly string[];
|
|
216
|
-
}
|
|
223
|
+
export type CsvOptions = PlayAuthoringCsvOptions;
|
|
217
224
|
|
|
218
|
-
export interface
|
|
225
|
+
export interface RuntimeDatasetOptions<TItem = Record<string, unknown>> {
|
|
219
226
|
description?: string;
|
|
220
227
|
/**
|
|
221
228
|
* Optional relative cache window for intentional reruns.
|
|
@@ -270,58 +277,30 @@ export interface DatasetOptions<TItem = Record<string, unknown>> {
|
|
|
270
277
|
mode?: 'upsert' | 'net_new';
|
|
271
278
|
}
|
|
272
279
|
|
|
273
|
-
export type
|
|
274
|
-
|
|
275
|
-
'description'
|
|
276
|
-
>;
|
|
280
|
+
export type RuntimeDatasetDefinitionOptions<TItem = Record<string, unknown>> =
|
|
281
|
+
Omit<RuntimeDatasetOptions<TItem>, 'description'>;
|
|
277
282
|
|
|
278
|
-
export type
|
|
279
|
-
|
|
283
|
+
export type RuntimeDatasetRunOptions<TItem = Record<string, unknown>> = Pick<
|
|
284
|
+
RuntimeDatasetOptions<TItem>,
|
|
280
285
|
'description' | 'key' | 'onRowError' | 'mode'
|
|
281
286
|
>;
|
|
282
287
|
|
|
283
|
-
export
|
|
284
|
-
|
|
285
|
-
force?: boolean;
|
|
286
|
-
staleAfterSeconds?: number;
|
|
287
|
-
timeoutMs?: number;
|
|
288
|
-
receiptWaitMs?: number;
|
|
289
|
-
}
|
|
288
|
+
export type ToolCallOptions = PlayToolCallOptions;
|
|
289
|
+
export type ToolExecutionRequest = PlayToolExecutionRequest;
|
|
290
290
|
|
|
291
|
-
export
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
force?: boolean;
|
|
297
|
-
staleAfterSeconds?: number;
|
|
298
|
-
timeoutMs?: number;
|
|
299
|
-
receiptWaitMs?: number;
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
export interface PlayCallOptions {
|
|
303
|
-
description?: string;
|
|
304
|
-
/**
|
|
305
|
-
* `child-workflow` is accepted only so the checker/runtime can emit the
|
|
306
|
-
* canonical CTX_RUN_PLAY_INLINE_ONLY migration diagnostic. It never starts a
|
|
307
|
-
* child workflow.
|
|
308
|
-
*/
|
|
291
|
+
export type PlayCallOptions = Omit<
|
|
292
|
+
PlayAuthoringCallOptions,
|
|
293
|
+
'execution' | 'timeoutMs'
|
|
294
|
+
> & {
|
|
295
|
+
/** Legacy invalid spelling retained only for the stable migration error. */
|
|
309
296
|
execution?: PlayCallExecution | 'child-workflow';
|
|
310
|
-
/**
|
|
311
|
-
* Parsed so source preflight and an untyped runtime call can return the
|
|
312
|
-
* canonical CTX_RUN_PLAY_INLINE_ONLY migration error. It is never honored.
|
|
313
|
-
*/
|
|
297
|
+
/** Legacy invalid option retained only for the stable migration error. */
|
|
314
298
|
timeoutMs?: number;
|
|
315
|
-
}
|
|
299
|
+
};
|
|
316
300
|
|
|
317
|
-
export
|
|
318
|
-
semanticKey?: string;
|
|
319
|
-
staleAfterSeconds?: number;
|
|
320
|
-
}
|
|
301
|
+
export type RuntimeStepOptions = PlayAuthoringRuntimeStepOptions;
|
|
321
302
|
|
|
322
|
-
export
|
|
323
|
-
staleAfterSeconds?: number;
|
|
324
|
-
}
|
|
303
|
+
export type FetchOptions = PlayAuthoringFetchOptions;
|
|
325
304
|
|
|
326
305
|
export interface ResolvedPlayExecution {
|
|
327
306
|
playId: string;
|
|
@@ -502,6 +481,8 @@ export type IntegrationEventWaitHandler = {
|
|
|
502
481
|
export interface ContextOptions {
|
|
503
482
|
/** Immutable logical and physical execution identity for this context. */
|
|
504
483
|
executionScope?: RunExecutionScope;
|
|
484
|
+
/** Authoring semantics pinned by the immutable artifact. */
|
|
485
|
+
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
505
486
|
/** Error shape pinned by the immutable play artifact; missing preserves legacy schema 0. */
|
|
506
487
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
507
488
|
/** Short-lived HMAC-signed internal token for tool callbacks. Required for cloud execution. */
|
|
@@ -589,7 +570,7 @@ export interface ContextOptions {
|
|
|
589
570
|
staticPipeline?: PlayStaticPipeline | null;
|
|
590
571
|
forceRefresh?: boolean;
|
|
591
572
|
inputOffset?: number;
|
|
592
|
-
mode?:
|
|
573
|
+
mode?: RuntimeDatasetRunOptions['mode'];
|
|
593
574
|
},
|
|
594
575
|
) => Promise<MapStartResult>;
|
|
595
576
|
/**
|
|
@@ -6,40 +6,29 @@ import {
|
|
|
6
6
|
// packed SDK's dist/bundling-sources graph, where only relative imports
|
|
7
7
|
// resolve.
|
|
8
8
|
} from '../plays/row-identity';
|
|
9
|
+
import { resolveDurableCallCachePolicy } from './durable-call-policy';
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
DURABLE_CALL_STALE_AFTER_SECONDS_ERROR,
|
|
13
|
+
resolveDurableCallCachePolicy,
|
|
14
|
+
} from './durable-call-policy';
|
|
15
|
+
export type { DurableCallCachePolicy } from './durable-call-policy';
|
|
9
16
|
|
|
10
17
|
export const DURABLE_CALL_CACHE_POLICY_VERSION = 'call-cache-v1';
|
|
11
18
|
|
|
12
19
|
export type DurableCallKind = 'tool' | 'step' | 'fetch';
|
|
13
20
|
|
|
14
|
-
function validateStaleAfterSeconds(staleAfterSeconds?: number | null): void {
|
|
15
|
-
if (staleAfterSeconds === undefined || staleAfterSeconds === null) {
|
|
16
|
-
return;
|
|
17
|
-
}
|
|
18
|
-
if (
|
|
19
|
-
!Number.isFinite(staleAfterSeconds) ||
|
|
20
|
-
!Number.isInteger(staleAfterSeconds) ||
|
|
21
|
-
staleAfterSeconds <= 0
|
|
22
|
-
) {
|
|
23
|
-
throw new Error(
|
|
24
|
-
'staleAfterSeconds must be a positive whole number of seconds.',
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
21
|
export function durableCacheStaleBucket(input: {
|
|
30
22
|
staleAfterSeconds?: number | null;
|
|
31
23
|
nowMs?: number;
|
|
32
24
|
}): string | null {
|
|
33
|
-
|
|
34
|
-
if (
|
|
35
|
-
input.staleAfterSeconds === undefined ||
|
|
36
|
-
input.staleAfterSeconds === null
|
|
37
|
-
) {
|
|
25
|
+
const policy = resolveDurableCallCachePolicy(input.staleAfterSeconds);
|
|
26
|
+
if (policy.staleAfterSeconds === null) {
|
|
38
27
|
return null;
|
|
39
28
|
}
|
|
40
29
|
const nowMs = input.nowMs ?? Date.now();
|
|
41
|
-
return `${
|
|
42
|
-
nowMs / (
|
|
30
|
+
return `${policy.staleAfterSeconds}:${Math.floor(
|
|
31
|
+
nowMs / (policy.staleAfterSeconds * 1000),
|
|
43
32
|
)}`;
|
|
44
33
|
}
|
|
45
34
|
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PLAY_AUTHORING_FIELD_REGISTRY,
|
|
3
|
+
validatePlayAuthoringField,
|
|
4
|
+
type PlayAuthoringFieldPath,
|
|
5
|
+
} from '../plays/authoring-contract';
|
|
6
|
+
|
|
7
|
+
export const DURABLE_CALL_STALE_AFTER_SECONDS_ERROR =
|
|
8
|
+
PLAY_AUTHORING_FIELD_REGISTRY['ctx.tools.execute.staleAfterSeconds']
|
|
9
|
+
.errorMessage;
|
|
10
|
+
|
|
11
|
+
export type DurableCallCachePolicy = {
|
|
12
|
+
forceRefresh: boolean;
|
|
13
|
+
staleAfterSeconds: number | null;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
/** Normalize the public freshness contract shared by durable calls. */
|
|
17
|
+
export function resolveDurableCallCachePolicy(
|
|
18
|
+
staleAfterSeconds?: number | null,
|
|
19
|
+
path: Extract<
|
|
20
|
+
PlayAuthoringFieldPath,
|
|
21
|
+
| 'ctx.tools.execute.staleAfterSeconds'
|
|
22
|
+
| 'ctx.step.staleAfterSeconds'
|
|
23
|
+
| 'ctx.fetch.staleAfterSeconds'
|
|
24
|
+
> = 'ctx.tools.execute.staleAfterSeconds',
|
|
25
|
+
): DurableCallCachePolicy {
|
|
26
|
+
if (staleAfterSeconds === undefined || staleAfterSeconds === null) {
|
|
27
|
+
return { forceRefresh: false, staleAfterSeconds: null };
|
|
28
|
+
}
|
|
29
|
+
if (staleAfterSeconds === 0) {
|
|
30
|
+
return { forceRefresh: true, staleAfterSeconds: null };
|
|
31
|
+
}
|
|
32
|
+
validatePlayAuthoringField(path, staleAfterSeconds);
|
|
33
|
+
return { forceRefresh: false, staleAfterSeconds };
|
|
34
|
+
}
|
|
@@ -3,4 +3,5 @@
|
|
|
3
3
|
* recognizes the historical `child-workflow` spelling so preflight can return
|
|
4
4
|
* CTX_RUN_PLAY_INLINE_ONLY, but it is no longer a supported runtime option.
|
|
5
5
|
*/
|
|
6
|
-
export type PlayCallExecution = 'inline'
|
|
6
|
+
export type PlayCallExecution = Extract<PlayAuthoringCallExecution, 'inline'>;
|
|
7
|
+
import type { PlayAuthoringCallExecution } from '../plays/authoring-contract';
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire contract for idempotent Runtime Postgres -> Convex Run Ledger delivery.
|
|
3
|
+
*
|
|
4
|
+
* Producers must use these builders and API boundaries must use these
|
|
5
|
+
* validators. Keeping the format here prevents the scheduler and runtime route
|
|
6
|
+
* from admitting different lifecycle-event keys.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const UUID_PATTERN =
|
|
10
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
11
|
+
const SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;
|
|
12
|
+
|
|
13
|
+
function requireRunId(runId: string): void {
|
|
14
|
+
if (!runId.trim()) {
|
|
15
|
+
throw new Error('Run Ledger projection idempotency key requires a run id.');
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function requireDeliveryKey(deliveryKey: string): void {
|
|
20
|
+
if (!UUID_PATTERN.test(deliveryKey)) {
|
|
21
|
+
throw new Error(
|
|
22
|
+
'Run Ledger projection delivery key must be a canonical UUID.',
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function buildRunLedgerStartIdempotencyKey(input: {
|
|
28
|
+
runId: string;
|
|
29
|
+
deliveryKey: string;
|
|
30
|
+
}): string {
|
|
31
|
+
requireRunId(input.runId);
|
|
32
|
+
requireDeliveryKey(input.deliveryKey);
|
|
33
|
+
return `run-started:${input.runId}:${input.deliveryKey}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function buildRunLedgerTerminalIdempotencyKey(input: {
|
|
37
|
+
runId: string;
|
|
38
|
+
deliveryKey: string;
|
|
39
|
+
}): string {
|
|
40
|
+
requireRunId(input.runId);
|
|
41
|
+
requireDeliveryKey(input.deliveryKey);
|
|
42
|
+
return `run-terminal:${input.runId}:${input.deliveryKey}`;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Compatibility key for the one-row projector. The `run-terminal` prefix was
|
|
47
|
+
* historically used for every non-start row, including lifecycle events, so
|
|
48
|
+
* changing it during a retry could append the same fact twice across deploys.
|
|
49
|
+
*/
|
|
50
|
+
export function buildRunLedgerSingleEventIdempotencyKey(input: {
|
|
51
|
+
runId: string;
|
|
52
|
+
deliveryKey: string;
|
|
53
|
+
}): string {
|
|
54
|
+
return buildRunLedgerTerminalIdempotencyKey(input);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function buildRunLedgerEventsIdempotencyKey(input: {
|
|
58
|
+
runId: string;
|
|
59
|
+
deliveryDigest: string;
|
|
60
|
+
}): string {
|
|
61
|
+
requireRunId(input.runId);
|
|
62
|
+
if (!SHA256_HEX_PATTERN.test(input.deliveryDigest)) {
|
|
63
|
+
throw new Error(
|
|
64
|
+
'Run Ledger projection delivery digest must be a SHA-256 hex value.',
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
return `run-events:${input.runId}:${input.deliveryDigest}`;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function isValidRunLedgerStartIdempotencyKey(input: {
|
|
71
|
+
runId: string;
|
|
72
|
+
idempotencyKey: string;
|
|
73
|
+
}): boolean {
|
|
74
|
+
const prefix = `run-started:${input.runId}:`;
|
|
75
|
+
return (
|
|
76
|
+
input.idempotencyKey.startsWith(prefix) &&
|
|
77
|
+
UUID_PATTERN.test(input.idempotencyKey.slice(prefix.length))
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function isValidRunLedgerAppendIdempotencyKey(input: {
|
|
82
|
+
runId: string;
|
|
83
|
+
idempotencyKey: string;
|
|
84
|
+
}): boolean {
|
|
85
|
+
const terminalPrefix = `run-terminal:${input.runId}:`;
|
|
86
|
+
if (input.idempotencyKey.startsWith(terminalPrefix)) {
|
|
87
|
+
return UUID_PATTERN.test(input.idempotencyKey.slice(terminalPrefix.length));
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const eventsPrefix = `run-events:${input.runId}:`;
|
|
91
|
+
return (
|
|
92
|
+
input.idempotencyKey.startsWith(eventsPrefix) &&
|
|
93
|
+
SHA256_HEX_PATTERN.test(input.idempotencyKey.slice(eventsPrefix.length))
|
|
94
|
+
);
|
|
95
|
+
}
|
|
@@ -5844,17 +5844,21 @@ export async function heartbeatRuntimeWorkReceipts(
|
|
|
5844
5844
|
JOIN unnest($3::text[]) WITH ORDINALITY AS lease_values(lease_id, ord)
|
|
5845
5845
|
ON lease_values.ord = key_values.ord
|
|
5846
5846
|
),
|
|
5847
|
+
unique_inputs AS (
|
|
5848
|
+
SELECT DISTINCT key_hex, lease_id
|
|
5849
|
+
FROM input_keys
|
|
5850
|
+
),
|
|
5847
5851
|
renewed AS (
|
|
5848
5852
|
UPDATE ${workReceiptTable(session)} AS target
|
|
5849
5853
|
SET lease_expires_at = now() + ($4::double precision * interval '1 millisecond'),
|
|
5850
5854
|
updated_at = now()
|
|
5851
|
-
FROM
|
|
5852
|
-
WHERE target.k = decode(
|
|
5855
|
+
FROM unique_inputs
|
|
5856
|
+
WHERE target.k = decode(unique_inputs.key_hex, 'hex')
|
|
5853
5857
|
AND ${workReceiptHeartbeatPredicateSql({
|
|
5854
5858
|
receiptTable: 'target',
|
|
5855
5859
|
ownerRunIdSql: '$2::text',
|
|
5856
5860
|
ownerRunAttemptSql: '$5',
|
|
5857
|
-
leaseIdSql: '
|
|
5861
|
+
leaseIdSql: 'unique_inputs.lease_id',
|
|
5858
5862
|
})}
|
|
5859
5863
|
RETURNING target.k,
|
|
5860
5864
|
target.status,
|
|
@@ -5867,8 +5871,7 @@ export async function heartbeatRuntimeWorkReceipts(
|
|
|
5867
5871
|
target.lease_owner_run_id,
|
|
5868
5872
|
target.lease_owner_attempt,
|
|
5869
5873
|
target.lease_expires_at,
|
|
5870
|
-
target.updated_at
|
|
5871
|
-
input_keys.ord
|
|
5874
|
+
target.updated_at
|
|
5872
5875
|
),
|
|
5873
5876
|
returned AS (
|
|
5874
5877
|
SELECT renewed.k,
|
|
@@ -5885,7 +5888,9 @@ export async function heartbeatRuntimeWorkReceipts(
|
|
|
5885
5888
|
renewed.updated_at,
|
|
5886
5889
|
input_keys.ord
|
|
5887
5890
|
FROM input_keys
|
|
5888
|
-
LEFT JOIN renewed
|
|
5891
|
+
LEFT JOIN renewed
|
|
5892
|
+
ON renewed.k = decode(input_keys.key_hex, 'hex')
|
|
5893
|
+
AND renewed.lease_id = input_keys.lease_id
|
|
5889
5894
|
)
|
|
5890
5895
|
SELECT convert_from(returned.k, 'UTF8') AS k,
|
|
5891
5896
|
returned.status,
|
|
@@ -25,7 +25,10 @@ import {
|
|
|
25
25
|
skipRuntimeStepReceiptViaAppRuntime,
|
|
26
26
|
type WorkerRuntimeApiContext,
|
|
27
27
|
} from './app-runtime-api';
|
|
28
|
-
import {
|
|
28
|
+
import {
|
|
29
|
+
RuntimeReceiptWriter,
|
|
30
|
+
RuntimeReceiptWriterResultCountError,
|
|
31
|
+
} from './runtime-receipt-writer';
|
|
29
32
|
|
|
30
33
|
type ReceiptOutput =
|
|
31
34
|
| RuntimeStepReceipt
|
|
@@ -490,17 +493,43 @@ async function sendReceiptCommands(input: {
|
|
|
490
493
|
ReceiptCommand,
|
|
491
494
|
{ kind: 'heartbeat' }
|
|
492
495
|
>[];
|
|
493
|
-
const
|
|
496
|
+
const uniqueCommands: (typeof commands)[number][] = [];
|
|
497
|
+
const uniqueIndexByIdentity = new Map<string, number>();
|
|
498
|
+
const originalToUniqueIndex = commands.map((command) => {
|
|
499
|
+
const identity = JSON.stringify([
|
|
500
|
+
command.input.key,
|
|
501
|
+
command.input.leaseId,
|
|
502
|
+
]);
|
|
503
|
+
const existingIndex = uniqueIndexByIdentity.get(identity);
|
|
504
|
+
if (existingIndex !== undefined) return existingIndex;
|
|
505
|
+
const uniqueIndex = uniqueCommands.length;
|
|
506
|
+
uniqueCommands.push(command);
|
|
507
|
+
uniqueIndexByIdentity.set(identity, uniqueIndex);
|
|
508
|
+
return uniqueIndex;
|
|
509
|
+
});
|
|
510
|
+
const leaseIds = uniqueCommands.map((command) => command.input.leaseId);
|
|
494
511
|
const sharedLeaseId = leaseIds.every((leaseId) => leaseId === leaseIds[0])
|
|
495
512
|
? leaseIds[0]
|
|
496
513
|
: undefined;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
514
|
+
const uniqueResults = await heartbeatRuntimeStepReceiptsViaAppRuntime(
|
|
515
|
+
input.context,
|
|
516
|
+
{
|
|
517
|
+
playName: input.playName,
|
|
518
|
+
runId: first.input.runId,
|
|
519
|
+
runAttempt: first.input.runAttempt,
|
|
520
|
+
...(sharedLeaseId ? { leaseId: sharedLeaseId } : { leaseIds }),
|
|
521
|
+
keys: uniqueCommands.map((command) => command.input.key),
|
|
522
|
+
},
|
|
523
|
+
);
|
|
524
|
+
if (uniqueResults.length !== uniqueCommands.length) {
|
|
525
|
+
throw new RuntimeReceiptWriterResultCountError(
|
|
526
|
+
uniqueCommands.length,
|
|
527
|
+
uniqueResults.length,
|
|
528
|
+
);
|
|
529
|
+
}
|
|
530
|
+
return originalToUniqueIndex.map(
|
|
531
|
+
(uniqueIndex) => uniqueResults[uniqueIndex]!,
|
|
532
|
+
);
|
|
504
533
|
}
|
|
505
534
|
case 'acquire_execution_lock':
|
|
506
535
|
return [
|
|
@@ -1,28 +1,36 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PlaySecretAuth,
|
|
3
|
+
PlaySecretAwareRequestInit,
|
|
4
|
+
PlaySecretHandle,
|
|
5
|
+
} from '../plays/authoring-contract';
|
|
6
|
+
|
|
1
7
|
const SECRET_HANDLE_BRAND = Symbol.for('deepline.secret.handle');
|
|
2
8
|
const SECRET_AUTH_BRAND = Symbol.for('deepline.secret.auth');
|
|
3
9
|
const SECRET_HANDLE_MARKER_RE = /\[secret:[A-Z0-9_ -]+\]/i;
|
|
4
10
|
|
|
5
|
-
export type SecretHandle = {
|
|
11
|
+
export type SecretHandle = PlaySecretHandle & {
|
|
6
12
|
readonly [SECRET_HANDLE_BRAND]: true;
|
|
7
13
|
readonly name: string;
|
|
8
14
|
toString(): string;
|
|
9
15
|
toJSON(): never;
|
|
10
16
|
};
|
|
11
17
|
|
|
12
|
-
export type SecretAuth =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
export type SecretAuth = PlaySecretAuth &
|
|
19
|
+
(
|
|
20
|
+
| {
|
|
21
|
+
readonly [SECRET_AUTH_BRAND]: true;
|
|
22
|
+
readonly kind: 'bearer';
|
|
23
|
+
readonly secret: SecretHandle;
|
|
24
|
+
}
|
|
25
|
+
| {
|
|
26
|
+
readonly [SECRET_AUTH_BRAND]: true;
|
|
27
|
+
readonly kind: 'header';
|
|
28
|
+
readonly header: string;
|
|
29
|
+
readonly secret: SecretHandle;
|
|
30
|
+
}
|
|
31
|
+
);
|
|
24
32
|
|
|
25
|
-
export type SecretAwareRequestInit =
|
|
33
|
+
export type SecretAwareRequestInit = PlaySecretAwareRequestInit & {
|
|
26
34
|
auth?: SecretAuth;
|
|
27
35
|
};
|
|
28
36
|
|
|
@@ -70,7 +78,7 @@ export function createSecretHandle(name: string): SecretHandle {
|
|
|
70
78
|
`Secret ${name} cannot be serialized. Use an approved ctx.secrets helper.`,
|
|
71
79
|
);
|
|
72
80
|
},
|
|
73
|
-
};
|
|
81
|
+
} as unknown as SecretHandle;
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
export function createBearerSecretAuth(secret: SecretHandle): SecretAuth {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ToolExecutionErrorSchemaVersion } from '../tool-execution-error';
|
|
2
|
+
import type { PlayAuthoringContractEdition } from './authoring-contract';
|
|
2
3
|
|
|
3
4
|
export type PlayPackageImport = {
|
|
4
5
|
name: string;
|
|
@@ -25,6 +26,8 @@ export type PlayArtifactCompatibility = {
|
|
|
25
26
|
runtimeBackend?: string | null;
|
|
26
27
|
/** Missing preserves the legacy schema used before this field existed. */
|
|
27
28
|
toolErrorSchemaVersion?: ToolExecutionErrorSchemaVersion;
|
|
29
|
+
/** Missing preserves edition 1 for artifacts created before authoring contracts were pinned. */
|
|
30
|
+
authoringContractEdition?: PlayAuthoringContractEdition;
|
|
28
31
|
};
|
|
29
32
|
|
|
30
33
|
/** The only executable Play artifact contract. */
|