deepline 0.1.21 → 0.1.23
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/cli/index.js +552 -237
- package/dist/cli/index.mjs +609 -289
- package/dist/index.d.mts +21 -58
- package/dist/index.d.ts +21 -58
- package/dist/index.js +177 -92
- package/dist/index.mjs +177 -92
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +3 -1
- package/dist/repo/apps/play-runner-workers/src/entry.ts +153 -0
- package/dist/repo/sdk/src/client.ts +243 -124
- package/dist/repo/sdk/src/types.ts +8 -14
- package/dist/repo/sdk/src/version.ts +1 -1
- package/dist/repo/shared_libs/play-runtime/execution-plan.ts +27 -2
- package/dist/repo/shared_libs/play-runtime/profiles.ts +4 -14
- package/dist/repo/shared_libs/play-runtime/runtime-actions.ts +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -241,7 +241,7 @@ function resolveConfig(options) {
|
|
|
241
241
|
}
|
|
242
242
|
|
|
243
243
|
// src/version.ts
|
|
244
|
-
var SDK_VERSION = "0.1.
|
|
244
|
+
var SDK_VERSION = "0.1.23";
|
|
245
245
|
var SDK_API_CONTRACT = "2026-05-runs-v2";
|
|
246
246
|
|
|
247
247
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
@@ -529,11 +529,24 @@ function sleep(ms) {
|
|
|
529
529
|
// src/client.ts
|
|
530
530
|
var TERMINAL_PLAY_STATUSES = /* @__PURE__ */ new Set(["completed", "failed", "cancelled"]);
|
|
531
531
|
var INCLUDE_TOOL_METADATA_HEADER = "x-deepline-include-tool-metadata";
|
|
532
|
+
var COMPILE_MANIFEST_RETRY_DELAYS_MS = [250, 1e3];
|
|
533
|
+
function sleep2(ms) {
|
|
534
|
+
return new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
535
|
+
}
|
|
536
|
+
function isTransientCompileManifestError(error) {
|
|
537
|
+
if (error instanceof DeeplineError && typeof error.statusCode === "number") {
|
|
538
|
+
return error.statusCode === 408 || error.statusCode === 425 || error.statusCode === 499 || error.statusCode >= 500 && error.statusCode < 600;
|
|
539
|
+
}
|
|
540
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
541
|
+
return /fetch failed|connection (?:closed|reset|terminated)|socket hang up|econnreset|etimedout|eai_again|abort/i.test(
|
|
542
|
+
message
|
|
543
|
+
);
|
|
544
|
+
}
|
|
532
545
|
function isRecord(value) {
|
|
533
546
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
534
547
|
}
|
|
535
548
|
function normalizePlayStatus(raw) {
|
|
536
|
-
const status = typeof raw.status === "string" ? raw.status :
|
|
549
|
+
const status = typeof raw.status === "string" ? raw.status : "running";
|
|
537
550
|
const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : "";
|
|
538
551
|
return {
|
|
539
552
|
...raw,
|
|
@@ -541,23 +554,6 @@ function normalizePlayStatus(raw) {
|
|
|
541
554
|
status
|
|
542
555
|
};
|
|
543
556
|
}
|
|
544
|
-
function mapLegacyTemporalStatus(status) {
|
|
545
|
-
switch (status.trim().toUpperCase()) {
|
|
546
|
-
case "PENDING":
|
|
547
|
-
return "queued";
|
|
548
|
-
case "COMPLETED":
|
|
549
|
-
return "completed";
|
|
550
|
-
case "FAILED":
|
|
551
|
-
return "failed";
|
|
552
|
-
case "CANCELLED":
|
|
553
|
-
case "TERMINATED":
|
|
554
|
-
case "TIMED_OUT":
|
|
555
|
-
return "cancelled";
|
|
556
|
-
case "RUNNING":
|
|
557
|
-
default:
|
|
558
|
-
return "running";
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
557
|
function decodeBase64Bytes(value) {
|
|
562
558
|
const binary = atob(value);
|
|
563
559
|
const bytes = new Uint8Array(binary.length);
|
|
@@ -566,6 +562,79 @@ function decodeBase64Bytes(value) {
|
|
|
566
562
|
}
|
|
567
563
|
return bytes;
|
|
568
564
|
}
|
|
565
|
+
function readStringArray(value) {
|
|
566
|
+
return Array.isArray(value) ? value.filter((line) => typeof line === "string") : [];
|
|
567
|
+
}
|
|
568
|
+
function getPlayLiveEventPayload(event) {
|
|
569
|
+
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
570
|
+
}
|
|
571
|
+
function normalizeLiveStatus(value) {
|
|
572
|
+
if (value === "queued" || value === "running" || value === "waiting" || value === "completed" || value === "failed" || value === "cancelled") {
|
|
573
|
+
return value;
|
|
574
|
+
}
|
|
575
|
+
return null;
|
|
576
|
+
}
|
|
577
|
+
function updatePlayLiveStatusState(state, event) {
|
|
578
|
+
const payload = getPlayLiveEventPayload(event);
|
|
579
|
+
if (event.type === "play.run.log") {
|
|
580
|
+
state.logs.push(...readStringArray(payload.lines));
|
|
581
|
+
return null;
|
|
582
|
+
}
|
|
583
|
+
if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
|
|
584
|
+
return null;
|
|
585
|
+
}
|
|
586
|
+
const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : state.runId;
|
|
587
|
+
const status = normalizeLiveStatus(payload.status) ?? state.status;
|
|
588
|
+
const logs = readStringArray(payload.logs);
|
|
589
|
+
if (logs.length > 0 || event.type === "play.run.snapshot") {
|
|
590
|
+
state.logs = logs;
|
|
591
|
+
}
|
|
592
|
+
if ("result" in payload) {
|
|
593
|
+
state.result = payload.result;
|
|
594
|
+
}
|
|
595
|
+
if (typeof payload.error === "string" && payload.error.trim()) {
|
|
596
|
+
state.error = payload.error;
|
|
597
|
+
}
|
|
598
|
+
state.runId = runId;
|
|
599
|
+
state.status = status;
|
|
600
|
+
const progressRecord = payload.progress && typeof payload.progress === "object" && !Array.isArray(payload.progress) ? payload.progress : {};
|
|
601
|
+
const next = {
|
|
602
|
+
...payload,
|
|
603
|
+
runId,
|
|
604
|
+
status,
|
|
605
|
+
progress: {
|
|
606
|
+
...progressRecord,
|
|
607
|
+
status: typeof progressRecord.status === "string" ? progressRecord.status : status,
|
|
608
|
+
logs: state.logs,
|
|
609
|
+
...state.error ? { error: state.error } : {}
|
|
610
|
+
},
|
|
611
|
+
..."result" in state ? { result: state.result } : {}
|
|
612
|
+
};
|
|
613
|
+
state.latest = next;
|
|
614
|
+
return next;
|
|
615
|
+
}
|
|
616
|
+
function playRunResultFromStatus(status, startedAt, fallbackRunId) {
|
|
617
|
+
return {
|
|
618
|
+
success: status.status === "completed",
|
|
619
|
+
runId: status.runId || fallbackRunId,
|
|
620
|
+
result: status.result,
|
|
621
|
+
logs: status.progress?.logs ?? [],
|
|
622
|
+
durationMs: Date.now() - startedAt,
|
|
623
|
+
error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
function playRunStatusFromState(state) {
|
|
627
|
+
return {
|
|
628
|
+
runId: state.runId,
|
|
629
|
+
status: state.status,
|
|
630
|
+
progress: {
|
|
631
|
+
status: state.status,
|
|
632
|
+
logs: state.logs,
|
|
633
|
+
...state.error ? { error: state.error } : {}
|
|
634
|
+
},
|
|
635
|
+
..."result" in state ? { result: state.result } : {}
|
|
636
|
+
};
|
|
637
|
+
}
|
|
569
638
|
var DeeplineClient = class {
|
|
570
639
|
http;
|
|
571
640
|
config;
|
|
@@ -675,7 +744,7 @@ var DeeplineClient = class {
|
|
|
675
744
|
/**
|
|
676
745
|
* Search available tools using Deepline's ranked backend search.
|
|
677
746
|
*
|
|
678
|
-
* This is the same discovery surface used by the
|
|
747
|
+
* This is the same discovery surface used by the CLI: it ranks across
|
|
679
748
|
* tool metadata, categories, agent guidance, and input schema fields.
|
|
680
749
|
*/
|
|
681
750
|
async searchTools(options = {}) {
|
|
@@ -768,7 +837,7 @@ var DeeplineClient = class {
|
|
|
768
837
|
* `progress.logs`; they are not part of the user output object.
|
|
769
838
|
*
|
|
770
839
|
* @param request - Play run configuration (name, code, input, etc.)
|
|
771
|
-
* @returns
|
|
840
|
+
* @returns Run metadata including the public `workflowId`
|
|
772
841
|
*
|
|
773
842
|
* @example
|
|
774
843
|
* ```typescript
|
|
@@ -878,8 +947,22 @@ var DeeplineClient = class {
|
|
|
878
947
|
});
|
|
879
948
|
}
|
|
880
949
|
async compilePlayManifest(input) {
|
|
881
|
-
const
|
|
882
|
-
|
|
950
|
+
const retryDelays = COMPILE_MANIFEST_RETRY_DELAYS_MS.slice(
|
|
951
|
+
0,
|
|
952
|
+
Math.max(0, this.config.maxRetries)
|
|
953
|
+
);
|
|
954
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
955
|
+
try {
|
|
956
|
+
const response = await this.http.post("/api/v2/plays/compile-manifest", input);
|
|
957
|
+
return response.compilerManifest;
|
|
958
|
+
} catch (error) {
|
|
959
|
+
const delayMs = retryDelays[attempt];
|
|
960
|
+
if (delayMs === void 0 || !isTransientCompileManifestError(error)) {
|
|
961
|
+
throw error;
|
|
962
|
+
}
|
|
963
|
+
await sleep2(delayMs);
|
|
964
|
+
}
|
|
965
|
+
}
|
|
883
966
|
}
|
|
884
967
|
/**
|
|
885
968
|
* Check a bundled play artifact against the server's current play compiler.
|
|
@@ -1060,9 +1143,6 @@ var DeeplineClient = class {
|
|
|
1060
1143
|
* Internal/advanced primitive. Public callers should usually prefer
|
|
1061
1144
|
* {@link runPlay}, {@link PlayJob.get}, or `deepline play run --watch`.
|
|
1062
1145
|
*
|
|
1063
|
-
* Poll this method until `status` reaches a terminal state:
|
|
1064
|
-
* `'completed'`, `'failed'`, or `'cancelled'`.
|
|
1065
|
-
*
|
|
1066
1146
|
* @param workflowId - Play-run id from {@link startPlayRun}
|
|
1067
1147
|
* @returns Current status with progress logs and partial results
|
|
1068
1148
|
*
|
|
@@ -1084,35 +1164,11 @@ var DeeplineClient = class {
|
|
|
1084
1164
|
);
|
|
1085
1165
|
return normalizePlayStatus(response);
|
|
1086
1166
|
}
|
|
1087
|
-
/**
|
|
1088
|
-
* Get the lightweight tail-polling status for a play execution.
|
|
1089
|
-
*
|
|
1090
|
-
* This is intentionally smaller than {@link getPlayStatus}: it returns the
|
|
1091
|
-
* fields needed for CLI log tailing while the run is in flight, without
|
|
1092
|
-
* forcing the API to rebuild final result views on every poll. Call
|
|
1093
|
-
* {@link getPlayStatus} once after a terminal state for the full result.
|
|
1094
|
-
*/
|
|
1095
|
-
async getPlayTailStatus(workflowId, options) {
|
|
1096
|
-
const params = new URLSearchParams({ mode: "tail" });
|
|
1097
|
-
if (typeof options?.afterLogIndex === "number") {
|
|
1098
|
-
params.set("afterLogIndex", String(options.afterLogIndex));
|
|
1099
|
-
}
|
|
1100
|
-
if (typeof options?.waitMs === "number") {
|
|
1101
|
-
params.set("waitMs", String(options.waitMs));
|
|
1102
|
-
}
|
|
1103
|
-
if (options?.terminalOnly) {
|
|
1104
|
-
params.set("terminalOnly", "true");
|
|
1105
|
-
}
|
|
1106
|
-
const response = await this.http.get(
|
|
1107
|
-
`/api/v2/plays/run/${encodeURIComponent(workflowId)}?${params.toString()}`
|
|
1108
|
-
);
|
|
1109
|
-
return normalizePlayStatus(response);
|
|
1110
|
-
}
|
|
1111
1167
|
/**
|
|
1112
1168
|
* Stream semantic play-run events using the same SSE feed as the dashboard.
|
|
1113
1169
|
*
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1170
|
+
* The server emits a canonical `play.run.snapshot` event first for every
|
|
1171
|
+
* connection, then incremental live events until terminal state or reconnect.
|
|
1116
1172
|
*/
|
|
1117
1173
|
async *streamPlayRunEvents(workflowId, options) {
|
|
1118
1174
|
const headers = options?.lastEventId && options.lastEventId.trim() ? { "Last-Event-ID": options.lastEventId.trim() } : void 0;
|
|
@@ -1132,7 +1188,7 @@ var DeeplineClient = class {
|
|
|
1132
1188
|
*
|
|
1133
1189
|
* Sends a stop request for the run.
|
|
1134
1190
|
*
|
|
1135
|
-
* @param workflowId -
|
|
1191
|
+
* @param workflowId - Public Deepline play-run id to cancel
|
|
1136
1192
|
*
|
|
1137
1193
|
* @example
|
|
1138
1194
|
* ```typescript
|
|
@@ -1148,7 +1204,7 @@ var DeeplineClient = class {
|
|
|
1148
1204
|
/**
|
|
1149
1205
|
* Stop a running play execution, including open HITL waits.
|
|
1150
1206
|
*
|
|
1151
|
-
* @param workflowId -
|
|
1207
|
+
* @param workflowId - Public Deepline play-run id to stop
|
|
1152
1208
|
* @param options.reason - Optional audit/debug reason
|
|
1153
1209
|
*/
|
|
1154
1210
|
async stopPlay(workflowId, options) {
|
|
@@ -1220,32 +1276,42 @@ var DeeplineClient = class {
|
|
|
1220
1276
|
);
|
|
1221
1277
|
return response.runs ?? [];
|
|
1222
1278
|
}
|
|
1223
|
-
/**
|
|
1224
|
-
* Fetch the lightweight tail status for a run using the public runs resource model.
|
|
1225
|
-
*
|
|
1226
|
-
* This is the SDK equivalent of:
|
|
1227
|
-
*
|
|
1228
|
-
* ```bash
|
|
1229
|
-
* deepline runs tail <run-id> --json
|
|
1230
|
-
* ```
|
|
1231
|
-
*/
|
|
1279
|
+
/** Read the canonical run stream and return the latest run snapshot. */
|
|
1232
1280
|
async tailRun(runId, options) {
|
|
1233
|
-
const
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1281
|
+
const state = {
|
|
1282
|
+
runId,
|
|
1283
|
+
status: "running",
|
|
1284
|
+
logs: [],
|
|
1285
|
+
latest: null
|
|
1286
|
+
};
|
|
1287
|
+
let terminal = false;
|
|
1288
|
+
for await (const event of this.streamPlayRunEvents(runId, {
|
|
1289
|
+
mode: "cli",
|
|
1290
|
+
signal: options?.signal
|
|
1291
|
+
})) {
|
|
1292
|
+
const status = updatePlayLiveStatusState(state, event);
|
|
1293
|
+
if (!status) {
|
|
1294
|
+
continue;
|
|
1295
|
+
}
|
|
1296
|
+
terminal = TERMINAL_PLAY_STATUSES.has(status.status);
|
|
1297
|
+
if (terminal) {
|
|
1298
|
+
break;
|
|
1299
|
+
}
|
|
1237
1300
|
}
|
|
1238
|
-
if (
|
|
1239
|
-
|
|
1301
|
+
if (terminal && state.latest) {
|
|
1302
|
+
return await this.getRunStatus(state.latest.runId || runId).catch(
|
|
1303
|
+
() => state.latest ?? playRunStatusFromState(state)
|
|
1304
|
+
);
|
|
1240
1305
|
}
|
|
1241
|
-
if (
|
|
1242
|
-
|
|
1306
|
+
if (state.latest) {
|
|
1307
|
+
return state.latest;
|
|
1243
1308
|
}
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1309
|
+
throw new DeeplineError(
|
|
1310
|
+
`Run stream for ${runId} ended before the initial snapshot.`,
|
|
1311
|
+
void 0,
|
|
1312
|
+
"PLAY_RUN_STREAM_EMPTY",
|
|
1313
|
+
{ runId }
|
|
1247
1314
|
);
|
|
1248
|
-
return normalizePlayStatus(response);
|
|
1249
1315
|
}
|
|
1250
1316
|
/**
|
|
1251
1317
|
* Fetch persisted logs for a run using the public runs resource model.
|
|
@@ -1402,11 +1468,11 @@ var DeeplineClient = class {
|
|
|
1402
1468
|
// Plays — high-level orchestration
|
|
1403
1469
|
// ——————————————————————————————————————————————————————————
|
|
1404
1470
|
/**
|
|
1405
|
-
* Run a play end-to-end: submit,
|
|
1471
|
+
* Run a play end-to-end: submit, stream until terminal, return result.
|
|
1406
1472
|
*
|
|
1407
1473
|
* This is the highest-level play execution method. It submits the play,
|
|
1408
|
-
*
|
|
1409
|
-
* and timing. Supports cancellation via `AbortSignal`.
|
|
1474
|
+
* reads the canonical run stream for status updates, and returns a structured
|
|
1475
|
+
* result with logs and timing. Supports cancellation via `AbortSignal`.
|
|
1410
1476
|
*
|
|
1411
1477
|
* @param code - Source string fallback; pass the bundled artifact in `options.artifact`
|
|
1412
1478
|
* @param csvPath - Input CSV path, or `null`
|
|
@@ -1422,7 +1488,6 @@ var DeeplineClient = class {
|
|
|
1422
1488
|
* const logs = status.progress?.logs ?? [];
|
|
1423
1489
|
* console.log(`[${status.status}] ${logs.length} log lines`);
|
|
1424
1490
|
* },
|
|
1425
|
-
* pollIntervalMs: 1000,
|
|
1426
1491
|
* });
|
|
1427
1492
|
*
|
|
1428
1493
|
* if (result.success) {
|
|
@@ -1453,33 +1518,53 @@ var DeeplineClient = class {
|
|
|
1453
1518
|
packagedFiles: options?.packagedFiles,
|
|
1454
1519
|
force: options?.force
|
|
1455
1520
|
});
|
|
1456
|
-
const pollInterval = options?.pollIntervalMs ?? 500;
|
|
1457
1521
|
const start = Date.now();
|
|
1458
|
-
|
|
1522
|
+
const state = {
|
|
1523
|
+
runId: workflowId,
|
|
1524
|
+
status: "running",
|
|
1525
|
+
logs: [],
|
|
1526
|
+
latest: null
|
|
1527
|
+
};
|
|
1528
|
+
if (options?.signal?.aborted) {
|
|
1529
|
+
await this.cancelPlay(workflowId);
|
|
1530
|
+
return {
|
|
1531
|
+
success: false,
|
|
1532
|
+
runId: workflowId,
|
|
1533
|
+
logs: [],
|
|
1534
|
+
durationMs: Date.now() - start,
|
|
1535
|
+
error: "Cancelled by user"
|
|
1536
|
+
};
|
|
1537
|
+
}
|
|
1538
|
+
for await (const event of this.streamPlayRunEvents(workflowId, {
|
|
1539
|
+
mode: "cli",
|
|
1540
|
+
signal: options?.signal
|
|
1541
|
+
})) {
|
|
1459
1542
|
if (options?.signal?.aborted) {
|
|
1460
1543
|
await this.cancelPlay(workflowId);
|
|
1461
1544
|
return {
|
|
1462
1545
|
success: false,
|
|
1463
1546
|
runId: workflowId,
|
|
1464
|
-
logs:
|
|
1547
|
+
logs: state.logs,
|
|
1465
1548
|
durationMs: Date.now() - start,
|
|
1466
1549
|
error: "Cancelled by user"
|
|
1467
1550
|
};
|
|
1468
1551
|
}
|
|
1469
|
-
const status =
|
|
1552
|
+
const status = updatePlayLiveStatusState(state, event);
|
|
1553
|
+
if (!status) {
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1470
1556
|
options?.onProgress?.(status);
|
|
1471
1557
|
if (TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
runId: status.runId || workflowId,
|
|
1475
|
-
result: status.result,
|
|
1476
|
-
logs: status.progress?.logs ?? [],
|
|
1477
|
-
durationMs: Date.now() - start,
|
|
1478
|
-
error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
|
|
1479
|
-
};
|
|
1558
|
+
const finalStatus = await this.getPlayStatus(status.runId || workflowId).catch(() => status);
|
|
1559
|
+
return playRunResultFromStatus(finalStatus, start, workflowId);
|
|
1480
1560
|
}
|
|
1481
|
-
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
1482
1561
|
}
|
|
1562
|
+
throw new DeeplineError(
|
|
1563
|
+
`Run stream for ${workflowId} ended before the run reached a terminal state.`,
|
|
1564
|
+
void 0,
|
|
1565
|
+
"PLAY_RUN_STREAM_ENDED",
|
|
1566
|
+
{ runId: workflowId, workflowId }
|
|
1567
|
+
);
|
|
1483
1568
|
}
|
|
1484
1569
|
// ——————————————————————————————————————————————————————————
|
|
1485
1570
|
// Health
|