deepline 0.1.212 → 0.1.214

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.
Files changed (41) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +167 -329
  2. package/dist/bundling-sources/sdk/src/client.ts +2 -2
  3. package/dist/bundling-sources/sdk/src/index.ts +2 -0
  4. package/dist/bundling-sources/sdk/src/play.ts +8 -1
  5. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +11 -1
  6. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  7. package/dist/bundling-sources/sdk/src/types.ts +3 -3
  8. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +49 -0
  9. package/dist/bundling-sources/shared_libs/play-runtime/child-execution-placement.ts +14 -0
  10. package/dist/bundling-sources/shared_libs/play-runtime/child-execution-strategy.ts +57 -23
  11. package/dist/bundling-sources/shared_libs/play-runtime/completed-receipt-cache.ts +166 -0
  12. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +209 -123
  13. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +2 -0
  14. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +30 -1
  15. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +160 -2
  16. package/dist/bundling-sources/shared_libs/play-runtime/gateway-auth-session.ts +93 -0
  17. package/dist/bundling-sources/shared_libs/play-runtime/play-call-execution.ts +1 -0
  18. package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +1 -1
  19. package/dist/bundling-sources/shared_libs/play-runtime/receipt-completion-sink.ts +16 -1
  20. package/dist/bundling-sources/shared_libs/play-runtime/receipt-state-sink.ts +10 -0
  21. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +80 -3
  22. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-session-execution.ts +94 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +54 -1
  24. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +477 -85
  25. package/dist/bundling-sources/shared_libs/play-runtime/runtime-postgres-admission.ts +162 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +2 -2
  27. package/dist/bundling-sources/shared_libs/play-runtime/sheet-attempt-sql.ts +16 -17
  28. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +1 -0
  29. package/dist/bundling-sources/shared_libs/plays/static-pipeline.ts +2 -4
  30. package/dist/cli/index.js +50 -436
  31. package/dist/cli/index.mjs +50 -436
  32. package/dist/{compiler-manifest-j6z8qzpd.d.mts → compiler-manifest-BhgZ23A4.d.mts} +1 -0
  33. package/dist/{compiler-manifest-j6z8qzpd.d.ts → compiler-manifest-BhgZ23A4.d.ts} +1 -0
  34. package/dist/index.d.mts +11 -8
  35. package/dist/index.d.ts +11 -8
  36. package/dist/index.js +4 -4
  37. package/dist/index.mjs +4 -4
  38. package/dist/plays/bundle-play-file.d.mts +2 -2
  39. package/dist/plays/bundle-play-file.d.ts +2 -2
  40. package/dist/plays/bundle-play-file.mjs +1 -1
  41. package/package.json +1 -1
@@ -1,5 +1,99 @@
1
1
  import type { DaytonaSandbox } from './daytona-lifecycle';
2
2
 
3
+ export type DetachedDaytonaStartupDiagnostic = {
4
+ commandFound: boolean;
5
+ exitCode: number | null;
6
+ sessionFound: boolean;
7
+ sessionCommandCount: number | null;
8
+ exitCodeFile: number | null;
9
+ processSummary: {
10
+ total: number;
11
+ node: number;
12
+ states: Record<string, number>;
13
+ } | null;
14
+ errors: string[];
15
+ };
16
+
17
+ function summarizeProcesses(value: unknown): {
18
+ total: number;
19
+ node: number;
20
+ states: Record<string, number>;
21
+ } | null {
22
+ if (typeof value !== 'string' || !value.trim()) return null;
23
+ const rows = value
24
+ .split('\n')
25
+ .map((line) => line.trim().split(/\s+/, 2))
26
+ .filter(([state, command]) => Boolean(state && command));
27
+ const states: Record<string, number> = {};
28
+ let node = 0;
29
+ for (const [state, command] of rows) {
30
+ const normalizedState = state![0]?.toUpperCase() || '?';
31
+ states[normalizedState] = (states[normalizedState] ?? 0) + 1;
32
+ if (/^node(?:-|$)/i.test(command!)) node += 1;
33
+ }
34
+ return { total: rows.length, node, states };
35
+ }
36
+
37
+ /**
38
+ * Inspect an accepted detached command without exposing its command line or
39
+ * environment. Daytona's command model has no queued/running state, so the
40
+ * combination of session membership, a numeric exit marker, and a
41
+ * aggregate process counts are the narrowest useful startup diagnostic.
42
+ * Process names are reduced to a Node count before logging; runner logs,
43
+ * output, and arbitrary process names are deliberately excluded because no
44
+ * heuristic redactor can guarantee removal of arbitrary customer secrets.
45
+ */
46
+ export async function inspectDetachedDaytonaStartup(input: {
47
+ sandbox: DaytonaSandbox;
48
+ sessionId: string;
49
+ cmdId: string;
50
+ exitCodePath: string;
51
+ }): Promise<DetachedDaytonaStartupDiagnostic> {
52
+ const errors: string[] = [];
53
+ const diagnostic: DetachedDaytonaStartupDiagnostic = {
54
+ commandFound: false,
55
+ exitCode: null,
56
+ sessionFound: false,
57
+ sessionCommandCount: null,
58
+ exitCodeFile: null,
59
+ processSummary: null,
60
+ errors,
61
+ };
62
+
63
+ await Promise.all([
64
+ input.sandbox.process
65
+ .getSessionCommand(input.sessionId, input.cmdId)
66
+ .then((command) => {
67
+ diagnostic.commandFound = true;
68
+ diagnostic.exitCode =
69
+ typeof command.exitCode === 'number' ? command.exitCode : null;
70
+ })
71
+ .catch(() => errors.push('get_session_command_failed')),
72
+ input.sandbox.process
73
+ .getSession(input.sessionId)
74
+ .then((session) => {
75
+ diagnostic.sessionFound = true;
76
+ diagnostic.sessionCommandCount = session.commands.length;
77
+ })
78
+ .catch(() => errors.push('get_session_failed')),
79
+ input.sandbox.fs
80
+ .downloadFile(input.exitCodePath, 5)
81
+ .then((file) => {
82
+ const value = Number.parseInt(file.toString('utf-8').trim(), 10);
83
+ diagnostic.exitCodeFile = Number.isFinite(value) ? value : null;
84
+ })
85
+ .catch(() => errors.push('exit_code_file_unavailable')),
86
+ input.sandbox.process
87
+ .executeCommand('ps -eo stat=,comm=', undefined, {}, 5)
88
+ .then((result) => {
89
+ diagnostic.processSummary = summarizeProcesses(result.result);
90
+ })
91
+ .catch(() => errors.push('process_snapshot_failed')),
92
+ ]);
93
+
94
+ return diagnostic;
95
+ }
96
+
3
97
  /**
4
98
  * Detached Daytona command start (push-execution B2-final).
5
99
  *
@@ -32,7 +32,10 @@ import {
32
32
  validateDaytonaExecutionContext,
33
33
  } from './daytona-lifecycle';
34
34
  import { stageDaytonaRunnerPayload } from './daytona-payload-transport';
35
- import { startDetachedDaytonaCommand } from './daytona-session-execution';
35
+ import {
36
+ inspectDetachedDaytonaStartup,
37
+ startDetachedDaytonaCommand,
38
+ } from './daytona-session-execution';
36
39
 
37
40
  const DAYTONA_EXECUTE_TIMEOUT_SECONDS = STANDARD_PLAY_RUNTIME_LIMIT_SECONDS;
38
41
  const STANDARD_WORKFLOW_RUNTIME_LIMIT_ERROR = `Based on this plan, max runtime is ${STANDARD_PLAY_RUNTIME_LIMIT_LABEL}. Use smaller batches; ask for runtime.`;
@@ -42,6 +45,8 @@ const DAYTONA_RUNTIME_INITIALIZATION_MAX_ATTEMPTS = 2;
42
45
  const DAYTONA_INFRASTRUCTURE_MAX_ATTEMPTS = 2;
43
46
  const DAYTONA_UPLOAD_MAX_ATTEMPTS = 2;
44
47
  const DAYTONA_UPLOAD_ATTEMPT_DEADLINE_MS = 90_000;
48
+ const DAYTONA_STARTUP_DIAGNOSTIC_DELAY_MS = 15_000;
49
+ const DAYTONA_STARTUP_TRACE_ENV = 'DEEPLINE_DAYTONA_STARTUP_TRACE';
45
50
 
46
51
  const RUNTIME_POSTGRES_CONNECT_RETRY_PATTERN =
47
52
  /\bRuntime Postgres\b.*\b(connection timed out|connect timeout|ETIMEDOUT|ECONNRESET|ECONNREFUSED|Connection terminated|Connection ended unexpectedly)\b/i;
@@ -749,8 +754,56 @@ export const daytonaPlayRunnerBackend: PlayRunnerBackend = {
749
754
  cmdId: start.cmdId,
750
755
  runnerAttempt,
751
756
  ceilingSeconds: DAYTONA_EXECUTE_TIMEOUT_SECONDS,
757
+ outputPath: stagedPayload.outputPath,
758
+ exitCodePath: stagedPayload.exitCodePath,
752
759
  elapsedMs: Date.now() - startedAt,
753
760
  });
761
+ // Daytona acknowledges an async command with only a cmdId. It does
762
+ // not expose a queued/running state, and the backend parks before the
763
+ // runner contacts the runtime sheet. During startup investigations,
764
+ // retain a bounded snapshot while the sandbox is still alive; the
765
+ // normal cancellation path otherwise deletes the only evidence.
766
+ // This is opt-in because it adds Daytona control-plane calls to every
767
+ // run. The diagnostic excludes command lines and environment values.
768
+ if (process.env[DAYTONA_STARTUP_TRACE_ENV] === '1') {
769
+ const diagnosticTimer = setTimeout(() => {
770
+ void inspectDetachedDaytonaStartup({
771
+ sandbox,
772
+ sessionId: start.sessionId,
773
+ cmdId: start.cmdId,
774
+ exitCodePath: stagedPayload.exitCodePath,
775
+ }).then(
776
+ (diagnostic) =>
777
+ emitDaytonaStage(
778
+ callbacks,
779
+ config.context,
780
+ 'execute:startup_diagnostic',
781
+ {
782
+ sandboxId: sandbox.id,
783
+ sessionId: start.sessionId,
784
+ cmdId: start.cmdId,
785
+ diagnostic,
786
+ elapsedMs: Date.now() - startedAt,
787
+ },
788
+ ),
789
+ (error: unknown) =>
790
+ emitDaytonaStage(
791
+ callbacks,
792
+ config.context,
793
+ 'execute:startup_diagnostic_failed',
794
+ {
795
+ sandboxId: sandbox.id,
796
+ sessionId: start.sessionId,
797
+ cmdId: start.cmdId,
798
+ errorType:
799
+ error instanceof Error ? error.name : 'unknown',
800
+ elapsedMs: Date.now() - startedAt,
801
+ },
802
+ ),
803
+ );
804
+ }, DAYTONA_STARTUP_DIAGNOSTIC_DELAY_MS);
805
+ diagnosticTimer.unref?.();
806
+ }
754
807
  return {
755
808
  status: 'suspended',
756
809
  suspension: {