deepline 0.3.80 → 0.3.82
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/release.ts +1 -1
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +5 -3
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +60 -14
- package/dist/bundling-sources/shared_libs/play-runtime/durable-invocation-fence.ts +35 -0
- package/dist/bundling-sources/shared_libs/play-runtime/play-run-recovery-policy.ts +2 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +0 -5
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +15 -0
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +5 -3
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-contract.ts +29 -71
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-operation.ts +51 -0
- package/dist/cli/index.js +15 -2
- package/dist/cli/index.mjs +15 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/install-integrity.json +2 -0
- package/package.json +1 -1
|
@@ -199,7 +199,7 @@ export const SDK_RELEASE = {
|
|
|
199
199
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
200
200
|
// getters keep their established compatibility behavior.
|
|
201
201
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
202
|
-
version: '0.3.
|
|
202
|
+
version: '0.3.82',
|
|
203
203
|
updateSummary:
|
|
204
204
|
'Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.',
|
|
205
205
|
packageCapabilities: {
|
|
@@ -41,8 +41,8 @@ import type {
|
|
|
41
41
|
} from './/protocol';
|
|
42
42
|
import {
|
|
43
43
|
PLAY_RUNTIME_TRANSPORT_ATTEMPT_HEADER,
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_FORMAT,
|
|
45
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_HEADER,
|
|
46
46
|
} from './/runtime-contract';
|
|
47
47
|
import { PLAY_RUNTIME_API_COMPAT_PATH } from './/runtime-api-paths';
|
|
48
48
|
import {
|
|
@@ -1138,7 +1138,9 @@ async function postAppRuntimeApi<TResponse>(
|
|
|
1138
1138
|
headers: {
|
|
1139
1139
|
'content-type': 'application/json',
|
|
1140
1140
|
authorization: `Bearer ${token}`,
|
|
1141
|
-
[
|
|
1141
|
+
[LEGACY_RUNTIME_RECEIPT_WIRE_HEADER]: String(
|
|
1142
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_FORMAT,
|
|
1143
|
+
),
|
|
1142
1144
|
[PLAY_RUNTIME_TRANSPORT_ATTEMPT_HEADER]: transportAttemptId,
|
|
1143
1145
|
...vercelHeaders,
|
|
1144
1146
|
...(context.preferredReceiptGatewayMachineId?.trim()
|
|
@@ -64,6 +64,10 @@ import {
|
|
|
64
64
|
PLAY_RUNTIME_OPERATION_ATTEMPT_HEADER,
|
|
65
65
|
PLAY_RUNTIME_OPERATION_ID_HEADER,
|
|
66
66
|
} from './runtime-api-paths';
|
|
67
|
+
import {
|
|
68
|
+
DURABLE_INVOCATION_FENCE_VERSION,
|
|
69
|
+
durableInvocationFenceExecutePath,
|
|
70
|
+
} from './durable-invocation-fence';
|
|
67
71
|
import {
|
|
68
72
|
isRetryableSecretResolutionStatus,
|
|
69
73
|
secretResolutionRetryDecision,
|
|
@@ -1145,7 +1149,7 @@ function isUnmarkedExecutionGateway502(input: {
|
|
|
1145
1149
|
return false;
|
|
1146
1150
|
}
|
|
1147
1151
|
try {
|
|
1148
|
-
return new URL(input.url).pathname
|
|
1152
|
+
return /\/execute-fenced-v[12]$/.test(new URL(input.url).pathname);
|
|
1149
1153
|
} catch {
|
|
1150
1154
|
return false;
|
|
1151
1155
|
}
|
|
@@ -2110,6 +2114,7 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
2110
2114
|
*/
|
|
2111
2115
|
private readonly durableMappedToolResultsBackedByReceipts: boolean;
|
|
2112
2116
|
private readonly durableDirectToolResultsBackedByReceipts: boolean;
|
|
2117
|
+
private durableInvocationFenceVerification: Promise<boolean> | null = null;
|
|
2113
2118
|
private steps: PlayStep[] = [];
|
|
2114
2119
|
private explicitMapInvocationKeys = new Set<string>();
|
|
2115
2120
|
/** The map step currently being built — substeps go here instead of top-level. */
|
|
@@ -13452,17 +13457,11 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13452
13457
|
const uncachedAsyncLifecycleCall =
|
|
13453
13458
|
options?.uncachedAsyncLifecycleCall === true ||
|
|
13454
13459
|
shouldWaitForAsyncOperation;
|
|
13455
|
-
const usesDurableInvocationFence =
|
|
13456
|
-
requestsDurableInvocationFence && !uncachedAsyncLifecycleCall;
|
|
13457
|
-
const executeSuffix = usesDurableInvocationFence
|
|
13458
|
-
? 'execute-fenced-v1'
|
|
13459
|
-
: 'execute';
|
|
13460
13460
|
// Keep receipts, runner heartbeats, terminals, sheets, and runtime control
|
|
13461
13461
|
// on baseUrl (the receipt gateway). Only the potentially long-lived
|
|
13462
13462
|
// provider request may use the separately managed execution relay.
|
|
13463
13463
|
const executionBaseUrl =
|
|
13464
13464
|
this.#options.executionGatewayBaseUrl?.trim() || this.#options.baseUrl;
|
|
13465
|
-
const url = `${executionBaseUrl.replace(/\/$/, '')}/api/v2/integrations/${encodeURIComponent(toolId)}/${executeSuffix}`;
|
|
13466
13465
|
const toolErrorSchemaVersion = this.currentToolErrorSchemaVersion;
|
|
13467
13466
|
const timeoutMs = resolveToolRuntimeTimeoutMs(
|
|
13468
13467
|
toolId,
|
|
@@ -13551,6 +13550,49 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13551
13550
|
retryPolicy?.retrySafeTransientHttp === true;
|
|
13552
13551
|
const requiresExecutionFence =
|
|
13553
13552
|
retryPolicy?.requiresExecutionFence === true;
|
|
13553
|
+
// Fenced execution is an operation-specific opt-in. A gateway may
|
|
13554
|
+
// support execute-fenced-v2 while ordinary provider calls continue
|
|
13555
|
+
// through /execute with no durable-operation metadata at all.
|
|
13556
|
+
const usesDurableInvocationFence =
|
|
13557
|
+
requestsDurableInvocationFence &&
|
|
13558
|
+
requiresExecutionFence &&
|
|
13559
|
+
!uncachedAsyncLifecycleCall;
|
|
13560
|
+
if (
|
|
13561
|
+
usesDurableInvocationFence &&
|
|
13562
|
+
this.#options.verifyDurableInvocationFence
|
|
13563
|
+
) {
|
|
13564
|
+
const verification =
|
|
13565
|
+
this.durableInvocationFenceVerification ??
|
|
13566
|
+
this.#options.verifyDurableInvocationFence();
|
|
13567
|
+
this.durableInvocationFenceVerification = verification;
|
|
13568
|
+
let supportsDurableInvocationFence: boolean;
|
|
13569
|
+
try {
|
|
13570
|
+
supportsDurableInvocationFence = await verification;
|
|
13571
|
+
} catch (error) {
|
|
13572
|
+
if (this.durableInvocationFenceVerification === verification) {
|
|
13573
|
+
this.durableInvocationFenceVerification = null;
|
|
13574
|
+
}
|
|
13575
|
+
throw error;
|
|
13576
|
+
}
|
|
13577
|
+
// A health probe is only a positive capability observation. A
|
|
13578
|
+
// transient probe failure must not poison every later fenced call
|
|
13579
|
+
// in this Play after the gateway has recovered.
|
|
13580
|
+
if (!supportsDurableInvocationFence) {
|
|
13581
|
+
if (this.durableInvocationFenceVerification === verification) {
|
|
13582
|
+
this.durableInvocationFenceVerification = null;
|
|
13583
|
+
}
|
|
13584
|
+
throw new Error(
|
|
13585
|
+
'The active execution gateway does not support execute-fenced-v2. ' +
|
|
13586
|
+
'No provider request was submitted; deploy the compatible gateway receiver first.',
|
|
13587
|
+
);
|
|
13588
|
+
}
|
|
13589
|
+
}
|
|
13590
|
+
const executeSuffix = usesDurableInvocationFence
|
|
13591
|
+
? durableInvocationFenceExecutePath(
|
|
13592
|
+
DURABLE_INVOCATION_FENCE_VERSION,
|
|
13593
|
+
)
|
|
13594
|
+
: 'execute';
|
|
13595
|
+
const url = `${executionBaseUrl.replace(/\/$/, '')}/api/v2/integrations/${encodeURIComponent(toolId)}/${executeSuffix}`;
|
|
13554
13596
|
const fixtureReplaySafe = this.#options.integrationMode === 'fixture';
|
|
13555
13597
|
const readOnlyQuery = isQueryResultDatasetReadRequest(
|
|
13556
13598
|
toolId,
|
|
@@ -13631,7 +13673,10 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13631
13673
|
? { async_operation_wait: true }
|
|
13632
13674
|
: {}),
|
|
13633
13675
|
...(usesDurableInvocationFence
|
|
13634
|
-
? {
|
|
13676
|
+
? {
|
|
13677
|
+
invocation_fence_version:
|
|
13678
|
+
DURABLE_INVOCATION_FENCE_VERSION,
|
|
13679
|
+
}
|
|
13635
13680
|
: {}),
|
|
13636
13681
|
...(durableCallReceiptKey
|
|
13637
13682
|
? {
|
|
@@ -13859,16 +13904,17 @@ export class PlayContextImpl implements ScalarPlayAuthoringRuntimeContext {
|
|
|
13859
13904
|
(await this.#options.getToolProvider?.(toolId))?.trim() ||
|
|
13860
13905
|
provider;
|
|
13861
13906
|
if (shouldRouteFixtureProvider(canonicalProvider)) {
|
|
13862
|
-
if (!durableCallReceiptKey) {
|
|
13863
|
-
throw new Error(
|
|
13864
|
-
'Configured fixture response timing requires a durable call receipt key.',
|
|
13865
|
-
);
|
|
13866
|
-
}
|
|
13867
13907
|
const canonicalOperation =
|
|
13868
13908
|
(
|
|
13869
13909
|
await this.#options.getToolOperation?.(toolId)
|
|
13870
13910
|
)?.trim() || toolId;
|
|
13871
|
-
|
|
13911
|
+
// A fixture schedule needs a stable logical-call identity,
|
|
13912
|
+
// not a cache receipt. Ordinary /execute calls deliberately
|
|
13913
|
+
// do not create durable receipts; deeplineRequestId remains
|
|
13914
|
+
// stable across their physical transport retries.
|
|
13915
|
+
const fixtureRequestIdentity =
|
|
13916
|
+
durableCallReceiptKey ?? deeplineRequestId;
|
|
13917
|
+
const stableRequestKey = `${canonicalProvider}:${canonicalOperation}:${fixtureRequestIdentity}`;
|
|
13872
13918
|
const behaviorDigest = stableDigest(
|
|
13873
13919
|
JSON.stringify(fixtureBehavior),
|
|
13874
13920
|
);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `execute-fenced-v2` is the first operation that requires semantic provider
|
|
3
|
+
* identity. It is intentionally a named operation rather than a runtime-wide
|
|
4
|
+
* deployment contract: callers can preflight this one receiver capability
|
|
5
|
+
* before they submit a provider request.
|
|
6
|
+
*/
|
|
7
|
+
export const DURABLE_INVOCATION_FENCE_VERSION = 2 as const;
|
|
8
|
+
/** Attestation understood by pre-v2 runners during their drain window. */
|
|
9
|
+
export const LEGACY_DURABLE_INVOCATION_FENCE_ATTESTATION_HEADER =
|
|
10
|
+
'x-deepline-invocation-fence';
|
|
11
|
+
export const LEGACY_DURABLE_INVOCATION_FENCE_ATTESTATION_VALUE = 'v1';
|
|
12
|
+
/**
|
|
13
|
+
* v2 is a distinct receiver capability, not a replacement value for the v1
|
|
14
|
+
* header. Keeping the two headers separate lets a receiver serve sleeping v1
|
|
15
|
+
* runners while new callers prove that execute-fenced-v2 is available.
|
|
16
|
+
*/
|
|
17
|
+
export const DURABLE_INVOCATION_FENCE_ATTESTATION_HEADER =
|
|
18
|
+
'x-deepline-invocation-fence-v2';
|
|
19
|
+
export const DURABLE_INVOCATION_FENCE_ATTESTATION_VALUE = 'v2';
|
|
20
|
+
|
|
21
|
+
export function durableInvocationFenceAttestationHeaders(): Record<
|
|
22
|
+
string,
|
|
23
|
+
string
|
|
24
|
+
> {
|
|
25
|
+
return {
|
|
26
|
+
[LEGACY_DURABLE_INVOCATION_FENCE_ATTESTATION_HEADER]:
|
|
27
|
+
LEGACY_DURABLE_INVOCATION_FENCE_ATTESTATION_VALUE,
|
|
28
|
+
[DURABLE_INVOCATION_FENCE_ATTESTATION_HEADER]:
|
|
29
|
+
DURABLE_INVOCATION_FENCE_ATTESTATION_VALUE,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function durableInvocationFenceExecutePath(version: 1 | 2): string {
|
|
34
|
+
return `execute-fenced-v${version}`;
|
|
35
|
+
}
|
|
@@ -240,7 +240,8 @@ export function recoveryForRuntimeInitializationTransportFailure(
|
|
|
240
240
|
reason:
|
|
241
241
|
| 'runtime_postgres_connect'
|
|
242
242
|
| 'runtime_api_transport'
|
|
243
|
-
| 'runtime_receipt_gateway_transport'
|
|
243
|
+
| 'runtime_receipt_gateway_transport'
|
|
244
|
+
| 'daytona_public_status',
|
|
244
245
|
): PlayRunRecoveryError {
|
|
245
246
|
return new PlayRunRecoveryError({
|
|
246
247
|
decision: {
|
|
@@ -5,10 +5,6 @@ import {
|
|
|
5
5
|
RUNNER_TERMINAL_CHECKPOINT_DISPOSITION,
|
|
6
6
|
type PlayRunnerExecutionConfig,
|
|
7
7
|
} from '../../protocol';
|
|
8
|
-
import {
|
|
9
|
-
PLAY_RUNTIME_CONTRACT,
|
|
10
|
-
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
11
|
-
} from '../../runtime-contract';
|
|
12
8
|
import {
|
|
13
9
|
PLAY_RUNNER_TERMINAL_GRACE_SECONDS,
|
|
14
10
|
PLAY_RUNNER_STARTUP_GRACE_SECONDS,
|
|
@@ -380,7 +376,6 @@ async function main() {
|
|
|
380
376
|
headers: {
|
|
381
377
|
'content-type': 'application/json',
|
|
382
378
|
authorization: 'Bearer ' + token,
|
|
383
|
-
'${PLAY_RUNTIME_CONTRACT_HEADER}': '${String(PLAY_RUNTIME_CONTRACT)}',
|
|
384
379
|
...(preferredGatewayMachineId
|
|
385
380
|
? { 'fly-force-instance-id': preferredGatewayMachineId }
|
|
386
381
|
: {}),
|
|
@@ -61,6 +61,13 @@ const RUNTIME_RECEIPT_GATEWAY_TRANSPORT_RETRY_PATTERN =
|
|
|
61
61
|
/AppRuntimeApiTransportError: (?:App runtime API|Runtime receipt gateway) transport exhausted action=(?:get|claim|mark|complete|fail|heartbeat|release|skip)_runtime_step_receipts?/i;
|
|
62
62
|
const RUNTIME_API_TRANSPORT_RETRY_PATTERN =
|
|
63
63
|
/\bRuntime API request to .+ failed before receiving a response:\s*(?:fetch failed|connection (?:terminated|timed out|closed|reset)|ECONNRESET|ETIMEDOUT|ECONNREFUSED)\b/i;
|
|
64
|
+
// Daytona has returned this 400 while looking up the newly-created sandbox's
|
|
65
|
+
// public status. It is a provider control-plane fault, not a caller-invalid
|
|
66
|
+
// sandbox request. Only retry it when the terminal result proves no row or
|
|
67
|
+
// Play step began, because a later public-status lookup could otherwise race
|
|
68
|
+
// with user code that has already had side effects.
|
|
69
|
+
const DAYTONA_PUBLIC_STATUS_TRANSIENT_RETRY_PATTERN =
|
|
70
|
+
/\bDaytonaValidationError:\s*bad request:\s*failed to get sandbox public status:\s*an unexpected error occurred\.?\b/i;
|
|
64
71
|
const DAYTONA_INFRASTRUCTURE_RETRY_PATTERN =
|
|
65
72
|
/\b(?:Request failed with status code (?:408|429|500|502|503|504)|ECONNRESET|ECONNREFUSED|ETIMEDOUT|UND_ERR_CONNECT_TIMEOUT|fetch failed|socket hang up|Daytona sandbox create failed across|Daytona sandbox create did not complete|Daytona readiness baseline)\b/i;
|
|
66
73
|
|
|
@@ -893,6 +900,7 @@ export function retryableRuntimeInitializationFailureReason(
|
|
|
893
900
|
| 'runtime_postgres_connect'
|
|
894
901
|
| 'runtime_api_transport'
|
|
895
902
|
| 'runtime_receipt_gateway_transport'
|
|
903
|
+
| 'daytona_public_status'
|
|
896
904
|
| null {
|
|
897
905
|
if (result.status !== 'failed') return null;
|
|
898
906
|
if (RUNTIME_POSTGRES_CONNECT_RETRY_PATTERN.test(result.error)) {
|
|
@@ -902,6 +910,13 @@ export function retryableRuntimeInitializationFailureReason(
|
|
|
902
910
|
return 'runtime_receipt_gateway_transport';
|
|
903
911
|
}
|
|
904
912
|
const rowsProcessed = Number(result.stats?.rowsProcessed ?? 0);
|
|
913
|
+
if (
|
|
914
|
+
rowsProcessed === 0 &&
|
|
915
|
+
result.steps.length === 0 &&
|
|
916
|
+
DAYTONA_PUBLIC_STATUS_TRANSIENT_RETRY_PATTERN.test(result.error)
|
|
917
|
+
) {
|
|
918
|
+
return 'daytona_public_status';
|
|
919
|
+
}
|
|
905
920
|
if (
|
|
906
921
|
rowsProcessed === 0 &&
|
|
907
922
|
result.steps.length === 0 &&
|
|
@@ -97,8 +97,8 @@ import {
|
|
|
97
97
|
} from './map-row-outcome';
|
|
98
98
|
import { DEEPLINE_CELL_META_FIELD } from '../plays/cell-staleness';
|
|
99
99
|
import {
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_FORMAT,
|
|
101
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_HEADER,
|
|
102
102
|
} from './runtime-contract';
|
|
103
103
|
import { PLAY_RUNTIME_API_COMPAT_PATH } from './runtime-api-paths';
|
|
104
104
|
import {
|
|
@@ -615,7 +615,9 @@ function resolveRuntimeApiHeaders(
|
|
|
615
615
|
return {
|
|
616
616
|
'content-type': 'application/json',
|
|
617
617
|
authorization: `Bearer ${token}`,
|
|
618
|
-
[
|
|
618
|
+
[LEGACY_RUNTIME_RECEIPT_WIRE_HEADER]: String(
|
|
619
|
+
LEGACY_RUNTIME_RECEIPT_WIRE_FORMAT,
|
|
620
|
+
),
|
|
619
621
|
// A run has many callback HTTP attempts. Preserve the logical run
|
|
620
622
|
// correlation in headers while Vercel keeps its own per-attempt request id.
|
|
621
623
|
...(context.runId?.trim()
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Kept on the old header name so sleeping runners can decode historical
|
|
3
|
+
* receipt presentations. New operations must not use this as a version gate.
|
|
4
|
+
*/
|
|
5
|
+
export const LEGACY_RUNTIME_RECEIPT_WIRE_HEADER = 'x-deepline-runtime-contract';
|
|
6
|
+
export const LEGACY_RUNTIME_RECEIPT_WIRE_FORMAT = 3 as const;
|
|
7
|
+
/**
|
|
8
|
+
* Historical workers validate this readiness range before they claim work.
|
|
9
|
+
* It is an output-only compatibility presentation; current callers use named
|
|
10
|
+
* operation capabilities and do not treat it as a global admission contract.
|
|
11
|
+
*/
|
|
12
|
+
export const LEGACY_RUNTIME_READINESS_MIN_SUPPORTED = 1 as const;
|
|
13
|
+
export const LEGACY_RUNTIME_READINESS_CURRENT = 6 as const;
|
|
4
14
|
/** Shared runner/gateway envelope limit for unacknowledged progress recovery. */
|
|
5
15
|
export const RUNTIME_RUNNER_TERMINAL_PROGRESS_MAX_EVENTS = 2_000;
|
|
6
16
|
/**
|
|
@@ -26,78 +36,26 @@ export function resolvePlayRuntimeTransportAttemptId(
|
|
|
26
36
|
return trimmed && RUNTIME_TRANSPORT_ATTEMPT_ID.test(trimmed) ? trimmed : null;
|
|
27
37
|
}
|
|
28
38
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
contract: 4,
|
|
46
|
-
changed:
|
|
47
|
-
'Runtime receipt heartbeat requests can carry one positional lease ID per receipt key.',
|
|
48
|
-
compatOwner: 'runtime',
|
|
49
|
-
compatRemoval: 'contract 3 runtime lane drain',
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
contract: 3,
|
|
53
|
-
changed:
|
|
54
|
-
'Runtime receipt completion responses are compact acknowledgements; receipt reads remain the payload replay path.',
|
|
55
|
-
compatOwner: 'runtime',
|
|
56
|
-
compatRemoval: 'contract 2 support window closure',
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
contract: 2,
|
|
60
|
-
changed:
|
|
61
|
-
'Runtime receipt batch responses use positional nulls and v2 lease-aware receipt semantics.',
|
|
62
|
-
compatOwner: 'runtime',
|
|
63
|
-
compatRemoval: 'ledger cutover milestone M1',
|
|
64
|
-
},
|
|
65
|
-
] as const;
|
|
39
|
+
/**
|
|
40
|
+
* The pre-operation-runtime header is retained only to decode historical
|
|
41
|
+
* receipt response shapes. It never admits or rejects a runtime request.
|
|
42
|
+
*/
|
|
43
|
+
export type LegacyRuntimeReceiptWireFormat = 1 | 2 | 3;
|
|
44
|
+
|
|
45
|
+
export function resolveLegacyRuntimeReceiptWireFormat(
|
|
46
|
+
rawContract: string | null | undefined,
|
|
47
|
+
): LegacyRuntimeReceiptWireFormat {
|
|
48
|
+
const requested = Number(rawContract?.trim());
|
|
49
|
+
if (!Number.isSafeInteger(requested) || requested <= 1) return 1;
|
|
50
|
+
if (requested === 2) return 2;
|
|
51
|
+
return 3;
|
|
52
|
+
}
|
|
66
53
|
|
|
67
54
|
export function runtimeReceiptCompletionResponse<
|
|
68
55
|
T extends { output?: unknown },
|
|
69
|
-
>(
|
|
70
|
-
if (!receipt ||
|
|
56
|
+
>(wireFormat: LegacyRuntimeReceiptWireFormat, receipt: T | null): T | null {
|
|
57
|
+
if (!receipt || wireFormat < 3) return receipt;
|
|
71
58
|
const { output, ...ack } = receipt;
|
|
72
59
|
void output;
|
|
73
60
|
return ack as T;
|
|
74
61
|
}
|
|
75
|
-
|
|
76
|
-
export type RuntimeContractResolution =
|
|
77
|
-
| { ok: true; contract: number }
|
|
78
|
-
| {
|
|
79
|
-
ok: false;
|
|
80
|
-
requestedContract: number;
|
|
81
|
-
currentContract: number;
|
|
82
|
-
minSupportedContract: number;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
export function resolvePlayRuntimeContract(
|
|
86
|
-
rawContract: string | null | undefined,
|
|
87
|
-
): RuntimeContractResolution {
|
|
88
|
-
const trimmed = rawContract?.trim();
|
|
89
|
-
const requestedContract = trimmed ? Number(trimmed) : 1;
|
|
90
|
-
if (
|
|
91
|
-
!Number.isInteger(requestedContract) ||
|
|
92
|
-
requestedContract < PLAY_RUNTIME_CONTRACT_MIN_SUPPORTED ||
|
|
93
|
-
requestedContract > PLAY_RUNTIME_CONTRACT
|
|
94
|
-
) {
|
|
95
|
-
return {
|
|
96
|
-
ok: false,
|
|
97
|
-
requestedContract,
|
|
98
|
-
currentContract: PLAY_RUNTIME_CONTRACT,
|
|
99
|
-
minSupportedContract: PLAY_RUNTIME_CONTRACT_MIN_SUPPORTED,
|
|
100
|
-
};
|
|
101
|
-
}
|
|
102
|
-
return { ok: true, contract: requestedContract };
|
|
103
|
-
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A named runtime operation is its complete public wire contract. Runtime
|
|
3
|
+
* deployment builds are deliberately not part of this type: a receiver must
|
|
4
|
+
* either understand the named operation or reject that operation before it
|
|
5
|
+
* performs an effect.
|
|
6
|
+
*/
|
|
7
|
+
export type RuntimeOperation<
|
|
8
|
+
Name extends string,
|
|
9
|
+
Request,
|
|
10
|
+
Response,
|
|
11
|
+
> = Readonly<{
|
|
12
|
+
name: Name;
|
|
13
|
+
request: Request;
|
|
14
|
+
response: Response;
|
|
15
|
+
}>;
|
|
16
|
+
|
|
17
|
+
export function defineRuntimeOperation<
|
|
18
|
+
const Name extends string,
|
|
19
|
+
Request,
|
|
20
|
+
Response,
|
|
21
|
+
>(
|
|
22
|
+
input: RuntimeOperation<Name, Request, Response>,
|
|
23
|
+
): RuntimeOperation<Name, Request, Response> {
|
|
24
|
+
return input;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Author a compatible evolution of one operation.
|
|
29
|
+
*
|
|
30
|
+
* The next request must accept every old request and the next response must
|
|
31
|
+
* remain consumable by every old caller. A breaking wire meaning therefore
|
|
32
|
+
* cannot be hidden behind a global deployment number: it needs a new named
|
|
33
|
+
* operation instead.
|
|
34
|
+
*/
|
|
35
|
+
export function evolveRuntimeOperation<
|
|
36
|
+
const Name extends string,
|
|
37
|
+
PreviousRequest,
|
|
38
|
+
PreviousResponse,
|
|
39
|
+
NextRequest,
|
|
40
|
+
NextResponse,
|
|
41
|
+
>(
|
|
42
|
+
previous: RuntimeOperation<Name, PreviousRequest, PreviousResponse>,
|
|
43
|
+
next: PreviousRequest extends NextRequest
|
|
44
|
+
? NextResponse extends PreviousResponse
|
|
45
|
+
? RuntimeOperation<Name, NextRequest, NextResponse>
|
|
46
|
+
: never
|
|
47
|
+
: never,
|
|
48
|
+
): RuntimeOperation<Name, NextRequest, NextResponse> {
|
|
49
|
+
void previous;
|
|
50
|
+
return next;
|
|
51
|
+
}
|
package/dist/cli/index.js
CHANGED
|
@@ -1225,7 +1225,7 @@ var SDK_RELEASE = {
|
|
|
1225
1225
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1226
1226
|
// getters keep their established compatibility behavior.
|
|
1227
1227
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1228
|
-
version: "0.3.
|
|
1228
|
+
version: "0.3.82",
|
|
1229
1229
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
1230
1230
|
packageCapabilities: {
|
|
1231
1231
|
updatePreferences: 1
|
|
@@ -36923,6 +36923,7 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
|
36923
36923
|
}
|
|
36924
36924
|
|
|
36925
36925
|
// src/cli/commands/skills.ts
|
|
36926
|
+
var SKILLS_PROCESS_TIMEOUT_MS = 45e3;
|
|
36926
36927
|
var RUNTIME_TO_SKILLS_AGENT = {
|
|
36927
36928
|
antigravity: "antigravity",
|
|
36928
36929
|
claude_code: "claude-code",
|
|
@@ -37080,8 +37081,20 @@ function runProcess(command, args, cwd) {
|
|
|
37080
37081
|
stderr += chunk.toString("utf8");
|
|
37081
37082
|
process.stderr.write(chunk);
|
|
37082
37083
|
});
|
|
37083
|
-
|
|
37084
|
+
const timeout = setTimeout(() => {
|
|
37085
|
+
child.kill("SIGTERM");
|
|
37086
|
+
reject(
|
|
37087
|
+
new Error(
|
|
37088
|
+
`${SKILLS_NPX_PACKAGE} timed out after ${SKILLS_PROCESS_TIMEOUT_MS}ms.`
|
|
37089
|
+
)
|
|
37090
|
+
);
|
|
37091
|
+
}, SKILLS_PROCESS_TIMEOUT_MS);
|
|
37092
|
+
child.once("error", (error) => {
|
|
37093
|
+
clearTimeout(timeout);
|
|
37094
|
+
reject(error);
|
|
37095
|
+
});
|
|
37084
37096
|
child.once("close", (code) => {
|
|
37097
|
+
clearTimeout(timeout);
|
|
37085
37098
|
if (code && stderr.trim()) {
|
|
37086
37099
|
process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
|
|
37087
37100
|
`);
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1210,7 +1210,7 @@ var SDK_RELEASE = {
|
|
|
1210
1210
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1211
1211
|
// getters keep their established compatibility behavior.
|
|
1212
1212
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
1213
|
-
version: "0.3.
|
|
1213
|
+
version: "0.3.82",
|
|
1214
1214
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
1215
1215
|
packageCapabilities: {
|
|
1216
1216
|
updatePreferences: 1
|
|
@@ -37017,6 +37017,7 @@ async function syncSdkSkillsIfNeeded(baseUrl, options = {}) {
|
|
|
37017
37017
|
}
|
|
37018
37018
|
|
|
37019
37019
|
// src/cli/commands/skills.ts
|
|
37020
|
+
var SKILLS_PROCESS_TIMEOUT_MS = 45e3;
|
|
37020
37021
|
var RUNTIME_TO_SKILLS_AGENT = {
|
|
37021
37022
|
antigravity: "antigravity",
|
|
37022
37023
|
claude_code: "claude-code",
|
|
@@ -37174,8 +37175,20 @@ function runProcess(command, args, cwd) {
|
|
|
37174
37175
|
stderr += chunk.toString("utf8");
|
|
37175
37176
|
process.stderr.write(chunk);
|
|
37176
37177
|
});
|
|
37177
|
-
|
|
37178
|
+
const timeout = setTimeout(() => {
|
|
37179
|
+
child.kill("SIGTERM");
|
|
37180
|
+
reject(
|
|
37181
|
+
new Error(
|
|
37182
|
+
`${SKILLS_NPX_PACKAGE} timed out after ${SKILLS_PROCESS_TIMEOUT_MS}ms.`
|
|
37183
|
+
)
|
|
37184
|
+
);
|
|
37185
|
+
}, SKILLS_PROCESS_TIMEOUT_MS);
|
|
37186
|
+
child.once("error", (error) => {
|
|
37187
|
+
clearTimeout(timeout);
|
|
37188
|
+
reject(error);
|
|
37189
|
+
});
|
|
37178
37190
|
child.once("close", (code) => {
|
|
37191
|
+
clearTimeout(timeout);
|
|
37179
37192
|
if (code && stderr.trim()) {
|
|
37180
37193
|
process.stderr.write(`${SKILLS_NPX_PACKAGE} exited ${code}.
|
|
37181
37194
|
`);
|
package/dist/index.js
CHANGED
|
@@ -832,7 +832,7 @@ var SDK_RELEASE = {
|
|
|
832
832
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
833
833
|
// getters keep their established compatibility behavior.
|
|
834
834
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
835
|
-
version: "0.3.
|
|
835
|
+
version: "0.3.82",
|
|
836
836
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
837
837
|
packageCapabilities: {
|
|
838
838
|
updatePreferences: 1
|
package/dist/index.mjs
CHANGED
|
@@ -744,7 +744,7 @@ var SDK_RELEASE = {
|
|
|
744
744
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
745
745
|
// getters keep their established compatibility behavior.
|
|
746
746
|
// 0.3.1 deprecated the legacy `deepline enrich` command in favor of Plays.
|
|
747
|
-
version: "0.3.
|
|
747
|
+
version: "0.3.82",
|
|
748
748
|
updateSummary: "Automatic CLI updates are now enabled by default. To opt out, run `deepline settings autoupdate off`; use `deepline settings autoupdate on` to re-enable updates or `deepline settings autoupdate pin <version>` to hold an exact release. This release also adds raw-v2 tool responses at toolResponse.rawV2 while preserving existing toolResponse.raw and declared getters.",
|
|
749
749
|
packageCapabilities: {
|
|
750
750
|
updatePreferences: 1
|
|
@@ -69,6 +69,7 @@
|
|
|
69
69
|
"dist/bundling-sources/shared_libs/play-runtime/durability-store.ts",
|
|
70
70
|
"dist/bundling-sources/shared_libs/play-runtime/durable-call-cache.ts",
|
|
71
71
|
"dist/bundling-sources/shared_libs/play-runtime/durable-call-policy.ts",
|
|
72
|
+
"dist/bundling-sources/shared_libs/play-runtime/durable-invocation-fence.ts",
|
|
72
73
|
"dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts",
|
|
73
74
|
"dist/bundling-sources/shared_libs/play-runtime/dynamic-worker-version.ts",
|
|
74
75
|
"dist/bundling-sources/shared_libs/play-runtime/email-status.ts",
|
|
@@ -160,6 +161,7 @@
|
|
|
160
161
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-environment.ts",
|
|
161
162
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-incident-drills.ts",
|
|
162
163
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-infra-mode.ts",
|
|
164
|
+
"dist/bundling-sources/shared_libs/play-runtime/runtime-operation.ts",
|
|
163
165
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver-pg.ts",
|
|
164
166
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-pg-driver.ts",
|
|
165
167
|
"dist/bundling-sources/shared_libs/play-runtime/runtime-postgres-admission.ts",
|