deepline 0.1.198 → 0.1.200

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 (72) hide show
  1. package/dist/bundling-sources/apps/play-runner-workers/src/coordinator-entry.ts +5 -1
  2. package/dist/bundling-sources/apps/play-runner-workers/src/entry.ts +51 -17
  3. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/README.md +1 -1
  4. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/harness-receipt-store.ts +16 -0
  5. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/receipts.ts +40 -9
  6. package/dist/bundling-sources/apps/play-runner-workers/src/runtime/tool-dispatch.ts +108 -39
  7. package/dist/bundling-sources/sdk/src/http.ts +5 -2
  8. package/dist/bundling-sources/sdk/src/play.ts +1 -1
  9. package/dist/bundling-sources/sdk/src/plays/harness-stub.ts +7 -0
  10. package/dist/bundling-sources/sdk/src/release.ts +2 -2
  11. package/dist/bundling-sources/sdk/src/worker-play-entry.ts +11 -55
  12. package/dist/bundling-sources/shared_libs/play-runtime/adaptive-tool-dispatcher.ts +355 -0
  13. package/dist/bundling-sources/shared_libs/play-runtime/app-runtime-api.ts +172 -73
  14. package/dist/bundling-sources/shared_libs/play-runtime/context.ts +1794 -377
  15. package/dist/bundling-sources/shared_libs/play-runtime/ctx-contract.ts +3 -0
  16. package/dist/bundling-sources/shared_libs/play-runtime/ctx-types.ts +67 -4
  17. package/dist/bundling-sources/shared_libs/play-runtime/durable-receipt-execution.ts +161 -39
  18. package/dist/bundling-sources/shared_libs/play-runtime/governor/adaptive-admission.ts +218 -0
  19. package/dist/bundling-sources/shared_libs/play-runtime/governor/app-runtime-rate-state-backend.ts +1 -1
  20. package/dist/bundling-sources/shared_libs/play-runtime/governor/governor.ts +115 -25
  21. package/dist/bundling-sources/shared_libs/play-runtime/governor/policy.ts +17 -17
  22. package/dist/bundling-sources/shared_libs/play-runtime/lease-policy.ts +22 -0
  23. package/dist/bundling-sources/shared_libs/play-runtime/ledger-safe-payload.ts +2 -1
  24. package/dist/bundling-sources/shared_libs/play-runtime/live-events.ts +0 -1
  25. package/dist/bundling-sources/shared_libs/play-runtime/map-memory-limits.ts +265 -0
  26. package/dist/bundling-sources/shared_libs/play-runtime/output-size-limits.ts +135 -0
  27. package/dist/bundling-sources/shared_libs/play-runtime/play-input.ts +17 -0
  28. package/dist/bundling-sources/shared_libs/play-runtime/play-latency-trace.ts +0 -3
  29. package/dist/bundling-sources/shared_libs/play-runtime/protocol.ts +10 -1
  30. package/dist/bundling-sources/shared_libs/play-runtime/providers.ts +9 -15
  31. package/dist/bundling-sources/shared_libs/play-runtime/receipt-completion-sink.ts +262 -0
  32. package/dist/bundling-sources/shared_libs/play-runtime/receipt-heartbeat-supervisor.ts +64 -0
  33. package/dist/bundling-sources/shared_libs/play-runtime/receipt-sql.ts +76 -8
  34. package/dist/bundling-sources/shared_libs/play-runtime/receipt-state-sink.ts +59 -0
  35. package/dist/bundling-sources/shared_libs/play-runtime/receipt-status.ts +3 -2
  36. package/dist/bundling-sources/shared_libs/play-runtime/resource-governor.ts +269 -0
  37. package/dist/bundling-sources/shared_libs/play-runtime/run-ledger.ts +2 -3
  38. package/dist/bundling-sources/shared_libs/play-runtime/run-terminal-source.ts +0 -1
  39. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-lifecycle.ts +433 -0
  40. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona-payload-transport.ts +227 -0
  41. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/daytona.ts +882 -0
  42. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/backends/local-process.ts +573 -0
  43. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/bundle.ts +264 -0
  44. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/index.ts +33 -0
  45. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/runner-events.ts +35 -0
  46. package/dist/bundling-sources/shared_libs/play-runtime/runner-backends/types.ts +53 -0
  47. package/dist/bundling-sources/shared_libs/play-runtime/runtime-actions.ts +0 -1
  48. package/dist/bundling-sources/shared_libs/play-runtime/runtime-api.ts +459 -103
  49. package/dist/bundling-sources/shared_libs/play-runtime/runtime-constants.ts +12 -0
  50. package/dist/bundling-sources/shared_libs/play-runtime/runtime-infra-mode.ts +23 -0
  51. package/dist/bundling-sources/shared_libs/play-runtime/runtime-sheet-attempt-state-machine.ts +23 -2
  52. package/dist/bundling-sources/shared_libs/play-runtime/scheduler-backend.ts +16 -24
  53. package/dist/bundling-sources/shared_libs/play-runtime/serial-task-queue.ts +26 -0
  54. package/dist/bundling-sources/shared_libs/play-runtime/submit-limits.ts +1 -1
  55. package/dist/bundling-sources/shared_libs/play-runtime/vercel-protection.ts +81 -0
  56. package/dist/bundling-sources/shared_libs/play-runtime/work-receipt-state-machine.ts +54 -9
  57. package/dist/bundling-sources/shared_libs/play-runtime/work-receipts.ts +17 -3
  58. package/dist/bundling-sources/shared_libs/play-runtime/worker-api-types.ts +0 -20
  59. package/dist/bundling-sources/shared_libs/plays/dataset.ts +105 -4
  60. package/dist/bundling-sources/shared_libs/plays/row-identity.ts +4 -11
  61. package/dist/cli/index.js +441 -101
  62. package/dist/cli/index.mjs +441 -101
  63. package/dist/index.d.mts +1 -1
  64. package/dist/index.d.ts +1 -1
  65. package/dist/index.js +8 -8
  66. package/dist/index.mjs +8 -8
  67. package/dist/plays/bundle-play-file.mjs +15 -20
  68. package/package.json +1 -1
  69. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-diagnosis.ts +0 -321
  70. package/dist/bundling-sources/shared_libs/play-runtime/hatchet-cold-execution-target.ts +0 -158
  71. package/dist/bundling-sources/shared_libs/temporal/constants.ts +0 -39
  72. package/dist/bundling-sources/shared_libs/temporal/preview-config.ts +0 -150
@@ -0,0 +1,264 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { access, readdir, readFile } from 'node:fs/promises';
3
+ import { dirname, join, relative, resolve } from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ import {
6
+ setSpanAttributes,
7
+ withActiveSpan,
8
+ } from '@shared_libs/observability/tracing';
9
+
10
+ const runtimeRequire = createRequire(import.meta.url);
11
+ const esbuild = runtimeRequire('esbuild') as {
12
+ build: (options: Record<string, unknown>) => Promise<{
13
+ outputFiles?: Array<{ text: string }>;
14
+ metafile?: {
15
+ inputs: Record<string, unknown>;
16
+ };
17
+ }>;
18
+ };
19
+
20
+ type EsbuildOnResolveArgs = {
21
+ importer: string;
22
+ path: string;
23
+ };
24
+
25
+ type EsbuildPluginBuild = {
26
+ onResolve: (
27
+ options: { filter: RegExp },
28
+ callback: (args: EsbuildOnResolveArgs) =>
29
+ | {
30
+ path?: string;
31
+ errors?: Array<{ text: string }>;
32
+ }
33
+ | undefined,
34
+ ) => void;
35
+ };
36
+
37
+ /**
38
+ * SECURITY: These are the only allowed module-scope caches in the play runner.
39
+ *
40
+ * They cache compiled runner CODE solely by source hash. They must never cache
41
+ * org-scoped, workflow-scoped, credential-bearing, or otherwise run-derived
42
+ * material. Future edits: do not thread execution config, play input, API
43
+ * responses, sandbox ids, or customer data into this cache key or payload.
44
+ */
45
+ let cachedRunnerBundle: Promise<string> | null = null;
46
+ let cachedRunnerSourceHash: string | null = null;
47
+
48
+ async function readPrebuiltRunnerBundle(): Promise<string | null> {
49
+ const bundlePath = process.env.DEEPLINE_PLAY_RUNNER_BUNDLE_PATH?.trim();
50
+ if (!bundlePath) {
51
+ return null;
52
+ }
53
+ try {
54
+ await access(bundlePath);
55
+ const bundle = await readFile(bundlePath, 'utf-8');
56
+ console.info('[plays.runner.bundle.prebuilt]', {
57
+ bundlePath,
58
+ bytes: bundle.length,
59
+ });
60
+ return bundle;
61
+ } catch (error) {
62
+ console.warn('[plays.runner.bundle.prebuilt_missing]', {
63
+ bundlePath,
64
+ error: error instanceof Error ? error.message : String(error),
65
+ });
66
+ return null;
67
+ }
68
+ }
69
+
70
+ async function listFiles(dir: string): Promise<string[]> {
71
+ const entries = await readdir(dir, { withFileTypes: true });
72
+ const values = await Promise.all(
73
+ entries.map(async (entry) => {
74
+ const fullPath = join(dir, entry.name);
75
+ if (entry.isDirectory()) {
76
+ return await listFiles(fullPath);
77
+ }
78
+ return entry.isFile() ? [fullPath] : [];
79
+ }),
80
+ );
81
+ return values.flat().sort();
82
+ }
83
+
84
+ async function hashRunnerSources(rootDirs: string[]): Promise<string> {
85
+ const sourceFiles = (
86
+ await Promise.all(rootDirs.map(async (rootDir) => await listFiles(rootDir)))
87
+ )
88
+ .flat()
89
+ .sort();
90
+ const hash = createHash('sha256');
91
+ for (const filePath of sourceFiles) {
92
+ hash.update(filePath);
93
+ hash.update(await readFile(filePath));
94
+ }
95
+ return hash.digest('hex');
96
+ }
97
+
98
+ function isInsidePath(candidate: string, parent: string): boolean {
99
+ const relativePath = relative(parent, candidate);
100
+ return (
101
+ Boolean(relativePath) &&
102
+ !relativePath.startsWith('..') &&
103
+ !relativePath.startsWith('/')
104
+ );
105
+ }
106
+
107
+ function createRunnerBoundaryPlugin(projectRoot: string) {
108
+ const forbiddenRoots = [
109
+ resolve(projectRoot, 'src'),
110
+ resolve(projectRoot, 'convex'),
111
+ ];
112
+
113
+ function rejectionForImport(args: EsbuildOnResolveArgs): string | null {
114
+ if (args.path.startsWith('@/') || args.path.startsWith('@convex/')) {
115
+ return `play-runner bundle cannot import ${args.path}; move shared runtime code to shared_libs or call the app over the runtime API`;
116
+ }
117
+
118
+ if (!args.path.startsWith('.') || !args.importer) {
119
+ return null;
120
+ }
121
+
122
+ const resolvedImport = resolve(dirname(args.importer), args.path);
123
+ const forbiddenRoot = forbiddenRoots.find(
124
+ (root) => isInsidePath(resolvedImport, root) || resolvedImport === root,
125
+ );
126
+ if (!forbiddenRoot) {
127
+ return null;
128
+ }
129
+
130
+ const relativeForbiddenPath = relative(projectRoot, resolvedImport);
131
+ return `play-runner bundle cannot import ${args.path} from ${args.importer}; it resolves into ${relativeForbiddenPath}`;
132
+ }
133
+
134
+ return {
135
+ name: 'deepline-play-runner-boundary',
136
+ setup(build: EsbuildPluginBuild) {
137
+ build.onResolve({ filter: /.*/ }, (args) => {
138
+ const rejection = rejectionForImport(args);
139
+ if (!rejection) {
140
+ return undefined;
141
+ }
142
+ return {
143
+ errors: [{ text: rejection }],
144
+ };
145
+ });
146
+ },
147
+ };
148
+ }
149
+
150
+ function assertBundleInputsStayInsideRunnerBoundary(
151
+ projectRoot: string,
152
+ inputs: Record<string, unknown> | undefined,
153
+ ) {
154
+ if (!inputs) {
155
+ return;
156
+ }
157
+ const forbiddenInputs = Object.keys(inputs)
158
+ .map((inputPath) => resolve(projectRoot, inputPath))
159
+ .filter(
160
+ (inputPath) =>
161
+ isInsidePath(inputPath, resolve(projectRoot, 'src')) ||
162
+ isInsidePath(inputPath, resolve(projectRoot, 'convex')) ||
163
+ inputPath === resolve(projectRoot, 'src') ||
164
+ inputPath === resolve(projectRoot, 'convex'),
165
+ );
166
+ if (forbiddenInputs.length === 0) {
167
+ return;
168
+ }
169
+ throw new Error(
170
+ [
171
+ 'play-runner bundle crossed into app/server source:',
172
+ ...forbiddenInputs.map(
173
+ (inputPath) => `- ${relative(projectRoot, inputPath)}`,
174
+ ),
175
+ ].join('\n'),
176
+ );
177
+ }
178
+
179
+ export async function buildPlayRunnerBundle(): Promise<string> {
180
+ return await withActiveSpan(
181
+ 'plays.runner.bundle',
182
+ {
183
+ tracer: 'deepline.plays',
184
+ },
185
+ async (span) => {
186
+ const prebuiltBundle = await readPrebuiltRunnerBundle();
187
+ if (prebuiltBundle) {
188
+ span.setAttribute('plays.bundle_prebuilt', true);
189
+ setSpanAttributes(span, {
190
+ 'plays.bundle_bytes': prebuiltBundle.length,
191
+ });
192
+ return prebuiltBundle;
193
+ }
194
+ span.setAttribute('plays.bundle_prebuilt', false);
195
+
196
+ const sourceRoots = [
197
+ resolve(process.cwd(), 'apps', 'play-runner', 'src'),
198
+ resolve(process.cwd(), 'shared_libs'),
199
+ ];
200
+ const sourceHash = await hashRunnerSources(sourceRoots);
201
+ setSpanAttributes(span, {
202
+ 'plays.runner_source_hash': sourceHash,
203
+ });
204
+
205
+ if (cachedRunnerBundle && cachedRunnerSourceHash === sourceHash) {
206
+ span.setAttribute('plays.bundle_cache_hit', true);
207
+ const bundle = await cachedRunnerBundle;
208
+ setSpanAttributes(span, {
209
+ 'plays.bundle_bytes': bundle.length,
210
+ });
211
+ return bundle;
212
+ }
213
+
214
+ span.setAttribute('plays.bundle_cache_hit', false);
215
+ cachedRunnerSourceHash = sourceHash;
216
+ cachedRunnerBundle = (async () => {
217
+ const projectRoot = process.cwd();
218
+ const runnerRoot = resolve(process.cwd(), 'apps', 'play-runner', 'src');
219
+ return await withActiveSpan(
220
+ 'plays.runner.bundle_build',
221
+ {
222
+ tracer: 'deepline.plays',
223
+ attributes: {
224
+ 'plays.runner_source_hash': sourceHash,
225
+ },
226
+ },
227
+ async (buildSpan) => {
228
+ const result = await esbuild.build({
229
+ entryPoints: [resolve(runnerRoot, 'entry.ts')],
230
+ bundle: true,
231
+ platform: 'node',
232
+ format: 'cjs',
233
+ target: ['node18'],
234
+ write: false,
235
+ sourcemap: false,
236
+ minify: true,
237
+ tsconfig: resolve(
238
+ process.cwd(),
239
+ 'tsconfig.apps.play-runner.json',
240
+ ),
241
+ metafile: true,
242
+ plugins: [createRunnerBoundaryPlugin(projectRoot)],
243
+ });
244
+ assertBundleInputsStayInsideRunnerBoundary(
245
+ projectRoot,
246
+ result.metafile?.inputs,
247
+ );
248
+ const bundle = result.outputFiles?.[0]?.text ?? '';
249
+ setSpanAttributes(buildSpan, {
250
+ 'plays.bundle_bytes': bundle.length,
251
+ });
252
+ return bundle;
253
+ },
254
+ );
255
+ })();
256
+
257
+ const bundle = await cachedRunnerBundle;
258
+ setSpanAttributes(span, {
259
+ 'plays.bundle_bytes': bundle.length,
260
+ });
261
+ return bundle;
262
+ },
263
+ );
264
+ }
@@ -0,0 +1,33 @@
1
+ import type { PlayRunnerBackend } from './types';
2
+ import { daytonaPlayRunnerBackend } from './backends/daytona';
3
+ import { localProcessPlayRunnerBackend } from './backends/local-process';
4
+ import {
5
+ PLAY_RUNTIME_BACKENDS,
6
+ normalizePlayRuntimeBackend,
7
+ type PlayRuntimeBackendId,
8
+ } from '@shared_libs/play-runtime/backend';
9
+
10
+ export function resolvePlayRunnerBackend(
11
+ backendId?: PlayRuntimeBackendId | string | null,
12
+ ): PlayRunnerBackend {
13
+ const backend = normalizePlayRuntimeBackend(
14
+ backendId ?? process.env.DEEPLINE_PLAY_RUNNER_BACKEND,
15
+ );
16
+ if (backend === PLAY_RUNTIME_BACKENDS.cloudflareWorkers) {
17
+ throw new Error(
18
+ 'The Cloudflare runner-only backend has been retired. Pass ' +
19
+ '`body.profile=workers_edge` on POST /api/v2/plays/run to use the ' +
20
+ 'Cloudflare scheduler/runner profile.',
21
+ );
22
+ }
23
+ if (backend === PLAY_RUNTIME_BACKENDS.daytona) {
24
+ return daytonaPlayRunnerBackend;
25
+ }
26
+ if (backend === PLAY_RUNTIME_BACKENDS.localProcess) {
27
+ return localProcessPlayRunnerBackend;
28
+ }
29
+ throw new Error(`Unsupported play runner backend: ${backend}`);
30
+ }
31
+
32
+ export { daytonaPlayRunnerBackend, localProcessPlayRunnerBackend };
33
+ export type { PlayRunnerBackend };
@@ -0,0 +1,35 @@
1
+ import type {
2
+ PlayRunnerEvent,
3
+ PlayRunnerResult,
4
+ } from '@shared_libs/play-runtime/protocol';
5
+
6
+ export function parsePlayRunnerEvents(stdout: string): PlayRunnerEvent[] {
7
+ return stdout
8
+ .split(/\r?\n/)
9
+ .map((line) => line.trim())
10
+ .filter(Boolean)
11
+ .flatMap((line) => {
12
+ try {
13
+ return [JSON.parse(line) as PlayRunnerEvent];
14
+ } catch {
15
+ return [];
16
+ }
17
+ });
18
+ }
19
+
20
+ export function parsePlayRunnerEventLine(line: string): PlayRunnerEvent | null {
21
+ try {
22
+ return JSON.parse(line) as PlayRunnerEvent;
23
+ } catch {
24
+ return null;
25
+ }
26
+ }
27
+
28
+ export function findPlayRunnerResult(
29
+ events: PlayRunnerEvent[],
30
+ ): PlayRunnerResult | null {
31
+ const resultEvent = [...events]
32
+ .reverse()
33
+ .find((event) => event.type === 'result');
34
+ return resultEvent?.type === 'result' ? resultEvent.result : null;
35
+ }
@@ -0,0 +1,53 @@
1
+ import type {
2
+ PlayCheckpoint,
3
+ PlayExecutionEvent,
4
+ PlayRowUpdate,
5
+ } from '@shared_libs/play-runtime/ctx-types';
6
+ import type {
7
+ PlayRunnerExecutionConfig,
8
+ PlayRunnerLogEvent,
9
+ PlayRunnerResult,
10
+ } from '@shared_libs/play-runtime/protocol';
11
+
12
+ export type PlayRunnerRuntimeResource =
13
+ | {
14
+ kind: 'daytona_sandbox';
15
+ sandboxId: string;
16
+ billingStartedAt: number;
17
+ cpu?: number | null;
18
+ memoryGiB?: number | null;
19
+ diskGiB?: number | null;
20
+ };
21
+
22
+ export interface PlayRunnerCallbacks {
23
+ onLog?: (event: PlayRunnerLogEvent) => void;
24
+ onCheckpoint?: (checkpoint: PlayCheckpoint) => void;
25
+ onRowUpdate?: (update: PlayRowUpdate) => void;
26
+ onExecutionEvent?: (event: PlayExecutionEvent) => void;
27
+ onRuntimeResourceAcquired?: (
28
+ resource: PlayRunnerRuntimeResource,
29
+ ) => void | Promise<void>;
30
+ cancellationSignal?: AbortSignal;
31
+ }
32
+
33
+ export interface PlayRunnerPrepareInput {
34
+ context: PlayRunnerExecutionConfig['context'];
35
+ }
36
+
37
+ export interface PlayRunnerPreparedExecution {
38
+ kind: string;
39
+ dispose?: () => Promise<void>;
40
+ }
41
+
42
+ export interface PlayRunnerBackend {
43
+ prepare?(
44
+ input: PlayRunnerPrepareInput,
45
+ callbacks?: PlayRunnerCallbacks,
46
+ ): Promise<PlayRunnerPreparedExecution>;
47
+
48
+ execute(
49
+ config: PlayRunnerExecutionConfig,
50
+ callbacks?: PlayRunnerCallbacks,
51
+ prepared?: PlayRunnerPreparedExecution,
52
+ ): Promise<PlayRunnerResult>;
53
+ }
@@ -147,7 +147,6 @@ export type RuntimeResultsAction = {
147
147
  error?: string;
148
148
  publicResult?: Record<string, unknown> | null;
149
149
  maxCreditsPerRun?: number | null;
150
- temporalActionEstimate?: Record<string, unknown> | null;
151
150
  };
152
151
  };
153
152