deepline 0.1.12 → 0.1.19

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 (80) hide show
  1. package/README.md +14 -6
  2. package/dist/cli/index.js +1298 -711
  3. package/dist/cli/index.mjs +1294 -707
  4. package/dist/index.d.mts +199 -23
  5. package/dist/index.d.ts +199 -23
  6. package/dist/index.js +219 -13
  7. package/dist/index.mjs +219 -13
  8. package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +68 -12
  9. package/dist/repo/apps/play-runner-workers/src/entry.ts +241 -51
  10. package/dist/repo/sdk/src/client.ts +237 -0
  11. package/dist/repo/sdk/src/config.ts +125 -8
  12. package/dist/repo/sdk/src/http.ts +10 -2
  13. package/dist/repo/sdk/src/play.ts +19 -36
  14. package/dist/repo/sdk/src/plays/bundle-play-file.ts +22 -8
  15. package/dist/repo/sdk/src/plays/local-file-discovery.ts +207 -160
  16. package/dist/repo/sdk/src/types.ts +25 -0
  17. package/dist/repo/sdk/src/version.ts +2 -2
  18. package/dist/repo/shared_libs/play-runtime/tool-result.ts +237 -145
  19. package/dist/repo/shared_libs/plays/bundling/index.ts +206 -229
  20. package/dist/repo/shared_libs/plays/dataset.ts +28 -0
  21. package/package.json +5 -4
  22. package/dist/cli/index.js.map +0 -1
  23. package/dist/cli/index.mjs.map +0 -1
  24. package/dist/index.js.map +0 -1
  25. package/dist/index.mjs.map +0 -1
  26. package/dist/repo/apps/play-runner-workers/src/runtime/README.md +0 -21
  27. package/dist/repo/apps/play-runner-workers/src/runtime/batching.ts +0 -177
  28. package/dist/repo/apps/play-runner-workers/src/runtime/execution-plan.ts +0 -52
  29. package/dist/repo/apps/play-runner-workers/src/runtime/tool-batch.ts +0 -100
  30. package/dist/repo/sdk/src/cli/commands/auth.ts +0 -500
  31. package/dist/repo/sdk/src/cli/commands/billing.ts +0 -188
  32. package/dist/repo/sdk/src/cli/commands/csv.ts +0 -123
  33. package/dist/repo/sdk/src/cli/commands/db.ts +0 -119
  34. package/dist/repo/sdk/src/cli/commands/feedback.ts +0 -40
  35. package/dist/repo/sdk/src/cli/commands/org.ts +0 -117
  36. package/dist/repo/sdk/src/cli/commands/play.ts +0 -3441
  37. package/dist/repo/sdk/src/cli/commands/tools.ts +0 -687
  38. package/dist/repo/sdk/src/cli/dataset-stats.ts +0 -415
  39. package/dist/repo/sdk/src/cli/index.ts +0 -148
  40. package/dist/repo/sdk/src/cli/progress.ts +0 -149
  41. package/dist/repo/sdk/src/cli/skills-sync.ts +0 -141
  42. package/dist/repo/sdk/src/cli/trace.ts +0 -61
  43. package/dist/repo/sdk/src/cli/utils.ts +0 -145
  44. package/dist/repo/sdk/src/compat.ts +0 -77
  45. package/dist/repo/shared_libs/observability/node-tracing.ts +0 -129
  46. package/dist/repo/shared_libs/observability/tracing.ts +0 -98
  47. package/dist/repo/shared_libs/play-runtime/context.ts +0 -4242
  48. package/dist/repo/shared_libs/play-runtime/ctx-contract.ts +0 -250
  49. package/dist/repo/shared_libs/play-runtime/ctx-types.ts +0 -725
  50. package/dist/repo/shared_libs/play-runtime/dataset-id.ts +0 -10
  51. package/dist/repo/shared_libs/play-runtime/db-session-crypto.ts +0 -304
  52. package/dist/repo/shared_libs/play-runtime/db-session.ts +0 -462
  53. package/dist/repo/shared_libs/play-runtime/live-events.ts +0 -214
  54. package/dist/repo/shared_libs/play-runtime/live-state-contract.ts +0 -50
  55. package/dist/repo/shared_libs/play-runtime/map-execution-frame.ts +0 -114
  56. package/dist/repo/shared_libs/play-runtime/map-row-identity.ts +0 -158
  57. package/dist/repo/shared_libs/play-runtime/progress-emitter.ts +0 -172
  58. package/dist/repo/shared_libs/play-runtime/protocol.ts +0 -121
  59. package/dist/repo/shared_libs/play-runtime/public-play-contract.ts +0 -42
  60. package/dist/repo/shared_libs/play-runtime/result-normalization.ts +0 -33
  61. package/dist/repo/shared_libs/play-runtime/runtime-api.ts +0 -1873
  62. package/dist/repo/shared_libs/play-runtime/runtime-constraints.ts +0 -2
  63. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-neon-serverless.ts +0 -201
  64. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver-pg.ts +0 -48
  65. package/dist/repo/shared_libs/play-runtime/runtime-pg-driver.ts +0 -84
  66. package/dist/repo/shared_libs/play-runtime/static-pipeline-types.ts +0 -147
  67. package/dist/repo/shared_libs/play-runtime/suspension.ts +0 -68
  68. package/dist/repo/shared_libs/play-runtime/tracing.ts +0 -31
  69. package/dist/repo/shared_libs/play-runtime/waterfall-replay.ts +0 -75
  70. package/dist/repo/shared_libs/play-runtime/worker-api-types.ts +0 -140
  71. package/dist/repo/shared_libs/plays/artifact-transport.ts +0 -14
  72. package/dist/repo/shared_libs/plays/artifact-types.ts +0 -49
  73. package/dist/repo/shared_libs/plays/compiler-manifest.ts +0 -186
  74. package/dist/repo/shared_libs/plays/definition.ts +0 -264
  75. package/dist/repo/shared_libs/plays/file-refs.ts +0 -11
  76. package/dist/repo/shared_libs/plays/rate-limit-scheduler.ts +0 -206
  77. package/dist/repo/shared_libs/plays/resolve-static-pipeline.ts +0 -164
  78. package/dist/repo/shared_libs/plays/runtime-validation.ts +0 -395
  79. package/dist/repo/shared_libs/temporal/constants.ts +0 -39
  80. package/dist/repo/shared_libs/temporal/preview-config.ts +0 -153
package/dist/index.mjs CHANGED
@@ -42,6 +42,10 @@ var ConfigError = class extends DeeplineError {
42
42
  var PROD_URL = "https://code.deepline.com";
43
43
  var DEFAULT_TIMEOUT = 6e4;
44
44
  var DEFAULT_MAX_RETRIES = 3;
45
+ var ACTIVE_DEEPLINE_ENV_FILE = ".env.deepline";
46
+ function projectEnvStartDir() {
47
+ return process.env.DEEPLINE_PROJECT_ENV_DIR?.trim() || process.cwd();
48
+ }
45
49
  function baseUrlSlug(baseUrl) {
46
50
  let url;
47
51
  try {
@@ -77,16 +81,52 @@ function parseEnvFile(filePath) {
77
81
  }
78
82
  return env;
79
83
  }
80
- function findNearestWorktreeEnv(startDir = process.cwd()) {
84
+ function findNearestEnvFile(names, startDir = process.cwd()) {
81
85
  let current = resolve(startDir);
82
86
  while (true) {
83
- const values = parseEnvFile(join(current, ".env.worktree"));
84
- if (Object.keys(values).length > 0) return values;
87
+ for (const name of names) {
88
+ const filePath = join(current, name);
89
+ if (existsSync(filePath)) return filePath;
90
+ }
85
91
  const parent = dirname(current);
86
- if (parent === current) return {};
92
+ if (parent === current) return null;
87
93
  current = parent;
88
94
  }
89
95
  }
96
+ function findNearestEnv(names, startDir = process.cwd()) {
97
+ const filePath = findNearestEnvFile(names, startDir);
98
+ return filePath ? parseEnvFile(filePath) : {};
99
+ }
100
+ function findNearestWorktreeEnv(startDir = process.cwd()) {
101
+ return findNearestEnv([".env.worktree"], startDir);
102
+ }
103
+ function resolveProfileEnvFileNames() {
104
+ const explicitProfile = process.env.DEEPLINE_ENV_PROFILE?.trim() || process.env.DEEPLINE_PROFILE?.trim() || "";
105
+ const names = [];
106
+ if (explicitProfile) names.push(`.env.deepline.${explicitProfile}`);
107
+ const nodeEnv = process.env.NODE_ENV?.trim();
108
+ if (nodeEnv === "production") names.push(".env.deepline.prod");
109
+ else if (nodeEnv === "staging") names.push(".env.deepline.staging");
110
+ names.push(ACTIVE_DEEPLINE_ENV_FILE);
111
+ return names;
112
+ }
113
+ function resolveProjectAppEnvFileNames() {
114
+ const nodeEnv = process.env.NODE_ENV?.trim();
115
+ const names = [];
116
+ if (nodeEnv === "production") names.push(".env.prod");
117
+ if (nodeEnv === "staging") names.push(".env.staging");
118
+ names.push(".env.local", ".env");
119
+ return names;
120
+ }
121
+ function resolveBaseUrlFromEnvValues(env) {
122
+ return env.DEEPLINE_ORIGIN_URL?.trim() || env.DEEPLINE_API_BASE_URL?.trim() || "";
123
+ }
124
+ function loadProjectDeeplineEnv() {
125
+ return findNearestEnv(resolveProfileEnvFileNames(), projectEnvStartDir());
126
+ }
127
+ function loadProjectAppEnv() {
128
+ return findNearestEnv(resolveProjectAppEnvFileNames(), projectEnvStartDir());
129
+ }
90
130
  function normalizeWorktreeBaseUrl(baseUrl, worktreeEnv = findNearestWorktreeEnv()) {
91
131
  const trimmed = baseUrl.trim().replace(/\/$/, "");
92
132
  if (!trimmed) return trimmed;
@@ -123,6 +163,10 @@ function autoDetectBaseUrl() {
123
163
  if (envOrigin) return normalizeWorktreeBaseUrl(envOrigin);
124
164
  const envBase = process.env.DEEPLINE_API_BASE_URL?.trim();
125
165
  if (envBase) return normalizeWorktreeBaseUrl(envBase);
166
+ const projectDeeplineBaseUrl = resolveBaseUrlFromEnvValues(loadProjectDeeplineEnv());
167
+ if (projectDeeplineBaseUrl) return normalizeWorktreeBaseUrl(projectDeeplineBaseUrl);
168
+ const projectAppBaseUrl = resolveBaseUrlFromEnvValues(loadProjectAppEnv());
169
+ if (projectAppBaseUrl) return normalizeWorktreeBaseUrl(projectAppBaseUrl);
126
170
  const worktreeBaseUrl = resolveWorktreeBaseUrl();
127
171
  if (worktreeBaseUrl) return worktreeBaseUrl;
128
172
  const globalEnv = loadGlobalCliEnv();
@@ -134,7 +178,9 @@ function resolveConfig(options) {
134
178
  const requestedBaseUrl = options?.baseUrl?.trim() || autoDetectBaseUrl();
135
179
  const baseUrl = normalizeWorktreeBaseUrl(requestedBaseUrl);
136
180
  const cliEnv = loadCliEnv(baseUrl);
137
- const apiKey = options?.apiKey?.trim() || process.env.DEEPLINE_API_KEY?.trim() || cliEnv.DEEPLINE_API_KEY || "";
181
+ const projectDeeplineEnv = loadProjectDeeplineEnv();
182
+ const projectAppEnv = loadProjectAppEnv();
183
+ const apiKey = options?.apiKey?.trim() || process.env.DEEPLINE_API_KEY?.trim() || projectDeeplineEnv.DEEPLINE_API_KEY || projectAppEnv.DEEPLINE_API_KEY || cliEnv.DEEPLINE_API_KEY || "";
138
184
  if (!apiKey) {
139
185
  throw new ConfigError(
140
186
  `No API key found. Set DEEPLINE_API_KEY env var, pass apiKey option, or run: deepline auth register`
@@ -149,8 +195,8 @@ function resolveConfig(options) {
149
195
  }
150
196
 
151
197
  // src/version.ts
152
- var SDK_VERSION = "0.1.12";
153
- var SDK_API_CONTRACT = "2026-04-plays-v1";
198
+ var SDK_VERSION = "0.1.19";
199
+ var SDK_API_CONTRACT = "2026-05-runs-v2";
154
200
 
155
201
  // ../shared_libs/play-runtime/coordinator-headers.ts
156
202
  var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
@@ -343,8 +389,12 @@ var HttpClient = class {
343
389
  * @param path - API path
344
390
  * @param body - Request body (will be JSON-serialized)
345
391
  */
346
- async post(path, body) {
347
- return this.request(path, { method: "POST", body });
392
+ async post(path, body, headers) {
393
+ return this.request(path, {
394
+ method: "POST",
395
+ body,
396
+ headers
397
+ });
348
398
  }
349
399
  /**
350
400
  * Send a DELETE request.
@@ -424,6 +474,7 @@ function sleep(ms) {
424
474
 
425
475
  // src/client.ts
426
476
  var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
477
+ var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
427
478
  function isRecord(value) {
428
479
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
429
480
  }
@@ -456,6 +507,7 @@ function mapLegacyTemporalStatus(status) {
456
507
  var DeeplineClient = class {
457
508
  http;
458
509
  config;
510
+ runs;
459
511
  /**
460
512
  * @param options - Optional overrides for API key, base URL, timeout, and retries.
461
513
  * @throws {@link ConfigError} if no API key can be resolved from any source.
@@ -463,6 +515,13 @@ var DeeplineClient = class {
463
515
  constructor(options) {
464
516
  this.config = resolveConfig(options);
465
517
  this.http = new HttpClient(this.config);
518
+ this.runs = {
519
+ get: (runId) => this.getRunStatus(runId),
520
+ list: (options2) => this.listRuns(options2),
521
+ tail: (runId, options2) => this.tailRun(runId, options2),
522
+ logs: (runId, options2) => this.getRunLogs(runId, options2),
523
+ stop: (runId, options2) => this.stopRun(runId, options2)
524
+ };
466
525
  }
467
526
  /** The resolved base URL this client is targeting (e.g. `"http://localhost:3000"`). */
468
527
  get baseUrl() {
@@ -551,6 +610,31 @@ var DeeplineClient = class {
551
610
  );
552
611
  return res.tools;
553
612
  }
613
+ /**
614
+ * Search available tools using Deepline's ranked backend search.
615
+ *
616
+ * This is the same discovery surface used by the legacy CLI: it ranks across
617
+ * tool metadata, categories, agent guidance, and input schema fields.
618
+ */
619
+ async searchTools(options = {}) {
620
+ const params = new URLSearchParams();
621
+ const query = options.query?.trim() ?? "";
622
+ params.set("q", query);
623
+ params.set(
624
+ "include_search_debug",
625
+ options.includeSearchDebug ? "true" : "false"
626
+ );
627
+ params.set("search_mode", options.searchMode ?? "v2");
628
+ if (options.categories?.trim()) {
629
+ params.set("categories", options.categories.trim());
630
+ }
631
+ if (options.searchTerms?.trim()) {
632
+ params.set("search_terms", options.searchTerms.trim());
633
+ }
634
+ return this.http.get(
635
+ `/api/v2/integrations/list?${params.toString()}`
636
+ );
637
+ }
554
638
  /**
555
639
  * Get detailed metadata for a single tool.
556
640
  *
@@ -586,12 +670,17 @@ var DeeplineClient = class {
586
670
  * Top-level fields such as `status`, `job_id`, and `billing` describe the
587
671
  * Deepline execution.
588
672
  */
589
- async executeTool(toolId, input) {
673
+ async executeTool(toolId, input, options) {
674
+ const headers = options?.includeToolMetadata ? { [INCLUDE_TOOL_METADATA_HEADER]: "true" } : void 0;
590
675
  return this.http.post(
591
676
  `/api/v2/integrations/${encodeURIComponent(toolId)}/execute`,
592
- { payload: input }
677
+ { payload: input },
678
+ headers
593
679
  );
594
680
  }
681
+ async executeToolRaw(toolId, input, options) {
682
+ return this.executeTool(toolId, input, options);
683
+ }
595
684
  async queryCustomerDb(input) {
596
685
  return this.http.post("/api/v2/db/query", {
597
686
  sql: input.sql,
@@ -640,6 +729,7 @@ var DeeplineClient = class {
640
729
  ...request.revisionId ? { revisionId: request.revisionId } : {},
641
730
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
642
731
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
732
+ ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
643
733
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
644
734
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
645
735
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -664,6 +754,7 @@ var DeeplineClient = class {
664
754
  ...request.revisionId ? { revisionId: request.revisionId } : {},
665
755
  ...request.artifactStorageKey ? { artifactStorageKey: request.artifactStorageKey } : {},
666
756
  ...request.sourceCode ? { sourceCode: request.sourceCode } : {},
757
+ ...request.sourceFiles ? { sourceFiles: request.sourceFiles } : {},
667
758
  ..."staticPipeline" in request ? { staticPipeline: request.staticPipeline } : {},
668
759
  ...request.artifactHash ? { artifactHash: request.artifactHash } : {},
669
760
  ...request.graphHash ? { graphHash: request.graphHash } : {},
@@ -700,6 +791,7 @@ var DeeplineClient = class {
700
791
  const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
701
792
  name: input.name,
702
793
  sourceCode: input.sourceCode,
794
+ sourceFiles: input.sourceFiles,
703
795
  artifact: input.artifact
704
796
  });
705
797
  return this.http.post("/api/v2/plays/artifacts", {
@@ -714,6 +806,7 @@ var DeeplineClient = class {
714
806
  compilerManifest: artifact.compilerManifest ?? await this.compilePlayManifest({
715
807
  name: artifact.name,
716
808
  sourceCode: artifact.sourceCode,
809
+ sourceFiles: artifact.sourceFiles,
717
810
  artifact: artifact.artifact
718
811
  })
719
812
  }))
@@ -740,11 +833,13 @@ var DeeplineClient = class {
740
833
  const compilerManifest = input.compilerManifest ?? await this.compilePlayManifest({
741
834
  name: input.name,
742
835
  sourceCode: input.sourceCode,
836
+ sourceFiles: input.sourceFiles,
743
837
  artifact: input.artifact
744
838
  });
745
839
  const registeredArtifact = await this.registerPlayArtifact({
746
840
  name: input.name,
747
841
  sourceCode: input.sourceCode,
842
+ sourceFiles: input.sourceFiles,
748
843
  artifact: input.artifact,
749
844
  compilerManifest,
750
845
  publish: false
@@ -804,11 +899,13 @@ var DeeplineClient = class {
804
899
  const compilerManifest = options?.compilerManifest ?? await this.compilePlayManifest({
805
900
  name,
806
901
  sourceCode,
902
+ sourceFiles: options?.sourceFiles,
807
903
  artifact
808
904
  });
809
905
  const registeredArtifact = await this.registerPlayArtifact({
810
906
  name,
811
907
  sourceCode,
908
+ sourceFiles: options?.sourceFiles,
812
909
  artifact,
813
910
  compilerManifest,
814
911
  publish: false
@@ -992,6 +1089,112 @@ var DeeplineClient = class {
992
1089
  );
993
1090
  return response.runs ?? [];
994
1091
  }
1092
+ /**
1093
+ * Get a run by id using the public runs resource model.
1094
+ *
1095
+ * This is the SDK equivalent of:
1096
+ *
1097
+ * ```bash
1098
+ * deepline runs get <run-id> --json
1099
+ * ```
1100
+ */
1101
+ async getRunStatus(runId) {
1102
+ const response = await this.http.get(
1103
+ `/api/v2/runs/${encodeURIComponent(runId)}`
1104
+ );
1105
+ return normalizePlayStatus(response);
1106
+ }
1107
+ /**
1108
+ * List play runs using the public runs resource model.
1109
+ *
1110
+ * This is the SDK equivalent of:
1111
+ *
1112
+ * ```bash
1113
+ * deepline runs list --play <play-name> --status failed --json
1114
+ * ```
1115
+ */
1116
+ async listRuns(options) {
1117
+ const playName = options.play.trim();
1118
+ if (!playName) {
1119
+ throw new Error("runs.list requires options.play.");
1120
+ }
1121
+ const params = new URLSearchParams({ play: playName });
1122
+ const status = options.status?.trim();
1123
+ if (status) {
1124
+ params.set("status", status);
1125
+ }
1126
+ const response = await this.http.get(
1127
+ `/api/v2/runs?${params.toString()}`
1128
+ );
1129
+ return response.runs ?? [];
1130
+ }
1131
+ /**
1132
+ * Fetch the lightweight tail status for a run using the public runs resource model.
1133
+ *
1134
+ * This is the SDK equivalent of:
1135
+ *
1136
+ * ```bash
1137
+ * deepline runs tail <run-id> --json
1138
+ * ```
1139
+ */
1140
+ async tailRun(runId, options) {
1141
+ const afterLogIndex = typeof options?.afterLogIndex === "number" ? options.afterLogIndex : typeof options?.cursor === "number" ? options.cursor : typeof options?.cursor === "string" && options.cursor.trim() ? Number(options.cursor) : void 0;
1142
+ const params = new URLSearchParams();
1143
+ if (Number.isFinite(afterLogIndex)) {
1144
+ params.set("afterLogIndex", String(Number(afterLogIndex)));
1145
+ }
1146
+ if (typeof options?.waitMs === "number") {
1147
+ params.set("waitMs", String(options.waitMs));
1148
+ }
1149
+ if (options?.terminalOnly) {
1150
+ params.set("terminalOnly", "true");
1151
+ }
1152
+ const suffix = params.toString() ? `?${params.toString()}` : "";
1153
+ const response = await this.http.get(
1154
+ `/api/v2/runs/${encodeURIComponent(runId)}/tail${suffix}`
1155
+ );
1156
+ return normalizePlayStatus(response);
1157
+ }
1158
+ /**
1159
+ * Fetch persisted logs for a run using the public runs resource model.
1160
+ *
1161
+ * This is the SDK equivalent of:
1162
+ *
1163
+ * ```bash
1164
+ * deepline runs logs <run-id> --limit 200 --json
1165
+ * ```
1166
+ */
1167
+ async getRunLogs(runId, options) {
1168
+ const status = await this.getRunStatus(runId);
1169
+ const logs = status.progress?.logs ?? [];
1170
+ const limit = typeof options?.limit === "number" && Number.isFinite(options.limit) ? Math.max(0, Math.trunc(options.limit)) : 200;
1171
+ const entries = logs.slice(Math.max(0, logs.length - limit));
1172
+ return {
1173
+ runId: status.runId,
1174
+ totalCount: logs.length,
1175
+ returnedCount: entries.length,
1176
+ firstSequence: logs.length === 0 ? null : logs.length - entries.length + 1,
1177
+ lastSequence: logs.length === 0 ? null : logs.length,
1178
+ truncated: logs.length > entries.length,
1179
+ hasMore: logs.length > entries.length,
1180
+ entries
1181
+ };
1182
+ }
1183
+ /**
1184
+ * Stop a run by id using the public runs resource model.
1185
+ *
1186
+ * This is the SDK equivalent of:
1187
+ *
1188
+ * ```bash
1189
+ * deepline runs stop <run-id> --reason "stale lock" --json
1190
+ * ```
1191
+ */
1192
+ async stopRun(runId, options) {
1193
+ return this.http.post(
1194
+ `/api/v2/runs/${encodeURIComponent(runId)}/stop`,
1195
+ options?.reason ? { reason: options.reason } : {}
1196
+ );
1197
+ }
995
1198
  async listPlays() {
996
1199
  const response = await this.http.get(
997
1200
  "/api/v2/plays"
@@ -1357,7 +1560,11 @@ var DeeplineContext = class {
1357
1560
  /** Get detailed metadata for a tool. */
1358
1561
  get: (toolId) => this.client.getTool(toolId),
1359
1562
  /** Execute a tool and return the standard execution envelope. */
1360
- execute: async (toolId, input) => this.client.executeTool(toolId, input)
1563
+ execute: async (toolId, input) => this.client.executeTool(
1564
+ toolId,
1565
+ input,
1566
+ { includeToolMetadata: true }
1567
+ )
1361
1568
  };
1362
1569
  }
1363
1570
  get plays() {
@@ -1724,4 +1931,3 @@ export {
1724
1931
  writeCsvOutputFile,
1725
1932
  writeJsonOutputFile
1726
1933
  };
1727
- //# sourceMappingURL=index.mjs.map
@@ -367,6 +367,8 @@ const WORKFLOW_POOL_TTL_MS = 8 * 60 * 1000;
367
367
  const WORKFLOW_POOL_TARGET_SIZE = 2;
368
368
  const WORKFLOW_POOL_READY_TIMEOUT_MS = 1_500;
369
369
  const WORKFLOW_POOL_READY_POLL_MS = 250;
370
+ const WORKFLOW_POOL_REFILL_ON_MISS_TIMEOUT_MS = 2_500;
371
+ const WORKFLOW_POOL_REFILL_ON_MISS_MIN_AVAILABLE = 1;
370
372
 
371
373
  function buildDynamicWorkflowMetadata(
372
374
  params: PlayWorkflowParams,
@@ -901,7 +903,7 @@ async function submitViaPooledWorkflow(input: {
901
903
  return null;
902
904
  }
903
905
  const leaseStartedAt = Date.now();
904
- const pooledInstanceId = await leaseWorkflowPoolId(input.env);
906
+ let pooledInstanceId = await leaseWorkflowPoolId(input.env);
905
907
  const missCounts = pooledInstanceId
906
908
  ? null
907
909
  : await workflowPoolCount(input.env).catch(() => null);
@@ -919,6 +921,47 @@ async function submitViaPooledWorkflow(input: {
919
921
  : {}),
920
922
  },
921
923
  });
924
+
925
+ if (!pooledInstanceId) {
926
+ // A pool miss is often a timing gap rather than a true lack of warm
927
+ // capacity. Wait briefly for refill/promotion, then retry lease once
928
+ // before falling back to a cold workflow create.
929
+ const refillStartedAt = Date.now();
930
+ const refillResult = await refillWorkflowPool(input.env, {
931
+ waitReady: true,
932
+ minAvailable: WORKFLOW_POOL_REFILL_ON_MISS_MIN_AVAILABLE,
933
+ waitTimeoutMs: WORKFLOW_POOL_REFILL_ON_MISS_TIMEOUT_MS,
934
+ }).catch(() => null);
935
+ input.recordSubmitTiming({
936
+ phase: 'coordinator.workflow_pool_refill_on_miss',
937
+ ms: Date.now() - refillStartedAt,
938
+ graphHash: input.params.graphHash ?? null,
939
+ extra:
940
+ refillResult === null
941
+ ? { ok: false }
942
+ : {
943
+ ok: true,
944
+ available: refillResult.available,
945
+ warming: refillResult.warming,
946
+ created: refillResult.created,
947
+ promoted: refillResult.promoted,
948
+ removed: refillResult.removed,
949
+ waitedMs: refillResult.waitedMs,
950
+ waitIterations: refillResult.waitIterations,
951
+ },
952
+ });
953
+ if (refillResult?.available) {
954
+ const retryStartedAt = Date.now();
955
+ pooledInstanceId = await leaseWorkflowPoolId(input.env);
956
+ input.recordSubmitTiming({
957
+ phase: 'coordinator.workflow_pool_lease_retry',
958
+ ms: Date.now() - retryStartedAt,
959
+ graphHash: input.params.graphHash ?? null,
960
+ extra: { pooled: Boolean(pooledInstanceId) },
961
+ });
962
+ }
963
+ }
964
+
922
965
  if (!pooledInstanceId) {
923
966
  return null;
924
967
  }
@@ -2781,10 +2824,11 @@ function loadDynamicPlayWorkerSync(
2781
2824
  // which case the per-play stub throws a loud error on first use
2782
2825
  // (no silent fallbacks — see harness-stub.ts → requireBinding).
2783
2826
  HARNESS: env.HARNESS,
2827
+ VERCEL_PROTECTION_BYPASS_TOKEN: env.VERCEL_PROTECTION_BYPASS_TOKEN,
2784
2828
  // In-process runtime API bridge used by the play harness for status,
2785
2829
  // tool execution, DB session, and artifact callbacks. This avoids a
2786
- // public fetch hop and is required by apps/play-runner-workers/src/entry.ts.
2787
- RUNTIME_API: makeRuntimeApiBinding(),
2830
+ // public fetch hop when Cloudflare exposes the RuntimeApi export.
2831
+ ...makeRuntimeApiEnvBinding(),
2788
2832
  // NOTE: We intentionally do NOT pass `env.PLAYS_BUCKET` (an R2Bucket
2789
2833
  // binding) through to the per-play Worker's env. Including a raw
2790
2834
  // R2Bucket in the dynamically-loaded Worker's env makes Cloudflare
@@ -2861,7 +2905,8 @@ async function loadDynamicPlayWorker(
2861
2905
  // HARNESS, and child workflow control uses the coordinator URL in the
2862
2906
  // run request.
2863
2907
  HARNESS: env.HARNESS,
2864
- RUNTIME_API: makeRuntimeApiBinding(),
2908
+ VERCEL_PROTECTION_BYPASS_TOKEN: env.VERCEL_PROTECTION_BYPASS_TOKEN,
2909
+ ...makeRuntimeApiEnvBinding(),
2865
2910
  },
2866
2911
  };
2867
2912
  });
@@ -3169,11 +3214,15 @@ async function handleCoordinatorWarmup(
3169
3214
  * structured-cloneable. WorkerEntrypoint stubs ARE cloneable — same trick
3170
3215
  * `makePlayAssetsBinding` already uses.
3171
3216
  *
3172
- * Falls back transparently in legacy coordinators: if the binding isn't
3173
- * present in `env`, the harness uses its existing `fetch(req.baseUrl + path)`
3174
- * path, which still works (just slower).
3217
+ * Falls back transparently when Cloudflare does not expose module exports in
3218
+ * the current execution path: if the binding is omitted from `env`, the play
3219
+ * worker uses its existing `fetch(req.baseUrl + path)` transport.
3175
3220
  */
3176
- function makeRuntimeApiBinding(): { fetch(req: Request): Promise<Response> } {
3221
+ let loggedMissingRuntimeApiExport = false;
3222
+
3223
+ function makeRuntimeApiEnvBinding():
3224
+ | { RUNTIME_API: { fetch(req: Request): Promise<Response> } }
3225
+ | Record<string, never> {
3177
3226
  const exports = workersExports as unknown as {
3178
3227
  RuntimeApi?: (init: { props: undefined }) => {
3179
3228
  fetch(req: Request): Promise<Response>;
@@ -3181,11 +3230,15 @@ function makeRuntimeApiBinding(): { fetch(req: Request): Promise<Response> } {
3181
3230
  };
3182
3231
  const ctor = exports.RuntimeApi;
3183
3232
  if (typeof ctor !== 'function') {
3184
- throw new Error(
3185
- 'RuntimeApi is not registered on cloudflare:workers exports.',
3186
- );
3233
+ if (!loggedMissingRuntimeApiExport) {
3234
+ loggedMissingRuntimeApiExport = true;
3235
+ console.warn(
3236
+ '[coordinator] RuntimeApi is not registered on cloudflare:workers exports; using public runtime API transport.',
3237
+ );
3238
+ }
3239
+ return {};
3187
3240
  }
3188
- return ctor({ props: undefined });
3241
+ return { RUNTIME_API: ctor({ props: undefined }) };
3189
3242
  }
3190
3243
 
3191
3244
  function makeCoordinatorControlBinding(): {
@@ -3261,6 +3314,9 @@ function mapWorkflowResult(
3261
3314
  : null;
3262
3315
  return {
3263
3316
  runId,
3317
+ ...(typeof output?.playName === 'string' && output.playName.trim()
3318
+ ? { playName: output.playName.trim() }
3319
+ : {}),
3264
3320
  status: mapped,
3265
3321
  result: output?.result ?? status.output ?? null,
3266
3322
  error,