deepline 0.1.215 → 0.1.217
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/apps/play-runner-workers/src/child-manifest-resolver.ts +1 -0
- package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +10 -85
- package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +9 -7
- package/dist/bundling-sources/sdk/src/release.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +2 -2
- package/dist/bundling-sources/shared_libs/play-runtime/context.ts +96 -142
- package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +37 -21
- package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +22 -47
- package/dist/cli/index.js +39 -11
- package/dist/cli/index.mjs +39 -11
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-runtime-proxy.ts +0 -34
|
@@ -57,13 +57,9 @@ import {
|
|
|
57
57
|
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
58
58
|
} from '../../../shared_libs/play-runtime/runtime-contract';
|
|
59
59
|
import {
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
61
|
+
PLAY_RUNTIME_TAIL_LOG_COMPAT_PATH,
|
|
62
62
|
} from '../../../shared_libs/play-runtime/runtime-api-paths';
|
|
63
|
-
import {
|
|
64
|
-
executorTokenFromAuthorizationHeader,
|
|
65
|
-
isCoordinatorRuntimeProxyPath,
|
|
66
|
-
} from './coordinator-runtime-proxy';
|
|
67
63
|
import {
|
|
68
64
|
decideWorkflowPlatformRetry,
|
|
69
65
|
PLATFORM_DEPLOY_WORKFLOW_RETRY_LIMIT,
|
|
@@ -1335,7 +1331,7 @@ async function markWorkflowRuntimeFailure(input: {
|
|
|
1335
1331
|
} satisfies PlayRunLedgerEvent,
|
|
1336
1332
|
],
|
|
1337
1333
|
});
|
|
1338
|
-
const url = `${baseUrl.replace(/\/$/, '')}${
|
|
1334
|
+
const url = `${baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
1339
1335
|
const backoffMs = [200, 500, 1500];
|
|
1340
1336
|
let lastError: unknown = null;
|
|
1341
1337
|
for (let attempt = 0; attempt <= backoffMs.length; attempt += 1) {
|
|
@@ -1424,7 +1420,7 @@ async function appendWorkflowChildCompletedRunEvent(input: {
|
|
|
1424
1420
|
} satisfies PlayRunLedgerEvent,
|
|
1425
1421
|
],
|
|
1426
1422
|
});
|
|
1427
|
-
const url = `${baseUrl.replace(/\/$/, '')}${
|
|
1423
|
+
const url = `${baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
1428
1424
|
const response = await fetch(url, { method: 'POST', headers, body });
|
|
1429
1425
|
if (!response.ok) {
|
|
1430
1426
|
throw new Error(
|
|
@@ -1844,7 +1840,7 @@ async function markRegisteredChildRunFailed(input: {
|
|
|
1844
1840
|
contract: PLAY_RUNTIME_CONTRACT,
|
|
1845
1841
|
executorToken: input.childExecutorToken,
|
|
1846
1842
|
baseUrl: input.baseUrl,
|
|
1847
|
-
path:
|
|
1843
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1848
1844
|
headers: {
|
|
1849
1845
|
'x-deepline-request-id': crypto.randomUUID(),
|
|
1850
1846
|
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
@@ -1901,7 +1897,7 @@ async function appendRegisteredChildRunTerminal(input: {
|
|
|
1901
1897
|
contract: PLAY_RUNTIME_CONTRACT,
|
|
1902
1898
|
executorToken: input.childExecutorToken,
|
|
1903
1899
|
baseUrl: input.baseUrl,
|
|
1904
|
-
path:
|
|
1900
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1905
1901
|
headers: {
|
|
1906
1902
|
'x-deepline-request-id': crypto.randomUUID(),
|
|
1907
1903
|
[PLAY_RUNTIME_CONTRACT_HEADER]: String(PLAY_RUNTIME_CONTRACT),
|
|
@@ -1983,7 +1979,7 @@ async function callRuntimeApiFromCoordinator(input: {
|
|
|
1983
1979
|
contract: PLAY_RUNTIME_CONTRACT,
|
|
1984
1980
|
executorToken: input.executorToken,
|
|
1985
1981
|
baseUrl: input.baseUrl,
|
|
1986
|
-
path:
|
|
1982
|
+
path: PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1987
1983
|
body,
|
|
1988
1984
|
headers: {
|
|
1989
1985
|
'x-deepline-request-id': requestId,
|
|
@@ -3122,8 +3118,7 @@ async function submitChildWorkflowThroughCoordinator(input: {
|
|
|
3122
3118
|
* Workflows serializes the dynamic Worker's `env` map when it persists
|
|
3123
3119
|
* workflow state. WorkerEntrypoint stubs ARE cloneable.
|
|
3124
3120
|
*
|
|
3125
|
-
* Path allowlist:
|
|
3126
|
-
* `/api/v2/integrations/*`.
|
|
3121
|
+
* Path allowlist: only `/api/v2/plays/*` and `/api/v2/integrations/*`.
|
|
3127
3122
|
* Anything else is a sandbox-escape attempt and gets a loud 403 — the
|
|
3128
3123
|
* coordinator must NOT proxy a play's request to internal admin routes
|
|
3129
3124
|
* even if the play tries to construct such a URL.
|
|
@@ -3132,7 +3127,6 @@ export class RuntimeApi extends WorkerEntrypoint<CoordinatorEnv, undefined> {
|
|
|
3132
3127
|
async fetch(request: Request): Promise<Response> {
|
|
3133
3128
|
const incoming = new URL(request.url);
|
|
3134
3129
|
const allowed =
|
|
3135
|
-
incoming.pathname === PLAY_RUNTIME_API_CURRENT_PATH ||
|
|
3136
3130
|
incoming.pathname.startsWith('/api/v2/plays/') ||
|
|
3137
3131
|
incoming.pathname.startsWith('/api/v2/integrations/');
|
|
3138
3132
|
if (!allowed) {
|
|
@@ -3765,62 +3759,6 @@ const coordinatorEntrypoint = {
|
|
|
3765
3759
|
|
|
3766
3760
|
export default coordinatorEntrypoint;
|
|
3767
3761
|
|
|
3768
|
-
const COORDINATOR_RUNTIME_PROXY_MAX_BODY_BYTES = 16 * 1024 * 1024;
|
|
3769
|
-
|
|
3770
|
-
async function proxyCoordinatorRuntimeApiRequest(input: {
|
|
3771
|
-
request: Request;
|
|
3772
|
-
env: CoordinatorEnv;
|
|
3773
|
-
url: URL;
|
|
3774
|
-
}): Promise<Response> {
|
|
3775
|
-
const { request, env, url } = input;
|
|
3776
|
-
if (request.method !== 'GET' && request.method !== 'POST') {
|
|
3777
|
-
return new Response('method not allowed', { status: 405 });
|
|
3778
|
-
}
|
|
3779
|
-
const executorToken = executorTokenFromAuthorizationHeader(
|
|
3780
|
-
request.headers.get('authorization'),
|
|
3781
|
-
);
|
|
3782
|
-
if (!executorToken) {
|
|
3783
|
-
return Response.json(
|
|
3784
|
-
{ error: 'Runtime gateway requires a bearer executor token.' },
|
|
3785
|
-
{ status: 401 },
|
|
3786
|
-
);
|
|
3787
|
-
}
|
|
3788
|
-
const contentLength = Number(request.headers.get('content-length') ?? '0');
|
|
3789
|
-
if (
|
|
3790
|
-
Number.isFinite(contentLength) &&
|
|
3791
|
-
contentLength > COORDINATOR_RUNTIME_PROXY_MAX_BODY_BYTES
|
|
3792
|
-
) {
|
|
3793
|
-
return Response.json(
|
|
3794
|
-
{ error: 'Runtime gateway request body exceeds the 16 MiB limit.' },
|
|
3795
|
-
{ status: 413 },
|
|
3796
|
-
);
|
|
3797
|
-
}
|
|
3798
|
-
let body: unknown = {};
|
|
3799
|
-
if (request.method === 'POST') {
|
|
3800
|
-
try {
|
|
3801
|
-
body = await request.json();
|
|
3802
|
-
} catch {
|
|
3803
|
-
return Response.json(
|
|
3804
|
-
{ error: 'Runtime gateway requires a JSON request body.' },
|
|
3805
|
-
{ status: 400 },
|
|
3806
|
-
);
|
|
3807
|
-
}
|
|
3808
|
-
}
|
|
3809
|
-
const upstream = await env.HARNESS.runtimeApiCall({
|
|
3810
|
-
contract: PLAY_RUNTIME_CONTRACT,
|
|
3811
|
-
executorToken,
|
|
3812
|
-
method: request.method,
|
|
3813
|
-
path: `${url.pathname}${url.search}`,
|
|
3814
|
-
body,
|
|
3815
|
-
headers: Object.fromEntries(request.headers.entries()),
|
|
3816
|
-
});
|
|
3817
|
-
const headers = new Headers(upstream.headers);
|
|
3818
|
-
// The harness materializes the upstream response body as a string. Let this
|
|
3819
|
-
// Response calculate its own byte length instead of forwarding a stale one.
|
|
3820
|
-
headers.delete('content-length');
|
|
3821
|
-
return new Response(upstream.body, { status: upstream.status, headers });
|
|
3822
|
-
}
|
|
3823
|
-
|
|
3824
3762
|
/**
|
|
3825
3763
|
* Route dispatcher for the coordinator fetch handler. Extracted as a standalone
|
|
3826
3764
|
* function so the outer {@link coordinatorEntrypoint.fetch} try/catch backstop
|
|
@@ -3849,19 +3787,6 @@ async function coordinatorRouteFetch(
|
|
|
3849
3787
|
}
|
|
3850
3788
|
return new Response('ok', { status: 200, headers });
|
|
3851
3789
|
}
|
|
3852
|
-
if (isCoordinatorRuntimeProxyPath(url.pathname)) {
|
|
3853
|
-
try {
|
|
3854
|
-
return await proxyCoordinatorRuntimeApiRequest({ request, env, url });
|
|
3855
|
-
} catch (error) {
|
|
3856
|
-
return coordinatorRouteErrorResponse({
|
|
3857
|
-
logTag: '[coordinator.runtime_proxy.error]',
|
|
3858
|
-
code: 'COORDINATOR_RUNTIME_PROXY_FAILED',
|
|
3859
|
-
phase: 'coordinator.runtime_proxy',
|
|
3860
|
-
runId: null,
|
|
3861
|
-
error,
|
|
3862
|
-
});
|
|
3863
|
-
}
|
|
3864
|
-
}
|
|
3865
3790
|
if (url.pathname === '/internal-token/probe') {
|
|
3866
3791
|
const authError = authorizeCoordinatorControlRequest({ request, env });
|
|
3867
3792
|
if (authError) return authError;
|
|
@@ -4110,7 +4035,7 @@ async function flushTailRunLogs(
|
|
|
4110
4035
|
return;
|
|
4111
4036
|
}
|
|
4112
4037
|
await fetch(
|
|
4113
|
-
`${env.DEEPLINE_API_BASE_URL}${
|
|
4038
|
+
`${env.DEEPLINE_API_BASE_URL}${PLAY_RUNTIME_TAIL_LOG_COMPAT_PATH}`,
|
|
4114
4039
|
{
|
|
4115
4040
|
method: 'POST',
|
|
4116
4041
|
headers: {
|
|
@@ -5530,7 +5455,7 @@ export class TenantWorkflow extends WorkflowEntrypoint {
|
|
|
5530
5455
|
const runId = payload && typeof payload.runId === "string" ? payload.runId : "warmup";
|
|
5531
5456
|
const startedAt = Date.now();
|
|
5532
5457
|
if (this.env.RUNTIME_API) {
|
|
5533
|
-
await this.env.RUNTIME_API.fetch(new Request("https://deepline.runtime.internal${
|
|
5458
|
+
await this.env.RUNTIME_API.fetch(new Request("https://deepline.runtime.internal${PLAY_RUNTIME_API_COMPAT_PATH}", {
|
|
5534
5459
|
method: "POST",
|
|
5535
5460
|
headers: { "content-type": "application/json" },
|
|
5536
5461
|
body: "{}"
|
|
@@ -185,8 +185,8 @@ import {
|
|
|
185
185
|
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
186
186
|
} from '../../../shared_libs/play-runtime/runtime-contract';
|
|
187
187
|
import {
|
|
188
|
-
|
|
189
|
-
|
|
188
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
189
|
+
PLAY_RUNTIME_EGRESS_FETCH_COMPAT_PATH,
|
|
190
190
|
} from '../../../shared_libs/play-runtime/runtime-api-paths';
|
|
191
191
|
import { DYNAMIC_PLAY_WORKER_ARTIFACT_VERSION } from '../../../shared_libs/play-runtime/dynamic-worker-version';
|
|
192
192
|
import {
|
|
@@ -860,7 +860,7 @@ async function fetchRuntimeApi(
|
|
|
860
860
|
? Math.max(1, Math.ceil(options.timeoutMsOverride))
|
|
861
861
|
: path === '/api/v2/plays/run'
|
|
862
862
|
? RUNTIME_API_PLAY_RUN_TIMEOUT_MS
|
|
863
|
-
: path ===
|
|
863
|
+
: path === PLAY_RUNTIME_EGRESS_FETCH_COMPAT_PATH
|
|
864
864
|
? RUNTIME_API_EGRESS_FETCH_TIMEOUT_MS
|
|
865
865
|
: /^\/api\/v2\/integrations\/[^/]+\/execute$/.test(path)
|
|
866
866
|
? RUNTIME_API_INTEGRATION_EXECUTE_TIMEOUT_MS
|
|
@@ -1170,6 +1170,8 @@ function recordRunnerPerfTrace(input: {
|
|
|
1170
1170
|
ts: Date.now(),
|
|
1171
1171
|
source: 'dynamic_worker' as const,
|
|
1172
1172
|
runId: input.req.runId,
|
|
1173
|
+
playName: input.req.playName,
|
|
1174
|
+
orgId: input.req.orgId,
|
|
1173
1175
|
phase,
|
|
1174
1176
|
ms: input.ms ?? 0,
|
|
1175
1177
|
...(input.extra ?? {}),
|
|
@@ -1316,7 +1318,7 @@ async function postRuntimeApi<T>(
|
|
|
1316
1318
|
try {
|
|
1317
1319
|
res = await fetchRuntimeApi(
|
|
1318
1320
|
baseUrl,
|
|
1319
|
-
|
|
1321
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
1320
1322
|
{
|
|
1321
1323
|
method: 'POST',
|
|
1322
1324
|
headers: {
|
|
@@ -2890,7 +2892,7 @@ async function postRuntimeEgressFetch(
|
|
|
2890
2892
|
) {
|
|
2891
2893
|
const response = await fetchRuntimeApi(
|
|
2892
2894
|
req.baseUrl,
|
|
2893
|
-
|
|
2895
|
+
PLAY_RUNTIME_EGRESS_FETCH_COMPAT_PATH,
|
|
2894
2896
|
{
|
|
2895
2897
|
method: 'POST',
|
|
2896
2898
|
headers: {
|
|
@@ -4263,7 +4265,7 @@ function createMinimalWorkerCtx(
|
|
|
4263
4265
|
if (!auth) return {};
|
|
4264
4266
|
const response = await fetchRuntimeApi(
|
|
4265
4267
|
req.baseUrl,
|
|
4266
|
-
|
|
4268
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
4267
4269
|
{
|
|
4268
4270
|
method: 'POST',
|
|
4269
4271
|
headers: {
|
|
@@ -8942,7 +8944,7 @@ export class TenantWorkflow extends WorkflowEntrypoint<
|
|
|
8942
8944
|
try {
|
|
8943
8945
|
const response = await fetchRuntimeApi(
|
|
8944
8946
|
req.baseUrl,
|
|
8945
|
-
|
|
8947
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
8946
8948
|
{
|
|
8947
8949
|
method: 'POST',
|
|
8948
8950
|
headers: {
|
|
@@ -106,10 +106,10 @@ export const SDK_RELEASE = {
|
|
|
106
106
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
107
107
|
// fields shipped in 0.1.153.
|
|
108
108
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
109
|
-
version: '0.1.
|
|
109
|
+
version: '0.1.217',
|
|
110
110
|
apiContract: '2026-06-dataset-handle-results-hard-cutover',
|
|
111
111
|
supportPolicy: {
|
|
112
|
-
latest: '0.1.
|
|
112
|
+
latest: '0.1.217',
|
|
113
113
|
minimumSupported: '0.1.53',
|
|
114
114
|
deprecatedBelow: '0.1.53',
|
|
115
115
|
commandMinimumSupported: [
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
PLAY_RUNTIME_CONTRACT,
|
|
39
39
|
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
40
40
|
} from '@shared_libs/play-runtime/runtime-contract';
|
|
41
|
-
import {
|
|
41
|
+
import { PLAY_RUNTIME_API_COMPAT_PATH } from '@shared_libs/play-runtime/runtime-api-paths';
|
|
42
42
|
import { PLAY_RUNTIME_TEST_FAULT_HEADER } from '@shared_libs/play-runtime/test-runtime-seams';
|
|
43
43
|
import { vercelProtectionBypassHeaders } from '@shared_libs/play-runtime/vercel-protection';
|
|
44
44
|
|
|
@@ -788,7 +788,7 @@ export class AppRuntimeApiTransportError extends Error {
|
|
|
788
788
|
|
|
789
789
|
function resolveAppRuntimeApiUrl(context: WorkerRuntimeApiContext): string {
|
|
790
790
|
const baseUrl = context.baseUrl.trim().replace(/\/$/, '');
|
|
791
|
-
return `${baseUrl}${
|
|
791
|
+
return `${baseUrl}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
792
792
|
}
|
|
793
793
|
|
|
794
794
|
async function postAppRuntimeApi<TResponse>(
|
|
@@ -48,8 +48,8 @@ import {
|
|
|
48
48
|
SYNTHETIC_RUN_HEADER,
|
|
49
49
|
} from './coordinator-headers';
|
|
50
50
|
import {
|
|
51
|
+
PLAY_RUNTIME_API_COMPAT_PATH,
|
|
51
52
|
PLAY_RUNTIME_API_CURRENT_PATH,
|
|
52
|
-
PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_CURRENT_PATH,
|
|
53
53
|
} from './runtime-api-paths';
|
|
54
54
|
import {
|
|
55
55
|
createRootRunExecutionScope,
|
|
@@ -262,6 +262,15 @@ const rowContext = new AsyncLocalStorage<{
|
|
|
262
262
|
rowKey?: string;
|
|
263
263
|
mapScope?: MapExecutionScope;
|
|
264
264
|
}>();
|
|
265
|
+
type InlineCompositionStore = {
|
|
266
|
+
context: PlayContextImpl;
|
|
267
|
+
executionScope: RunExecutionScope;
|
|
268
|
+
governor: PlayExecutionGovernor;
|
|
269
|
+
playName: string;
|
|
270
|
+
staticPipeline: ContextOptions['staticPipeline'];
|
|
271
|
+
};
|
|
272
|
+
const inlineCompositionContext =
|
|
273
|
+
new AsyncLocalStorage<InlineCompositionStore>();
|
|
265
274
|
const toolExecutionOverrides = new AsyncLocalStorage<{ force: boolean }>();
|
|
266
275
|
const PROGRESS_HEARTBEAT_INTERVAL_MS = 1_000;
|
|
267
276
|
const PURE_JS_HEARTBEAT_ROW_INTERVAL = 250;
|
|
@@ -1270,12 +1279,6 @@ export class PlayContextImpl {
|
|
|
1270
1279
|
*/
|
|
1271
1280
|
private readonly governor: PlayExecutionGovernor;
|
|
1272
1281
|
private readonly resourceGovernor: RuntimeResourceGovernor;
|
|
1273
|
-
/**
|
|
1274
|
-
* Lineage identity for this context (run/play ids + ancestry). Seeded from the
|
|
1275
|
-
* Governor snapshot; used only for receipt keys, durable-boundary scoping, and
|
|
1276
|
-
* child run-id derivation. All policy lives in {@link governor}.
|
|
1277
|
-
*/
|
|
1278
|
-
private readonly governance: GovernanceSnapshot;
|
|
1279
1282
|
private readonly resolvedPlayExecutorCache = new Map<
|
|
1280
1283
|
string,
|
|
1281
1284
|
Promise<ResolvedPlayExecutor>
|
|
@@ -1443,7 +1446,6 @@ export class PlayContextImpl {
|
|
|
1443
1446
|
this.resourceGovernor = createRuntimeResourceGovernor({
|
|
1444
1447
|
executionGovernor: this.governor,
|
|
1445
1448
|
});
|
|
1446
|
-
this.governance = this.governor.snapshot();
|
|
1447
1449
|
}
|
|
1448
1450
|
|
|
1449
1451
|
private durableBoundaryId(localId: string): string {
|
|
@@ -1451,7 +1453,33 @@ export class PlayContextImpl {
|
|
|
1451
1453
|
// Nested plays and concurrent child calls therefore need a stable run scope
|
|
1452
1454
|
// in the key, otherwise two children can both produce e.g. "sleep-0-25"
|
|
1453
1455
|
// and replay the wrong boundary or never observe completion.
|
|
1454
|
-
return `${this.
|
|
1456
|
+
return `${this.currentGovernance.currentRunId}:${localId}`;
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
private get activeInlineComposition(): InlineCompositionStore | null {
|
|
1460
|
+
const active = inlineCompositionContext.getStore();
|
|
1461
|
+
return active?.context === this ? active : null;
|
|
1462
|
+
}
|
|
1463
|
+
|
|
1464
|
+
private get currentExecutionScope(): RunExecutionScope {
|
|
1465
|
+
return this.activeInlineComposition?.executionScope ?? this.executionScope;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
private get currentExecutionGovernor(): PlayExecutionGovernor {
|
|
1469
|
+
return this.activeInlineComposition?.governor ?? this.governor;
|
|
1470
|
+
}
|
|
1471
|
+
|
|
1472
|
+
private get currentGovernance(): GovernanceSnapshot {
|
|
1473
|
+
return this.currentExecutionGovernor.snapshot();
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
private get currentPlayName(): string | undefined {
|
|
1477
|
+
return this.activeInlineComposition?.playName ?? this.#options.playName;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
private get currentStaticPipeline(): ContextOptions['staticPipeline'] {
|
|
1481
|
+
const active = this.activeInlineComposition;
|
|
1482
|
+
return active ? active.staticPipeline : this.#options.staticPipeline;
|
|
1455
1483
|
}
|
|
1456
1484
|
|
|
1457
1485
|
private shouldLaunchChildPlaysThroughScheduler(): boolean {
|
|
@@ -1617,17 +1645,18 @@ export class PlayContextImpl {
|
|
|
1617
1645
|
childInput: Record<string, unknown>;
|
|
1618
1646
|
description?: string | null;
|
|
1619
1647
|
}): Promise<void> {
|
|
1648
|
+
const parentGovernance = this.currentGovernance;
|
|
1620
1649
|
const parentPlayName =
|
|
1621
|
-
|
|
1622
|
-
this
|
|
1650
|
+
parentGovernance.currentPlayId ||
|
|
1651
|
+
this.currentPlayName ||
|
|
1623
1652
|
this.#options.playId ||
|
|
1624
1653
|
'anonymous-play';
|
|
1625
1654
|
const governance: PlayCallGovernanceSnapshot = {
|
|
1626
|
-
rootRunId:
|
|
1627
|
-
parentRunId:
|
|
1655
|
+
rootRunId: parentGovernance.rootRunId,
|
|
1656
|
+
parentRunId: parentGovernance.currentRunId,
|
|
1628
1657
|
parentPlayName,
|
|
1629
1658
|
key: input.key,
|
|
1630
|
-
ancestryPlayIds: [...
|
|
1659
|
+
ancestryPlayIds: [...parentGovernance.ancestryPlayIds],
|
|
1631
1660
|
callDepth: input.childGovernance.callDepth,
|
|
1632
1661
|
playCallCount: input.childGovernance.playCallCount,
|
|
1633
1662
|
toolCallCount: input.childGovernance.toolCallCount,
|
|
@@ -1702,13 +1731,13 @@ export class PlayContextImpl {
|
|
|
1702
1731
|
| null
|
|
1703
1732
|
> {
|
|
1704
1733
|
const response = await fetch(
|
|
1705
|
-
`${this.runtimeApiBaseUrl()}${
|
|
1734
|
+
`${this.runtimeApiBaseUrl()}${PLAY_RUNTIME_API_COMPAT_PATH}`,
|
|
1706
1735
|
{
|
|
1707
1736
|
method: 'POST',
|
|
1708
1737
|
headers: await this.runtimeApiHeaders(),
|
|
1709
1738
|
body: JSON.stringify({
|
|
1710
1739
|
action: 'read_child_run_terminal_snapshot',
|
|
1711
|
-
parentRunId: this.
|
|
1740
|
+
parentRunId: this.currentGovernance.currentRunId,
|
|
1712
1741
|
childRunId: input.childRunId,
|
|
1713
1742
|
childPlayName: input.childPlayName,
|
|
1714
1743
|
}),
|
|
@@ -1817,7 +1846,7 @@ export class PlayContextImpl {
|
|
|
1817
1846
|
this.#options.runId
|
|
1818
1847
|
) {
|
|
1819
1848
|
const response = await fetch(
|
|
1820
|
-
`${this.#options.baseUrl.replace(/\/$/, '')}${
|
|
1849
|
+
`${this.#options.baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`,
|
|
1821
1850
|
{
|
|
1822
1851
|
method: 'POST',
|
|
1823
1852
|
headers: {
|
|
@@ -2716,7 +2745,7 @@ export class PlayContextImpl {
|
|
|
2716
2745
|
}): Promise<string> {
|
|
2717
2746
|
return await this.durableToolCallCacheKeyForScope({
|
|
2718
2747
|
...input,
|
|
2719
|
-
playLocalScope: this.
|
|
2748
|
+
playLocalScope: this.currentGovernance.currentPlayId,
|
|
2720
2749
|
});
|
|
2721
2750
|
}
|
|
2722
2751
|
|
|
@@ -2871,7 +2900,7 @@ export class PlayContextImpl {
|
|
|
2871
2900
|
opts.receiptKey?.trim() ||
|
|
2872
2901
|
durableCtxKey({
|
|
2873
2902
|
orgId: this.#options.orgId,
|
|
2874
|
-
playId: this.
|
|
2903
|
+
playId: this.currentExecutionScope.receipt.namespace,
|
|
2875
2904
|
operation,
|
|
2876
2905
|
id,
|
|
2877
2906
|
semanticKey: opts.semanticKey,
|
|
@@ -2905,15 +2934,15 @@ export class PlayContextImpl {
|
|
|
2905
2934
|
}
|
|
2906
2935
|
|
|
2907
2936
|
private get currentRunId(): string {
|
|
2908
|
-
return this.
|
|
2937
|
+
return this.currentExecutionScope.logical.runId;
|
|
2909
2938
|
}
|
|
2910
2939
|
|
|
2911
2940
|
private get currentReceiptOwnerRunId(): string {
|
|
2912
|
-
return this.
|
|
2941
|
+
return this.currentExecutionScope.receipt.ownerRunId;
|
|
2913
2942
|
}
|
|
2914
2943
|
|
|
2915
2944
|
private get currentRunAttempt(): number {
|
|
2916
|
-
return this.
|
|
2945
|
+
return this.currentExecutionScope.receipt.ownerAttempt;
|
|
2917
2946
|
}
|
|
2918
2947
|
|
|
2919
2948
|
private emitScopedFieldMetaUpdate(input: {
|
|
@@ -3193,7 +3222,8 @@ export class PlayContextImpl {
|
|
|
3193
3222
|
rowKey?: string;
|
|
3194
3223
|
callId?: string;
|
|
3195
3224
|
}): string {
|
|
3196
|
-
const scope =
|
|
3225
|
+
const scope =
|
|
3226
|
+
this.currentGovernance.currentRunId || this.#options.runId || 'run';
|
|
3197
3227
|
if (input.callId?.trim()) {
|
|
3198
3228
|
return `${scope}:${input.callId.trim()}`;
|
|
3199
3229
|
}
|
|
@@ -3961,16 +3991,16 @@ export class PlayContextImpl {
|
|
|
3961
3991
|
const flushStartedAt = Date.now();
|
|
3962
3992
|
try {
|
|
3963
3993
|
await this.#options.onMapRowsCompleted!({
|
|
3964
|
-
playName: this
|
|
3965
|
-
playId: this
|
|
3966
|
-
runId: this
|
|
3994
|
+
playName: this.currentPlayName,
|
|
3995
|
+
playId: this.currentExecutionScope.logical.playId,
|
|
3996
|
+
runId: this.currentRunId,
|
|
3967
3997
|
executorToken: this.#options.executorToken,
|
|
3968
3998
|
tableNamespace: resolvedTableNamespace,
|
|
3969
3999
|
rows: chunk,
|
|
3970
4000
|
outputFields: datasetColumnNames.filter((field) =>
|
|
3971
4001
|
shouldPersistMapCellField(field),
|
|
3972
4002
|
),
|
|
3973
|
-
staticPipeline: this
|
|
4003
|
+
staticPipeline: this.currentStaticPipeline ?? null,
|
|
3974
4004
|
});
|
|
3975
4005
|
this.resourceGovernor.observe({
|
|
3976
4006
|
sheetFlushBytes: chunkBytes,
|
|
@@ -4037,11 +4067,11 @@ export class PlayContextImpl {
|
|
|
4037
4067
|
pageStartRows,
|
|
4038
4068
|
resolvedTableNamespace,
|
|
4039
4069
|
{
|
|
4040
|
-
playName: this
|
|
4041
|
-
playId: this
|
|
4042
|
-
runId: this
|
|
4070
|
+
playName: this.currentPlayName,
|
|
4071
|
+
playId: this.currentExecutionScope.logical.playId,
|
|
4072
|
+
runId: this.currentRunId,
|
|
4043
4073
|
executorToken: this.#options.executorToken,
|
|
4044
|
-
staticPipeline: this
|
|
4074
|
+
staticPipeline: this.currentStaticPipeline,
|
|
4045
4075
|
forceRefresh: this.#options.cachePolicy?.forceToolRefresh === true,
|
|
4046
4076
|
inputOffset: page.offset,
|
|
4047
4077
|
},
|
|
@@ -4472,11 +4502,11 @@ export class PlayContextImpl {
|
|
|
4472
4502
|
mapStartRows,
|
|
4473
4503
|
resolvedTableNamespace,
|
|
4474
4504
|
{
|
|
4475
|
-
playName: this
|
|
4476
|
-
playId: this
|
|
4477
|
-
runId: this
|
|
4505
|
+
playName: this.currentPlayName,
|
|
4506
|
+
playId: this.currentExecutionScope.logical.playId,
|
|
4507
|
+
runId: this.currentRunId,
|
|
4478
4508
|
executorToken: this.#options.executorToken,
|
|
4479
|
-
staticPipeline: this
|
|
4509
|
+
staticPipeline: this.currentStaticPipeline,
|
|
4480
4510
|
forceRefresh: this.#options.cachePolicy?.forceToolRefresh === true,
|
|
4481
4511
|
},
|
|
4482
4512
|
);
|
|
@@ -4620,16 +4650,16 @@ export class PlayContextImpl {
|
|
|
4620
4650
|
const flushStartedAt = Date.now();
|
|
4621
4651
|
try {
|
|
4622
4652
|
const writeResult = await this.#options.onMapRowsCompleted!({
|
|
4623
|
-
playName: this
|
|
4624
|
-
playId: this
|
|
4625
|
-
runId: this
|
|
4653
|
+
playName: this.currentPlayName,
|
|
4654
|
+
playId: this.currentExecutionScope.logical.playId,
|
|
4655
|
+
runId: this.currentRunId,
|
|
4626
4656
|
executorToken: this.#options.executorToken,
|
|
4627
4657
|
tableNamespace: resolvedTableNamespace,
|
|
4628
4658
|
rows: chunk,
|
|
4629
4659
|
outputFields: datasetColumnNames.filter((field) =>
|
|
4630
4660
|
shouldPersistMapCellField(field),
|
|
4631
4661
|
),
|
|
4632
|
-
staticPipeline: this
|
|
4662
|
+
staticPipeline: this.currentStaticPipeline ?? null,
|
|
4633
4663
|
});
|
|
4634
4664
|
if (writeResult) {
|
|
4635
4665
|
for (const key of writeResult.staleDroppedKeys ?? []) {
|
|
@@ -6158,6 +6188,7 @@ export class PlayContextImpl {
|
|
|
6158
6188
|
input: Record<string, unknown>,
|
|
6159
6189
|
options?: ToolCallOptions,
|
|
6160
6190
|
): Promise<unknown> {
|
|
6191
|
+
const executionScope = this.currentExecutionScope;
|
|
6161
6192
|
const normalizedKey = this.normalizeContextKey(key, 'tool');
|
|
6162
6193
|
const toolCachePolicy = this.effectiveToolCallCachePolicy(options);
|
|
6163
6194
|
const toolRequestIdentity = deriveToolRequestIdentity({
|
|
@@ -6303,6 +6334,7 @@ export class PlayContextImpl {
|
|
|
6303
6334
|
const rowId = store.rowId;
|
|
6304
6335
|
const fieldName = store.fieldName;
|
|
6305
6336
|
const callId = [
|
|
6337
|
+
executionScope.receipt.namespace,
|
|
6306
6338
|
store.tableNamespace?.trim() || 'map',
|
|
6307
6339
|
store.rowKey?.trim() || String(rowId),
|
|
6308
6340
|
normalizedKey,
|
|
@@ -6669,10 +6701,10 @@ export class PlayContextImpl {
|
|
|
6669
6701
|
});
|
|
6670
6702
|
|
|
6671
6703
|
const executePlayCall = async (): Promise<TOutput> => {
|
|
6672
|
-
//
|
|
6673
|
-
//
|
|
6674
|
-
//
|
|
6675
|
-
//
|
|
6704
|
+
// Scheduled children reserve the parent's durable play/descendant
|
|
6705
|
+
// budgets. Inline scalar children are function composition: their
|
|
6706
|
+
// Governor view changes only local lineage for recursion/depth checks
|
|
6707
|
+
// and delegates tool admission, pacing, and tool budgets to the parent.
|
|
6676
6708
|
//
|
|
6677
6709
|
// The SCHEDULED substrate still allocates a durable child run id (through
|
|
6678
6710
|
// the shared canonical builder so in-process and the workers_edge
|
|
@@ -6682,9 +6714,10 @@ export class PlayContextImpl {
|
|
|
6682
6714
|
// settlement. Their only identity is a replay-stable, call-site scoped
|
|
6683
6715
|
// composition namespace (`child:<playName>#<ordinal>`) used to scope tool
|
|
6684
6716
|
// receipts under the PARENT run. See child-composition-namespace below.
|
|
6717
|
+
const parentGovernor = this.currentExecutionGovernor;
|
|
6685
6718
|
const inlineChildGovernor = launchThroughScheduler
|
|
6686
6719
|
? null
|
|
6687
|
-
: await
|
|
6720
|
+
: await parentGovernor.forkInlineChild({
|
|
6688
6721
|
childPlayName: resolvedName,
|
|
6689
6722
|
childRunId: this.inlineChildCompositionNamespace(
|
|
6690
6723
|
resolvedName,
|
|
@@ -6692,7 +6725,7 @@ export class PlayContextImpl {
|
|
|
6692
6725
|
),
|
|
6693
6726
|
});
|
|
6694
6727
|
const childGovernance = launchThroughScheduler
|
|
6695
|
-
? await
|
|
6728
|
+
? await parentGovernor.forkChild({
|
|
6696
6729
|
childPlayName: resolvedName,
|
|
6697
6730
|
childRunId: buildChildRunId({
|
|
6698
6731
|
childPlayName: resolvedName,
|
|
@@ -6706,8 +6739,8 @@ export class PlayContextImpl {
|
|
|
6706
6739
|
})
|
|
6707
6740
|
: inlineChildGovernor!.snapshot();
|
|
6708
6741
|
const childPlaySlot = launchThroughScheduler
|
|
6709
|
-
? await
|
|
6710
|
-
:
|
|
6742
|
+
? await parentGovernor.acquireChildSubmitSlot()
|
|
6743
|
+
: null;
|
|
6711
6744
|
const rowStore = rowContext.getStore();
|
|
6712
6745
|
const producer = {
|
|
6713
6746
|
kind: 'play' as const,
|
|
@@ -6840,7 +6873,7 @@ export class PlayContextImpl {
|
|
|
6840
6873
|
// per-row inline-invocation sanity cap at creation).
|
|
6841
6874
|
const compositionNamespace = childGovernance.currentRunId;
|
|
6842
6875
|
const childExecutionScope = deriveChildRunExecutionScope(
|
|
6843
|
-
this.
|
|
6876
|
+
this.currentExecutionScope,
|
|
6844
6877
|
{
|
|
6845
6878
|
placement: 'inline',
|
|
6846
6879
|
runId: compositionNamespace,
|
|
@@ -6849,49 +6882,22 @@ export class PlayContextImpl {
|
|
|
6849
6882
|
},
|
|
6850
6883
|
);
|
|
6851
6884
|
this.inlineChildAggregates.total += 1;
|
|
6852
|
-
const inlineScalarChild =
|
|
6853
|
-
childExecutionDecision.reason === 'scalar_child';
|
|
6854
|
-
const childContext = createPlayContext({
|
|
6855
|
-
...this.#options,
|
|
6856
|
-
executionScope: childExecutionScope,
|
|
6857
|
-
playId: resolvedName,
|
|
6858
|
-
playName: resolvedName,
|
|
6859
|
-
runId: compositionNamespace,
|
|
6860
|
-
executorToken: inlineScalarChild
|
|
6861
|
-
? this.#options.executorToken
|
|
6862
|
-
: await this.mintChildExecutorToken({
|
|
6863
|
-
parentRunId: this.currentRunId,
|
|
6864
|
-
parentPlayName: this.#options.playName,
|
|
6865
|
-
childRunId: compositionNamespace,
|
|
6866
|
-
childPlayName: resolvedName,
|
|
6867
|
-
}),
|
|
6868
|
-
staticPipeline: resolvedPlay.staticPipeline ?? null,
|
|
6869
|
-
checkpoint: this.checkpoint,
|
|
6870
|
-
governance: undefined,
|
|
6871
|
-
executionGovernor: inlineChildGovernor!,
|
|
6872
|
-
...(inlineScalarChild
|
|
6873
|
-
? {}
|
|
6874
|
-
: {
|
|
6875
|
-
getRuntimeStepReceipt: undefined,
|
|
6876
|
-
getRuntimeStepReceipts: undefined,
|
|
6877
|
-
claimRuntimeStepReceipt: undefined,
|
|
6878
|
-
claimRuntimeStepReceipts: undefined,
|
|
6879
|
-
completeRuntimeStepReceipt: undefined,
|
|
6880
|
-
completeRuntimeStepReceipts: undefined,
|
|
6881
|
-
failRuntimeStepReceipt: undefined,
|
|
6882
|
-
failRuntimeStepReceipts: undefined,
|
|
6883
|
-
heartbeatRuntimeStepReceipts: undefined,
|
|
6884
|
-
skipRuntimeStepReceipt: undefined,
|
|
6885
|
-
}),
|
|
6886
|
-
});
|
|
6887
6885
|
try {
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6886
|
+
// A scalar child is a normal function call on the parent's context.
|
|
6887
|
+
// Async-local identity changes receipt and recursion scope without
|
|
6888
|
+
// allocating another PlayContext, tool queue, drain loop, resource
|
|
6889
|
+
// governor, or receipt client. Calls from every concurrent child
|
|
6890
|
+
// therefore reach the same proven parent batching path.
|
|
6891
|
+
const result = await inlineCompositionContext.run(
|
|
6892
|
+
{
|
|
6893
|
+
context: this,
|
|
6894
|
+
executionScope: childExecutionScope,
|
|
6895
|
+
governor: inlineChildGovernor!,
|
|
6896
|
+
playName: resolvedName,
|
|
6897
|
+
staticPipeline: resolvedPlay.staticPipeline ?? null,
|
|
6898
|
+
},
|
|
6899
|
+
() => this.executeResolvedPlay(resolvedPlay, this, input),
|
|
6892
6900
|
);
|
|
6893
|
-
await childContext.drainQueuedWork([childExecution]);
|
|
6894
|
-
const result = await childExecution;
|
|
6895
6901
|
this.inlineChildAggregates.ok += 1;
|
|
6896
6902
|
if (rowStore) {
|
|
6897
6903
|
this.emitScopedFieldMetaUpdate({
|
|
@@ -6912,7 +6918,6 @@ export class PlayContextImpl {
|
|
|
6912
6918
|
playId: resolvedName,
|
|
6913
6919
|
execution: options?.execution,
|
|
6914
6920
|
description: options?.description,
|
|
6915
|
-
nestedSteps: childContext.getSteps(),
|
|
6916
6921
|
});
|
|
6917
6922
|
return result as TOutput;
|
|
6918
6923
|
} catch (childError) {
|
|
@@ -6950,57 +6955,6 @@ export class PlayContextImpl {
|
|
|
6950
6955
|
}
|
|
6951
6956
|
}
|
|
6952
6957
|
|
|
6953
|
-
private async mintChildExecutorToken(input: {
|
|
6954
|
-
parentRunId: string;
|
|
6955
|
-
parentPlayName?: string | null;
|
|
6956
|
-
childRunId: string;
|
|
6957
|
-
childPlayName: string;
|
|
6958
|
-
}): Promise<string | undefined> {
|
|
6959
|
-
if (!this.#options.executorToken || !this.#options.baseUrl) {
|
|
6960
|
-
return this.#options.executorToken;
|
|
6961
|
-
}
|
|
6962
|
-
const parentPlayName = input.parentPlayName?.trim();
|
|
6963
|
-
if (!parentPlayName) {
|
|
6964
|
-
return this.#options.executorToken;
|
|
6965
|
-
}
|
|
6966
|
-
const response = await fetch(
|
|
6967
|
-
`${this.#options.baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_CURRENT_PATH}`,
|
|
6968
|
-
{
|
|
6969
|
-
method: 'POST',
|
|
6970
|
-
headers: {
|
|
6971
|
-
Authorization: `Bearer ${this.#options.executorToken}`,
|
|
6972
|
-
'Content-Type': 'application/json',
|
|
6973
|
-
...(await this.vercelProtectionHeaders()),
|
|
6974
|
-
},
|
|
6975
|
-
body: JSON.stringify({
|
|
6976
|
-
parentRunId: input.parentRunId,
|
|
6977
|
-
parentPlayName,
|
|
6978
|
-
childRunId: input.childRunId,
|
|
6979
|
-
childPlayName: input.childPlayName,
|
|
6980
|
-
}),
|
|
6981
|
-
},
|
|
6982
|
-
);
|
|
6983
|
-
const body = (await response.json().catch(() => null)) as {
|
|
6984
|
-
executorToken?: unknown;
|
|
6985
|
-
error?: unknown;
|
|
6986
|
-
} | null;
|
|
6987
|
-
if (!response.ok) {
|
|
6988
|
-
const message =
|
|
6989
|
-
typeof body?.error === 'string' && body.error.trim()
|
|
6990
|
-
? body.error.trim()
|
|
6991
|
-
: response.statusText;
|
|
6992
|
-
throw new Error(
|
|
6993
|
-
`ctx.runPlay failed to mint child executor token for "${input.childPlayName}": ${message} (status ${response.status}).`,
|
|
6994
|
-
);
|
|
6995
|
-
}
|
|
6996
|
-
if (typeof body?.executorToken !== 'string' || !body.executorToken.trim()) {
|
|
6997
|
-
throw new Error(
|
|
6998
|
-
`ctx.runPlay failed to mint child executor token for "${input.childPlayName}": response did not include executorToken.`,
|
|
6999
|
-
);
|
|
7000
|
-
}
|
|
7001
|
-
return body.executorToken.trim();
|
|
7002
|
-
}
|
|
7003
|
-
|
|
7004
6958
|
/**
|
|
7005
6959
|
* Replay-stable composition namespace for one inline `ctx.runPlay`
|
|
7006
6960
|
* invocation. Format `child:<playName>#<callKey>[@<rowScope>]`:
|
|
@@ -7358,7 +7312,7 @@ export class PlayContextImpl {
|
|
|
7358
7312
|
|
|
7359
7313
|
const rowStore = rowContext.getStore();
|
|
7360
7314
|
const scope = rowStore ? `row-${rowStore.rowId}` : 'workflow';
|
|
7361
|
-
const callIndexKey = `${scope}:${normalizedKey}`;
|
|
7315
|
+
const callIndexKey = `${this.currentExecutionScope.receipt.namespace}:${scope}:${normalizedKey}`;
|
|
7362
7316
|
const callIndex = this.stepCallIndexByKey.get(callIndexKey) ?? 0;
|
|
7363
7317
|
this.stepCallIndexByKey.set(callIndexKey, callIndex + 1);
|
|
7364
7318
|
const boundarySuffix = callIndex === 0 ? '' : `:${callIndex}`;
|
|
@@ -106,13 +106,6 @@ export interface PlayExecutionGovernor {
|
|
|
106
106
|
acquireRowSlot(opts?: { signal?: AbortSignal }): Promise<WorkLease>;
|
|
107
107
|
/** Block until a child-play submit slot is free. Released after submit, not terminal. */
|
|
108
108
|
acquireChildSubmitSlot(opts?: { signal?: AbortSignal }): Promise<WorkLease>;
|
|
109
|
-
/**
|
|
110
|
-
* Block until an in-process child-composition slot is free. Unlike a
|
|
111
|
-
* scheduled child's submit slot, this lease is held through child terminal
|
|
112
|
-
* execution so a large row fan-out cannot materialize thousands of child
|
|
113
|
-
* contexts and receipt closures at once.
|
|
114
|
-
*/
|
|
115
|
-
acquireInlineChildSlot(opts?: { signal?: AbortSignal }): Promise<WorkLease>;
|
|
116
109
|
/**
|
|
117
110
|
* Block until a global tool-concurrency slot AND the per-(org,provider) pacer
|
|
118
111
|
* permit are free, then charge the tool-call budget and return a lease. Order:
|
|
@@ -404,7 +397,6 @@ export function createPlayExecutionGovernor(
|
|
|
404
397
|
|
|
405
398
|
acquireRowSlot: (opts) => rowSlots.acquire(opts?.signal),
|
|
406
399
|
acquireChildSubmitSlot: (opts) => childPlaySlots.acquire(opts?.signal),
|
|
407
|
-
acquireInlineChildSlot: (opts) => childPlaySlots.acquire(opts?.signal),
|
|
408
400
|
|
|
409
401
|
async acquireToolSlot(toolId, opts) {
|
|
410
402
|
// 1. global tool-concurrency slot.
|
|
@@ -548,7 +540,7 @@ export function createPlayExecutionGovernor(
|
|
|
548
540
|
async forkInlineChild(childInput) {
|
|
549
541
|
return createInlineChildGovernor(
|
|
550
542
|
governor,
|
|
551
|
-
|
|
543
|
+
deriveInlineChildSnapshot(state, childInput, policy),
|
|
552
544
|
);
|
|
553
545
|
},
|
|
554
546
|
|
|
@@ -601,6 +593,38 @@ export function createPlayExecutionGovernor(
|
|
|
601
593
|
return governor;
|
|
602
594
|
}
|
|
603
595
|
|
|
596
|
+
function deriveInlineChildSnapshot(
|
|
597
|
+
parent: GovernanceSnapshot,
|
|
598
|
+
input: { childPlayName: string; childRunId: string },
|
|
599
|
+
policy: ResolvedExecutionPolicy,
|
|
600
|
+
): GovernanceSnapshot {
|
|
601
|
+
if (parent.ancestryPlayIds.includes(input.childPlayName)) {
|
|
602
|
+
throw new Error(
|
|
603
|
+
`Recursive play graph detected: ${[
|
|
604
|
+
...parent.ancestryPlayIds,
|
|
605
|
+
input.childPlayName,
|
|
606
|
+
].join(' -> ')}`,
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
const nextDepth = parent.callDepth + 1;
|
|
610
|
+
if (nextDepth > policy.budgets.maxPlayCallDepth) {
|
|
611
|
+
throw new GovernorBudgetError(
|
|
612
|
+
'playDepth',
|
|
613
|
+
nextDepth,
|
|
614
|
+
policy.budgets.maxPlayCallDepth,
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
return {
|
|
618
|
+
...parent,
|
|
619
|
+
currentRunId: input.childRunId,
|
|
620
|
+
currentPlayId: input.childPlayName,
|
|
621
|
+
ancestryPlayIds: [...parent.ancestryPlayIds, input.childPlayName],
|
|
622
|
+
ancestryRunIds: [...parent.ancestryRunIds, input.childRunId],
|
|
623
|
+
callDepth: nextDepth,
|
|
624
|
+
parentChildCalls: {},
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
|
|
604
628
|
function createInlineChildGovernor(
|
|
605
629
|
root: PlayExecutionGovernor,
|
|
606
630
|
initial: GovernanceSnapshot,
|
|
@@ -620,17 +644,6 @@ function createInlineChildGovernor(
|
|
|
620
644
|
policy: root.policy,
|
|
621
645
|
acquireRowSlot: (opts) => root.acquireRowSlot(opts),
|
|
622
646
|
acquireChildSubmitSlot: (opts) => root.acquireChildSubmitSlot(opts),
|
|
623
|
-
async acquireInlineChildSlot(opts) {
|
|
624
|
-
if (opts?.signal?.aborted) {
|
|
625
|
-
throw opts.signal.reason instanceof Error
|
|
626
|
-
? opts.signal.reason
|
|
627
|
-
: new Error('Slot acquire aborted.');
|
|
628
|
-
}
|
|
629
|
-
// This governor already runs inside a root inline-child lease. Descendant
|
|
630
|
-
// composition shares that admitted subtree slot; reacquiring the root
|
|
631
|
-
// semaphore here can deadlock when every admitted parent awaits a child.
|
|
632
|
-
return { release: () => {} };
|
|
633
|
-
},
|
|
634
647
|
acquireToolSlot: (toolId, opts) => root.acquireToolSlot(toolId, opts),
|
|
635
648
|
suggestedParallelism: (toolId, fallback) =>
|
|
636
649
|
root.suggestedParallelism(toolId, fallback),
|
|
@@ -686,7 +699,10 @@ function createInlineChildGovernor(
|
|
|
686
699
|
};
|
|
687
700
|
},
|
|
688
701
|
async forkInlineChild(input) {
|
|
689
|
-
return createInlineChildGovernor(
|
|
702
|
+
return createInlineChildGovernor(
|
|
703
|
+
child,
|
|
704
|
+
deriveInlineChildSnapshot(child.snapshot(), input, child.policy),
|
|
705
|
+
);
|
|
690
706
|
},
|
|
691
707
|
snapshot() {
|
|
692
708
|
const counters = root.snapshot();
|
|
@@ -95,7 +95,7 @@ import {
|
|
|
95
95
|
PLAY_RUNTIME_CONTRACT,
|
|
96
96
|
PLAY_RUNTIME_CONTRACT_HEADER,
|
|
97
97
|
} from './runtime-contract';
|
|
98
|
-
import {
|
|
98
|
+
import { PLAY_RUNTIME_API_COMPAT_PATH } from './runtime-api-paths';
|
|
99
99
|
import {
|
|
100
100
|
PLAY_RUNTIME_SHEET_ATTEMPT_LEASE_TTL_MS,
|
|
101
101
|
PLAY_RUNTIME_WORK_RECEIPT_LEASE_TTL_MS,
|
|
@@ -298,7 +298,6 @@ const RUNTIME_WORK_RECEIPT_LEASE_COLUMNS = [
|
|
|
298
298
|
'lease_expires_at',
|
|
299
299
|
] as const;
|
|
300
300
|
const RUNTIME_WORK_RECEIPT_FAILURE_KIND_COLUMN = 'failure_kind';
|
|
301
|
-
const RUNTIME_WORK_RECEIPT_KEY_INDEX = 'idx_deepline_step_receipts_k_unique';
|
|
302
301
|
const RUNTIME_WORK_RECEIPT_SELF_HEAL_COLUMNS = [
|
|
303
302
|
...RUNTIME_WORK_RECEIPT_LEASE_COLUMNS,
|
|
304
303
|
RUNTIME_WORK_RECEIPT_FAILURE_KIND_COLUMN,
|
|
@@ -505,7 +504,7 @@ function resolveRuntimeApiUrl(context: RuntimeApiContext): string {
|
|
|
505
504
|
if (!baseUrl) {
|
|
506
505
|
throw new Error('Runner runtime API requires a baseUrl.');
|
|
507
506
|
}
|
|
508
|
-
return `${baseUrl.replace(/\/$/, '')}${
|
|
507
|
+
return `${baseUrl.replace(/\/$/, '')}${PLAY_RUNTIME_API_COMPAT_PATH}`;
|
|
509
508
|
}
|
|
510
509
|
|
|
511
510
|
function resolveRuntimeApiHeaders(
|
|
@@ -587,10 +586,10 @@ async function postRuntimeApi<TResponse>(
|
|
|
587
586
|
? parsed.retry_after_ms
|
|
588
587
|
: RUNTIME_API_DEFAULT_RETRY_AFTER_MS;
|
|
589
588
|
const details =
|
|
590
|
-
typeof parsed?.
|
|
591
|
-
? parsed.
|
|
592
|
-
: typeof parsed?.
|
|
593
|
-
? parsed.
|
|
589
|
+
typeof parsed?.detail === 'string'
|
|
590
|
+
? parsed.detail
|
|
591
|
+
: typeof parsed?.details === 'string'
|
|
592
|
+
? parsed.details
|
|
594
593
|
: typeof parsed?.debug_error === 'string'
|
|
595
594
|
? parsed.debug_error
|
|
596
595
|
: null;
|
|
@@ -2043,22 +2042,6 @@ function isMissingRuntimeWorkReceiptSelfHealColumnError(
|
|
|
2043
2042
|
);
|
|
2044
2043
|
}
|
|
2045
2044
|
|
|
2046
|
-
function isMissingRuntimeWorkReceiptKeyConstraintError(
|
|
2047
|
-
error: unknown,
|
|
2048
|
-
): boolean {
|
|
2049
|
-
if (!error || typeof error !== 'object') {
|
|
2050
|
-
return false;
|
|
2051
|
-
}
|
|
2052
|
-
const code = 'code' in error ? String(error.code) : '';
|
|
2053
|
-
const message = 'message' in error ? String(error.message) : '';
|
|
2054
|
-
return (
|
|
2055
|
-
code === '42P10' ||
|
|
2056
|
-
/no unique or exclusion constraint matching the ON CONFLICT specification/i.test(
|
|
2057
|
-
message,
|
|
2058
|
-
)
|
|
2059
|
-
);
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
2045
|
function runtimeWorkReceiptEnsureCacheKey(
|
|
2063
2046
|
session: RuntimePostgresSession,
|
|
2064
2047
|
): string {
|
|
@@ -2138,29 +2121,22 @@ async function ensureRuntimeWorkReceiptTable(
|
|
|
2138
2121
|
session,
|
|
2139
2122
|
client,
|
|
2140
2123
|
);
|
|
2141
|
-
if (missingColumns.length
|
|
2142
|
-
await client.query(`
|
|
2143
|
-
ALTER TABLE ${workReceiptTable(session)}
|
|
2144
|
-
${missingColumns
|
|
2145
|
-
.map((column) => {
|
|
2146
|
-
const type =
|
|
2147
|
-
column === 'lease_expires_at'
|
|
2148
|
-
? 'timestamptz'
|
|
2149
|
-
: column === 'lease_owner_attempt'
|
|
2150
|
-
? 'integer'
|
|
2151
|
-
: column === RUNTIME_WORK_RECEIPT_FAILURE_KIND_COLUMN
|
|
2152
|
-
? 'smallint NOT NULL DEFAULT 0'
|
|
2153
|
-
: 'text';
|
|
2154
|
-
return `ADD COLUMN IF NOT EXISTS ${column} ${type}`;
|
|
2155
|
-
})
|
|
2156
|
-
.join(',\n ')}
|
|
2157
|
-
`);
|
|
2158
|
-
}
|
|
2124
|
+
if (missingColumns.length === 0) return;
|
|
2159
2125
|
await client.query(`
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2126
|
+
ALTER TABLE ${workReceiptTable(session)}
|
|
2127
|
+
${missingColumns
|
|
2128
|
+
.map((column) => {
|
|
2129
|
+
const type =
|
|
2130
|
+
column === 'lease_expires_at'
|
|
2131
|
+
? 'timestamptz'
|
|
2132
|
+
: column === 'lease_owner_attempt'
|
|
2133
|
+
? 'integer'
|
|
2134
|
+
: column === RUNTIME_WORK_RECEIPT_FAILURE_KIND_COLUMN
|
|
2135
|
+
? 'smallint NOT NULL DEFAULT 0'
|
|
2136
|
+
: 'text';
|
|
2137
|
+
return `ADD COLUMN IF NOT EXISTS ${column} ${type}`;
|
|
2138
|
+
})
|
|
2139
|
+
.join(',\n ')}
|
|
2164
2140
|
`);
|
|
2165
2141
|
})
|
|
2166
2142
|
.then(() => undefined);
|
|
@@ -2264,8 +2240,7 @@ async function withRuntimeWorkReceiptClient<T>(
|
|
|
2264
2240
|
} catch (error) {
|
|
2265
2241
|
if (
|
|
2266
2242
|
isMissingRelationError(error) ||
|
|
2267
|
-
isMissingRuntimeWorkReceiptSelfHealColumnError(error)
|
|
2268
|
-
isMissingRuntimeWorkReceiptKeyConstraintError(error)
|
|
2243
|
+
isMissingRuntimeWorkReceiptSelfHealColumnError(error)
|
|
2269
2244
|
) {
|
|
2270
2245
|
runtimeWorkReceiptEnsureCache.delete(
|
|
2271
2246
|
runtimeWorkReceiptEnsureCacheKey(session),
|
package/dist/cli/index.js
CHANGED
|
@@ -623,10 +623,10 @@ var SDK_RELEASE = {
|
|
|
623
623
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
624
624
|
// fields shipped in 0.1.153.
|
|
625
625
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
626
|
-
version: "0.1.
|
|
626
|
+
version: "0.1.217",
|
|
627
627
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
628
628
|
supportPolicy: {
|
|
629
|
-
latest: "0.1.
|
|
629
|
+
latest: "0.1.217",
|
|
630
630
|
minimumSupported: "0.1.53",
|
|
631
631
|
deprecatedBelow: "0.1.53",
|
|
632
632
|
commandMinimumSupported: [
|
|
@@ -13348,7 +13348,9 @@ function normalizeProgressForEnvelope(status, rowsInfo) {
|
|
|
13348
13348
|
const pending = getNumericField(progress, "pending") ?? (typeof total === "number" && typeof completed === "number" && typeof failed === "number" ? Math.max(0, total - completed - failed) : null);
|
|
13349
13349
|
return {
|
|
13350
13350
|
total,
|
|
13351
|
+
totalRows: total,
|
|
13351
13352
|
completed,
|
|
13353
|
+
completedRows: completed,
|
|
13352
13354
|
pending,
|
|
13353
13355
|
failed,
|
|
13354
13356
|
executed: getNumericField(progress, "executed"),
|
|
@@ -15483,7 +15485,7 @@ async function handleRunsList(args) {
|
|
|
15483
15485
|
return 0;
|
|
15484
15486
|
}
|
|
15485
15487
|
async function handleRunTail(args) {
|
|
15486
|
-
const usage = "Usage: deepline runs tail <run-id> [--json] [--compact]";
|
|
15488
|
+
const usage = "Usage: deepline runs tail <run-id> [--json | --jsonl] [--compact]";
|
|
15487
15489
|
let runId;
|
|
15488
15490
|
try {
|
|
15489
15491
|
runId = parseRunIdPositional(args, usage);
|
|
@@ -15499,13 +15501,18 @@ async function handleRunTail(args) {
|
|
|
15499
15501
|
);
|
|
15500
15502
|
return 1;
|
|
15501
15503
|
}
|
|
15502
|
-
if (arg.startsWith("--") && arg !== "--json" && arg !== "--compact") {
|
|
15504
|
+
if (arg.startsWith("--") && arg !== "--json" && arg !== "--jsonl" && arg !== "--compact") {
|
|
15503
15505
|
console.error(`${arg} is not supported by deepline runs tail.`);
|
|
15504
15506
|
return 1;
|
|
15505
15507
|
}
|
|
15506
15508
|
}
|
|
15509
|
+
if (args.includes("--json") && args.includes("--jsonl")) {
|
|
15510
|
+
console.error("--json and --jsonl cannot be used together.");
|
|
15511
|
+
return 1;
|
|
15512
|
+
}
|
|
15507
15513
|
const client2 = new DeeplineClient();
|
|
15508
|
-
const
|
|
15514
|
+
const jsonLines = args.includes("--jsonl");
|
|
15515
|
+
const jsonOutput = !jsonLines && argsWantJson(args);
|
|
15509
15516
|
const compact = args.includes("--compact");
|
|
15510
15517
|
const compactState = {
|
|
15511
15518
|
lastLogIndex: 0,
|
|
@@ -15515,7 +15522,16 @@ async function handleRunTail(args) {
|
|
|
15515
15522
|
lastStatusHeartbeatAt: 0
|
|
15516
15523
|
};
|
|
15517
15524
|
const status = await client2.runs.tail(runId, {
|
|
15518
|
-
onEvent:
|
|
15525
|
+
onEvent: jsonLines ? (event) => {
|
|
15526
|
+
process.stdout.write(
|
|
15527
|
+
`${JSON.stringify({
|
|
15528
|
+
schemaVersion: 1,
|
|
15529
|
+
kind: "play_run_event",
|
|
15530
|
+
event
|
|
15531
|
+
})}
|
|
15532
|
+
`
|
|
15533
|
+
);
|
|
15534
|
+
} : compact && !jsonOutput ? (event) => {
|
|
15519
15535
|
const transition = getStepTransitionLineFromLiveEvent(
|
|
15520
15536
|
event,
|
|
15521
15537
|
compactState
|
|
@@ -15545,7 +15561,12 @@ async function handleRunTail(args) {
|
|
|
15545
15561
|
);
|
|
15546
15562
|
}
|
|
15547
15563
|
});
|
|
15548
|
-
|
|
15564
|
+
if (jsonLines) {
|
|
15565
|
+
process.stdout.write(`${JSON.stringify(compactPlayStatus(status))}
|
|
15566
|
+
`);
|
|
15567
|
+
} else {
|
|
15568
|
+
writePlayResult(status, jsonOutput);
|
|
15569
|
+
}
|
|
15549
15570
|
return status.status === "failed" ? 1 : 0;
|
|
15550
15571
|
}
|
|
15551
15572
|
async function handleRunLogs(args) {
|
|
@@ -16911,19 +16932,26 @@ Examples:
|
|
|
16911
16932
|
Notes:
|
|
16912
16933
|
Streams live run events until the stream ends. Use get for current status and
|
|
16913
16934
|
logs for persisted log history. In human output, --compact prints deduplicated
|
|
16914
|
-
step transitions and progress instead of the full event stream.
|
|
16935
|
+
step transitions and progress instead of the full event stream. --json emits
|
|
16936
|
+
one terminal package. --jsonl emits canonical live events as JSON Lines and
|
|
16937
|
+
ends with the same compact package shape as runs get --json.
|
|
16915
16938
|
|
|
16916
16939
|
Examples:
|
|
16917
16940
|
deepline runs tail play/my-play/run/20260501t000000-000
|
|
16918
|
-
deepline runs tail play/my-play/run/20260501t000000-000 --compact
|
|
16941
|
+
deepline runs tail play/my-play/run/20260501t000000-000 --compact
|
|
16942
|
+
deepline runs tail play/my-play/run/20260501t000000-000 --jsonl
|
|
16919
16943
|
`
|
|
16920
|
-
).option("--json", "Emit
|
|
16944
|
+
).option("--json", "Emit one terminal JSON package after the run completes").option(
|
|
16945
|
+
"--jsonl",
|
|
16946
|
+
"Stream live events as JSON Lines, then the terminal package"
|
|
16947
|
+
).option(
|
|
16921
16948
|
"--compact",
|
|
16922
|
-
"Show deduplicated step transitions and progress
|
|
16949
|
+
"Show deduplicated human step transitions and progress"
|
|
16923
16950
|
).action(async (runId, options) => {
|
|
16924
16951
|
process.exitCode = await handleRunTail([
|
|
16925
16952
|
runId,
|
|
16926
16953
|
...options.json ? ["--json"] : [],
|
|
16954
|
+
...options.jsonl ? ["--jsonl"] : [],
|
|
16927
16955
|
...options.compact ? ["--compact"] : []
|
|
16928
16956
|
]);
|
|
16929
16957
|
});
|
package/dist/cli/index.mjs
CHANGED
|
@@ -608,10 +608,10 @@ var SDK_RELEASE = {
|
|
|
608
608
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
609
609
|
// fields shipped in 0.1.153.
|
|
610
610
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
611
|
-
version: "0.1.
|
|
611
|
+
version: "0.1.217",
|
|
612
612
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
613
613
|
supportPolicy: {
|
|
614
|
-
latest: "0.1.
|
|
614
|
+
latest: "0.1.217",
|
|
615
615
|
minimumSupported: "0.1.53",
|
|
616
616
|
deprecatedBelow: "0.1.53",
|
|
617
617
|
commandMinimumSupported: [
|
|
@@ -13377,7 +13377,9 @@ function normalizeProgressForEnvelope(status, rowsInfo) {
|
|
|
13377
13377
|
const pending = getNumericField(progress, "pending") ?? (typeof total === "number" && typeof completed === "number" && typeof failed === "number" ? Math.max(0, total - completed - failed) : null);
|
|
13378
13378
|
return {
|
|
13379
13379
|
total,
|
|
13380
|
+
totalRows: total,
|
|
13380
13381
|
completed,
|
|
13382
|
+
completedRows: completed,
|
|
13381
13383
|
pending,
|
|
13382
13384
|
failed,
|
|
13383
13385
|
executed: getNumericField(progress, "executed"),
|
|
@@ -15512,7 +15514,7 @@ async function handleRunsList(args) {
|
|
|
15512
15514
|
return 0;
|
|
15513
15515
|
}
|
|
15514
15516
|
async function handleRunTail(args) {
|
|
15515
|
-
const usage = "Usage: deepline runs tail <run-id> [--json] [--compact]";
|
|
15517
|
+
const usage = "Usage: deepline runs tail <run-id> [--json | --jsonl] [--compact]";
|
|
15516
15518
|
let runId;
|
|
15517
15519
|
try {
|
|
15518
15520
|
runId = parseRunIdPositional(args, usage);
|
|
@@ -15528,13 +15530,18 @@ async function handleRunTail(args) {
|
|
|
15528
15530
|
);
|
|
15529
15531
|
return 1;
|
|
15530
15532
|
}
|
|
15531
|
-
if (arg.startsWith("--") && arg !== "--json" && arg !== "--compact") {
|
|
15533
|
+
if (arg.startsWith("--") && arg !== "--json" && arg !== "--jsonl" && arg !== "--compact") {
|
|
15532
15534
|
console.error(`${arg} is not supported by deepline runs tail.`);
|
|
15533
15535
|
return 1;
|
|
15534
15536
|
}
|
|
15535
15537
|
}
|
|
15538
|
+
if (args.includes("--json") && args.includes("--jsonl")) {
|
|
15539
|
+
console.error("--json and --jsonl cannot be used together.");
|
|
15540
|
+
return 1;
|
|
15541
|
+
}
|
|
15536
15542
|
const client2 = new DeeplineClient();
|
|
15537
|
-
const
|
|
15543
|
+
const jsonLines = args.includes("--jsonl");
|
|
15544
|
+
const jsonOutput = !jsonLines && argsWantJson(args);
|
|
15538
15545
|
const compact = args.includes("--compact");
|
|
15539
15546
|
const compactState = {
|
|
15540
15547
|
lastLogIndex: 0,
|
|
@@ -15544,7 +15551,16 @@ async function handleRunTail(args) {
|
|
|
15544
15551
|
lastStatusHeartbeatAt: 0
|
|
15545
15552
|
};
|
|
15546
15553
|
const status = await client2.runs.tail(runId, {
|
|
15547
|
-
onEvent:
|
|
15554
|
+
onEvent: jsonLines ? (event) => {
|
|
15555
|
+
process.stdout.write(
|
|
15556
|
+
`${JSON.stringify({
|
|
15557
|
+
schemaVersion: 1,
|
|
15558
|
+
kind: "play_run_event",
|
|
15559
|
+
event
|
|
15560
|
+
})}
|
|
15561
|
+
`
|
|
15562
|
+
);
|
|
15563
|
+
} : compact && !jsonOutput ? (event) => {
|
|
15548
15564
|
const transition = getStepTransitionLineFromLiveEvent(
|
|
15549
15565
|
event,
|
|
15550
15566
|
compactState
|
|
@@ -15574,7 +15590,12 @@ async function handleRunTail(args) {
|
|
|
15574
15590
|
);
|
|
15575
15591
|
}
|
|
15576
15592
|
});
|
|
15577
|
-
|
|
15593
|
+
if (jsonLines) {
|
|
15594
|
+
process.stdout.write(`${JSON.stringify(compactPlayStatus(status))}
|
|
15595
|
+
`);
|
|
15596
|
+
} else {
|
|
15597
|
+
writePlayResult(status, jsonOutput);
|
|
15598
|
+
}
|
|
15578
15599
|
return status.status === "failed" ? 1 : 0;
|
|
15579
15600
|
}
|
|
15580
15601
|
async function handleRunLogs(args) {
|
|
@@ -16940,19 +16961,26 @@ Examples:
|
|
|
16940
16961
|
Notes:
|
|
16941
16962
|
Streams live run events until the stream ends. Use get for current status and
|
|
16942
16963
|
logs for persisted log history. In human output, --compact prints deduplicated
|
|
16943
|
-
step transitions and progress instead of the full event stream.
|
|
16964
|
+
step transitions and progress instead of the full event stream. --json emits
|
|
16965
|
+
one terminal package. --jsonl emits canonical live events as JSON Lines and
|
|
16966
|
+
ends with the same compact package shape as runs get --json.
|
|
16944
16967
|
|
|
16945
16968
|
Examples:
|
|
16946
16969
|
deepline runs tail play/my-play/run/20260501t000000-000
|
|
16947
|
-
deepline runs tail play/my-play/run/20260501t000000-000 --compact
|
|
16970
|
+
deepline runs tail play/my-play/run/20260501t000000-000 --compact
|
|
16971
|
+
deepline runs tail play/my-play/run/20260501t000000-000 --jsonl
|
|
16948
16972
|
`
|
|
16949
|
-
).option("--json", "Emit
|
|
16973
|
+
).option("--json", "Emit one terminal JSON package after the run completes").option(
|
|
16974
|
+
"--jsonl",
|
|
16975
|
+
"Stream live events as JSON Lines, then the terminal package"
|
|
16976
|
+
).option(
|
|
16950
16977
|
"--compact",
|
|
16951
|
-
"Show deduplicated step transitions and progress
|
|
16978
|
+
"Show deduplicated human step transitions and progress"
|
|
16952
16979
|
).action(async (runId, options) => {
|
|
16953
16980
|
process.exitCode = await handleRunTail([
|
|
16954
16981
|
runId,
|
|
16955
16982
|
...options.json ? ["--json"] : [],
|
|
16983
|
+
...options.jsonl ? ["--jsonl"] : [],
|
|
16956
16984
|
...options.compact ? ["--compact"] : []
|
|
16957
16985
|
]);
|
|
16958
16986
|
});
|
package/dist/index.js
CHANGED
|
@@ -422,10 +422,10 @@ var SDK_RELEASE = {
|
|
|
422
422
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
423
423
|
// fields shipped in 0.1.153.
|
|
424
424
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
425
|
-
version: "0.1.
|
|
425
|
+
version: "0.1.217",
|
|
426
426
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
427
427
|
supportPolicy: {
|
|
428
|
-
latest: "0.1.
|
|
428
|
+
latest: "0.1.217",
|
|
429
429
|
minimumSupported: "0.1.53",
|
|
430
430
|
deprecatedBelow: "0.1.53",
|
|
431
431
|
commandMinimumSupported: [
|
package/dist/index.mjs
CHANGED
|
@@ -352,10 +352,10 @@ var SDK_RELEASE = {
|
|
|
352
352
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
353
353
|
// fields shipped in 0.1.153.
|
|
354
354
|
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
355
|
-
version: "0.1.
|
|
355
|
+
version: "0.1.217",
|
|
356
356
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
357
357
|
supportPolicy: {
|
|
358
|
-
latest: "0.1.
|
|
358
|
+
latest: "0.1.217",
|
|
359
359
|
minimumSupported: "0.1.53",
|
|
360
360
|
deprecatedBelow: "0.1.53",
|
|
361
361
|
commandMinimumSupported: [
|
package/package.json
CHANGED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
PLAY_RUNTIME_API_CURRENT_PATH,
|
|
3
|
-
PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_CURRENT_PATH,
|
|
4
|
-
PLAY_RUNTIME_EGRESS_FETCH_CURRENT_PATH,
|
|
5
|
-
} from '../../../shared_libs/play-runtime/runtime-api-paths';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Paths a credential-isolated Daytona sandbox may send through the
|
|
9
|
-
* coordinator. The sandbox receives the coordinator as its runtime origin so
|
|
10
|
-
* it never holds the Vercel protection-bypass credential; the harness owns the
|
|
11
|
-
* protected upstream hop. Keep this deliberately narrower than the harness
|
|
12
|
-
* allowlist: a coordinator URL is public, while the harness is a service
|
|
13
|
-
* binding.
|
|
14
|
-
*/
|
|
15
|
-
export function isCoordinatorRuntimeProxyPath(pathname: string): boolean {
|
|
16
|
-
return (
|
|
17
|
-
pathname === PLAY_RUNTIME_API_CURRENT_PATH ||
|
|
18
|
-
pathname === PLAY_RUNTIME_CHILD_EXECUTOR_TOKEN_CURRENT_PATH ||
|
|
19
|
-
pathname === PLAY_RUNTIME_EGRESS_FETCH_CURRENT_PATH ||
|
|
20
|
-
pathname === '/api/v2/plays/run' ||
|
|
21
|
-
/^\/api\/v2\/plays\/runtime-tools\/[^/]+(?:\/(?:auth-scope|event-wait))?$/.test(
|
|
22
|
-
pathname,
|
|
23
|
-
) ||
|
|
24
|
-
/^\/api\/v2\/integrations\/[^/]+\/(?:execute|stream)$/.test(pathname)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export function executorTokenFromAuthorizationHeader(
|
|
29
|
-
authorization: string | null,
|
|
30
|
-
): string | null {
|
|
31
|
-
const match = /^Bearer\s+(.+)$/i.exec(authorization?.trim() ?? '');
|
|
32
|
-
const token = match?.[1]?.trim();
|
|
33
|
-
return token || null;
|
|
34
|
-
}
|