deepline 0.3.9 → 0.3.10
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/runner-backends/backends/daytona-payload-transport.ts +5 -2
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +98 -1
- package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -192,7 +192,7 @@ export const SDK_RELEASE = {
|
|
|
192
192
|
// 0.3.0 introduces raw-v2: complete scrubbed provider responses are
|
|
193
193
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
194
194
|
// getters keep their established compatibility behavior.
|
|
195
|
-
version: '0.3.
|
|
195
|
+
version: '0.3.10',
|
|
196
196
|
updateSummary:
|
|
197
197
|
'New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.',
|
|
198
198
|
contracts: {
|
|
@@ -68,6 +68,7 @@ export type StagedDaytonaPayload = {
|
|
|
68
68
|
runtimeCompletedPath: string;
|
|
69
69
|
terminationDiagnosticPath: string;
|
|
70
70
|
progressEventPath: string;
|
|
71
|
+
startupDiagnosticPath: string;
|
|
71
72
|
};
|
|
72
73
|
|
|
73
74
|
export type RemoteRunnerPayloadSandbox = {
|
|
@@ -573,6 +574,7 @@ export async function stageRunnerPayload(input: {
|
|
|
573
574
|
const runtimeLimitMarkerPath = `${workDir}/deepline-play-runtime-limit-${randomUUID()}.txt`;
|
|
574
575
|
const terminationDiagnosticPath = `${workDir}/deepline-play-termination-${randomUUID()}.json`;
|
|
575
576
|
const progressEventPath = `${workDir}/deepline-play-progress-${randomUUID()}.jsonl`;
|
|
577
|
+
const startupDiagnosticPath = `${workDir}/deepline-play-startup-${randomUUID()}.json`;
|
|
576
578
|
const runnerTraceEnv =
|
|
577
579
|
process.env.DEEPLINE_RUNTIME_RECEIPT_TRACE === '1'
|
|
578
580
|
? 'DEEPLINE_RUNTIME_RECEIPT_TRACE=1 '
|
|
@@ -598,7 +600,7 @@ export async function stageRunnerPayload(input: {
|
|
|
598
600
|
artifactCodePath,
|
|
599
601
|
artifactSourceMapPath,
|
|
600
602
|
crashPusherPath,
|
|
601
|
-
})} && DEEPLINE_PLAY_RUNNER_RUNTIME_STARTED_PATH=${shellQuote(runtimeStartedPath)} DEEPLINE_PLAY_RUNNER_RUNTIME_COMPLETED_PATH=${shellQuote(runtimeCompletedPath)} DEEPLINE_PLAY_RUNNER_PROGRESS_EVENT_PATH=${shellQuote(progressEventPath)} DEEPLINE_PLAY_RUNNER_STDOUT_EVENT_MODE=compact ${runnerTraceEnv}${watchedRunnerCommand}`;
|
|
603
|
+
})} && DEEPLINE_PLAY_RUNNER_RUNTIME_STARTED_PATH=${shellQuote(runtimeStartedPath)} DEEPLINE_PLAY_RUNNER_RUNTIME_COMPLETED_PATH=${shellQuote(runtimeCompletedPath)} DEEPLINE_PLAY_RUNNER_PROGRESS_EVENT_PATH=${shellQuote(progressEventPath)} DEEPLINE_PLAY_RUNNER_STARTUP_DIAGNOSTIC_PATH=${shellQuote(startupDiagnosticPath)} DEEPLINE_PLAY_RUNNER_STDOUT_EVENT_MODE=compact ${runnerTraceEnv}${watchedRunnerCommand}`;
|
|
602
604
|
// Crash-containment epilogue: runs UNCONDITIONALLY after the runner exits and
|
|
603
605
|
// pushes the parsed (or synthesized) terminal to the gateway so the parked
|
|
604
606
|
// worker wakes within seconds of ANY runner death — process.exit abuse, OOM
|
|
@@ -607,7 +609,7 @@ export async function stageRunnerPayload(input: {
|
|
|
607
609
|
// Its own retry diagnostics are kept in a separate log: appending them to
|
|
608
610
|
// `outputPath` after a near-gateway-sized result could hide that result from
|
|
609
611
|
// a later bounded-tail recovery read.
|
|
610
|
-
const command = `rm -f ${shellQuote(outputPath)} ${shellQuote(crashPusherLogPath)} ${shellQuote(exitCodePath)} ${shellQuote(oomKillBaselinePath)} ${shellQuote(runtimeStartedPath)} ${shellQuote(runtimeCompletedPath)} ${shellQuote(runtimeLimitMarkerPath)} ${shellQuote(terminationDiagnosticPath)} ${shellQuote(progressEventPath)} ${shellQuote(`${progressEventPath}.*`)}; ( awk '$1 == "oom_kill" { print $2 }' /sys/fs/cgroup/memory.events 2>/dev/null || true ) > ${shellQuote(oomKillBaselinePath)}; ( ${runnerCommand} ) > ${shellQuote(outputPath)} 2>&1; code=$?; printf '%s' "$code" > ${shellQuote(exitCodePath)}; node ${shellQuote(crashPusherPath)} ${shellQuote(configPath)} "$code" ${shellQuote(outputPath)} ${shellQuote(runtimeLimitMarkerPath)} ${shellQuote(oomKillBaselinePath)} /sys/fs/cgroup/memory.events ${shellQuote(terminationDiagnosticPath)} > ${shellQuote(crashPusherLogPath)} 2>&1 || true; printf 'deepline runner output captured: %s\\n' ${shellQuote(outputPath)}; exit "$code"`;
|
|
612
|
+
const command = `rm -f ${shellQuote(outputPath)} ${shellQuote(crashPusherLogPath)} ${shellQuote(exitCodePath)} ${shellQuote(oomKillBaselinePath)} ${shellQuote(runtimeStartedPath)} ${shellQuote(runtimeCompletedPath)} ${shellQuote(runtimeLimitMarkerPath)} ${shellQuote(terminationDiagnosticPath)} ${shellQuote(progressEventPath)} ${shellQuote(`${progressEventPath}.*`)} ${shellQuote(startupDiagnosticPath)}; ( awk '$1 == "oom_kill" { print $2 }' /sys/fs/cgroup/memory.events 2>/dev/null || true ) > ${shellQuote(oomKillBaselinePath)}; ( ${runnerCommand} ) > ${shellQuote(outputPath)} 2>&1; code=$?; printf '%s' "$code" > ${shellQuote(exitCodePath)}; node ${shellQuote(crashPusherPath)} ${shellQuote(configPath)} "$code" ${shellQuote(outputPath)} ${shellQuote(runtimeLimitMarkerPath)} ${shellQuote(oomKillBaselinePath)} /sys/fs/cgroup/memory.events ${shellQuote(terminationDiagnosticPath)} > ${shellQuote(crashPusherLogPath)} 2>&1 || true; printf 'deepline runner output captured: %s\\n' ${shellQuote(outputPath)}; exit "$code"`;
|
|
611
613
|
|
|
612
614
|
return {
|
|
613
615
|
workDir: input.workDir,
|
|
@@ -617,6 +619,7 @@ export async function stageRunnerPayload(input: {
|
|
|
617
619
|
runtimeCompletedPath,
|
|
618
620
|
terminationDiagnosticPath,
|
|
619
621
|
progressEventPath,
|
|
622
|
+
startupDiagnosticPath,
|
|
620
623
|
};
|
|
621
624
|
}
|
|
622
625
|
|
|
@@ -13,9 +13,88 @@ export type DetachedDaytonaStartupDiagnostic = {
|
|
|
13
13
|
node: number;
|
|
14
14
|
states: Record<string, number>;
|
|
15
15
|
} | null;
|
|
16
|
+
runnerStartup: {
|
|
17
|
+
phase: 'booted' | 'heartbeat_transport';
|
|
18
|
+
outcome?:
|
|
19
|
+
| 'ok'
|
|
20
|
+
| 'terminal'
|
|
21
|
+
| 'redirect'
|
|
22
|
+
| 'gateway_4xx'
|
|
23
|
+
| 'gateway_5xx'
|
|
24
|
+
| 'protocol_error'
|
|
25
|
+
| 'timeout'
|
|
26
|
+
| 'network_error';
|
|
27
|
+
status?: number;
|
|
28
|
+
errorCode?: string;
|
|
29
|
+
transportAttemptId?: string;
|
|
30
|
+
} | null;
|
|
16
31
|
errors: string[];
|
|
17
32
|
};
|
|
18
33
|
|
|
34
|
+
function parseRunnerStartupDiagnostic(
|
|
35
|
+
value: Buffer,
|
|
36
|
+
): DetachedDaytonaStartupDiagnostic['runnerStartup'] {
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(value.toString('utf-8')) as Record<
|
|
39
|
+
string,
|
|
40
|
+
unknown
|
|
41
|
+
>;
|
|
42
|
+
if (
|
|
43
|
+
parsed.schemaVersion !== 1 ||
|
|
44
|
+
(parsed.phase !== 'booted' && parsed.phase !== 'heartbeat_transport')
|
|
45
|
+
) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
if (parsed.phase === 'booted') return { phase: 'booted' };
|
|
49
|
+
const event = parsed.event;
|
|
50
|
+
if (!event || typeof event !== 'object') return null;
|
|
51
|
+
const record = event as Record<string, unknown>;
|
|
52
|
+
const allowedOutcomes = new Set([
|
|
53
|
+
'ok',
|
|
54
|
+
'terminal',
|
|
55
|
+
'redirect',
|
|
56
|
+
'gateway_4xx',
|
|
57
|
+
'gateway_5xx',
|
|
58
|
+
'protocol_error',
|
|
59
|
+
'timeout',
|
|
60
|
+
'network_error',
|
|
61
|
+
]);
|
|
62
|
+
if (
|
|
63
|
+
typeof record.outcome !== 'string' ||
|
|
64
|
+
!allowedOutcomes.has(record.outcome)
|
|
65
|
+
)
|
|
66
|
+
return null;
|
|
67
|
+
const diagnostic: NonNullable<
|
|
68
|
+
DetachedDaytonaStartupDiagnostic['runnerStartup']
|
|
69
|
+
> = {
|
|
70
|
+
phase: 'heartbeat_transport',
|
|
71
|
+
outcome: record.outcome as NonNullable<
|
|
72
|
+
DetachedDaytonaStartupDiagnostic['runnerStartup']
|
|
73
|
+
>['outcome'],
|
|
74
|
+
};
|
|
75
|
+
if (
|
|
76
|
+
typeof record.status === 'number' &&
|
|
77
|
+
Number.isSafeInteger(record.status) &&
|
|
78
|
+
record.status >= 100 &&
|
|
79
|
+
record.status <= 599
|
|
80
|
+
)
|
|
81
|
+
diagnostic.status = record.status;
|
|
82
|
+
if (
|
|
83
|
+
typeof record.errorCode === 'string' &&
|
|
84
|
+
/^[A-Za-z0-9_]{1,64}$/.test(record.errorCode)
|
|
85
|
+
)
|
|
86
|
+
diagnostic.errorCode = record.errorCode;
|
|
87
|
+
if (
|
|
88
|
+
typeof record.transportAttemptId === 'string' &&
|
|
89
|
+
/^[a-f0-9-]{36}$/i.test(record.transportAttemptId)
|
|
90
|
+
)
|
|
91
|
+
diagnostic.transportAttemptId = record.transportAttemptId;
|
|
92
|
+
return diagnostic;
|
|
93
|
+
} catch {
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
19
98
|
function summarizeProcesses(value: unknown): {
|
|
20
99
|
total: number;
|
|
21
100
|
node: number;
|
|
@@ -50,6 +129,7 @@ export async function inspectDetachedDaytonaStartup(input: {
|
|
|
50
129
|
sessionId: string;
|
|
51
130
|
cmdId: string;
|
|
52
131
|
exitCodePath: string;
|
|
132
|
+
startupDiagnosticPath?: string;
|
|
53
133
|
}): Promise<DetachedDaytonaStartupDiagnostic> {
|
|
54
134
|
const errors: string[] = [];
|
|
55
135
|
const diagnostic: DetachedDaytonaStartupDiagnostic = {
|
|
@@ -61,6 +141,7 @@ export async function inspectDetachedDaytonaStartup(input: {
|
|
|
61
141
|
sessionCommandCount: null,
|
|
62
142
|
exitCodeFile: null,
|
|
63
143
|
processSummary: null,
|
|
144
|
+
runnerStartup: null,
|
|
64
145
|
errors,
|
|
65
146
|
};
|
|
66
147
|
|
|
@@ -87,6 +168,18 @@ export async function inspectDetachedDaytonaStartup(input: {
|
|
|
87
168
|
diagnostic.exitCodeFile = Number.isFinite(value) ? value : null;
|
|
88
169
|
})
|
|
89
170
|
.catch(() => errors.push('exit_code_file_unavailable')),
|
|
171
|
+
...(input.startupDiagnosticPath
|
|
172
|
+
? [
|
|
173
|
+
input.sandbox.fs
|
|
174
|
+
.downloadFile(input.startupDiagnosticPath, 5)
|
|
175
|
+
.then((file) => {
|
|
176
|
+
diagnostic.runnerStartup = parseRunnerStartupDiagnostic(file);
|
|
177
|
+
if (!diagnostic.runnerStartup)
|
|
178
|
+
errors.push('startup_diagnostic_invalid');
|
|
179
|
+
})
|
|
180
|
+
.catch(() => errors.push('startup_diagnostic_unavailable')),
|
|
181
|
+
]
|
|
182
|
+
: []),
|
|
90
183
|
input.sandbox.process
|
|
91
184
|
.executeCommand('ps -eo stat=,comm=', undefined, {}, 5)
|
|
92
185
|
.then((result) => {
|
|
@@ -130,6 +223,7 @@ export type DetachedDaytonaRunnerSupervisor = {
|
|
|
130
223
|
start(input: {
|
|
131
224
|
command: string;
|
|
132
225
|
exitCodePath: string;
|
|
226
|
+
startupDiagnosticPath?: string;
|
|
133
227
|
}): Promise<Extract<DetachedDaytonaRunnerState, { phase: 'ready' }>>;
|
|
134
228
|
};
|
|
135
229
|
|
|
@@ -283,7 +377,7 @@ export function prepareDetachedDaytonaRunner(input: {
|
|
|
283
377
|
let started = false;
|
|
284
378
|
|
|
285
379
|
return {
|
|
286
|
-
async start({ command, exitCodePath }) {
|
|
380
|
+
async start({ command, exitCodePath, startupDiagnosticPath }) {
|
|
287
381
|
if (started) {
|
|
288
382
|
throw new Error(
|
|
289
383
|
`Detached Daytona runner session ${input.sessionId} was already started.`,
|
|
@@ -319,6 +413,7 @@ export function prepareDetachedDaytonaRunner(input: {
|
|
|
319
413
|
sessionId: state.sessionId,
|
|
320
414
|
cmdId: state.cmdId,
|
|
321
415
|
exitCodePath,
|
|
416
|
+
startupDiagnosticPath,
|
|
322
417
|
readiness: input.readiness,
|
|
323
418
|
baselineHeartbeatAt: state.baselineHeartbeatAt,
|
|
324
419
|
}),
|
|
@@ -342,6 +437,7 @@ export async function confirmDetachedDaytonaRunnerReady(input: {
|
|
|
342
437
|
sessionId: string;
|
|
343
438
|
cmdId: string;
|
|
344
439
|
exitCodePath: string;
|
|
440
|
+
startupDiagnosticPath?: string;
|
|
345
441
|
readiness: DetachedRunnerReadinessPort;
|
|
346
442
|
baselineHeartbeatAt: string | null;
|
|
347
443
|
timeoutMs?: number;
|
|
@@ -385,6 +481,7 @@ export async function confirmDetachedDaytonaRunnerReady(input: {
|
|
|
385
481
|
sessionId: input.sessionId,
|
|
386
482
|
cmdId: input.cmdId,
|
|
387
483
|
exitCodePath: input.exitCodePath,
|
|
484
|
+
startupDiagnosticPath: input.startupDiagnosticPath,
|
|
388
485
|
});
|
|
389
486
|
diagnostic.schedulerReadinessObserved = false;
|
|
390
487
|
diagnostic.schedulerReadinessResponses = schedulerReadinessResponses;
|
|
@@ -1292,6 +1292,7 @@ export const daytonaPlayRunnerBackend: PlayRunnerBackend = {
|
|
|
1292
1292
|
start = await detachedRunner.start({
|
|
1293
1293
|
command: stagedPayload.command,
|
|
1294
1294
|
exitCodePath: stagedPayload.exitCodePath,
|
|
1295
|
+
startupDiagnosticPath: stagedPayload.startupDiagnosticPath,
|
|
1295
1296
|
});
|
|
1296
1297
|
} catch (error) {
|
|
1297
1298
|
if (
|
package/dist/cli/index.js
CHANGED
|
@@ -1047,7 +1047,7 @@ var SDK_RELEASE = {
|
|
|
1047
1047
|
// 0.3.0 introduces raw-v2: complete scrubbed provider responses are
|
|
1048
1048
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1049
1049
|
// getters keep their established compatibility behavior.
|
|
1050
|
-
version: "0.3.
|
|
1050
|
+
version: "0.3.10",
|
|
1051
1051
|
updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
|
|
1052
1052
|
contracts: {
|
|
1053
1053
|
api: {
|
package/dist/cli/index.mjs
CHANGED
|
@@ -1033,7 +1033,7 @@ var SDK_RELEASE = {
|
|
|
1033
1033
|
// 0.3.0 introduces raw-v2: complete scrubbed provider responses are
|
|
1034
1034
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
1035
1035
|
// getters keep their established compatibility behavior.
|
|
1036
|
-
version: "0.3.
|
|
1036
|
+
version: "0.3.10",
|
|
1037
1037
|
updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
|
|
1038
1038
|
contracts: {
|
|
1039
1039
|
api: {
|
package/dist/index.js
CHANGED
|
@@ -783,7 +783,7 @@ var SDK_RELEASE = {
|
|
|
783
783
|
// 0.3.0 introduces raw-v2: complete scrubbed provider responses are
|
|
784
784
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
785
785
|
// getters keep their established compatibility behavior.
|
|
786
|
-
version: "0.3.
|
|
786
|
+
version: "0.3.10",
|
|
787
787
|
updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
|
|
788
788
|
contracts: {
|
|
789
789
|
api: {
|
package/dist/index.mjs
CHANGED
|
@@ -706,7 +706,7 @@ var SDK_RELEASE = {
|
|
|
706
706
|
// 0.3.0 introduces raw-v2: complete scrubbed provider responses are
|
|
707
707
|
// available at toolResponse.rawV2 while toolResponse.raw and all declared
|
|
708
708
|
// getters keep their established compatibility behavior.
|
|
709
|
-
version: "0.3.
|
|
709
|
+
version: "0.3.10",
|
|
710
710
|
updateSummary: "New raw-v2 tool responses preserve complete scrubbed provider envelopes at toolResponse.rawV2, including JSON:API included resources, links, cursors, and totals. Existing toolResponse.raw and declared getters keep working unchanged.",
|
|
711
711
|
contracts: {
|
|
712
712
|
api: {
|