deepline 0.1.20 → 0.1.22
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 +845 -337
- package/dist/cli/index.mjs +902 -389
- package/dist/index.d.mts +23 -58
- package/dist/index.d.ts +23 -58
- package/dist/index.js +195 -92
- package/dist/index.mjs +195 -92
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +888 -227
- package/dist/repo/apps/play-runner-workers/src/dedup-do.ts +540 -36
- package/dist/repo/apps/play-runner-workers/src/entry.ts +477 -374
- package/dist/repo/sdk/src/client.ts +245 -118
- package/dist/repo/sdk/src/http.ts +19 -1
- package/dist/repo/sdk/src/plays/harness-stub.ts +12 -0
- 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/profiles.ts +4 -14
- package/dist/repo/shared_libs/play-runtime/runtime-actions.ts +1 -1
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +3 -6
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -195,7 +195,7 @@ function resolveConfig(options) {
|
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
// src/version.ts
|
|
198
|
-
var SDK_VERSION = "0.1.
|
|
198
|
+
var SDK_VERSION = "0.1.22";
|
|
199
199
|
var SDK_API_CONTRACT = "2026-05-runs-v2";
|
|
200
200
|
|
|
201
201
|
// ../shared_libs/play-runtime/coordinator-headers.ts
|
|
@@ -278,7 +278,7 @@ var HttpClient = class {
|
|
|
278
278
|
const response = await fetch(candidateUrl, {
|
|
279
279
|
method,
|
|
280
280
|
headers,
|
|
281
|
-
body: options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
281
|
+
body: options?.formData !== void 0 ? options.formData : options?.body !== void 0 ? JSON.stringify(options.body) : void 0,
|
|
282
282
|
signal: controller.signal
|
|
283
283
|
});
|
|
284
284
|
clearTimeout(timeoutId);
|
|
@@ -397,6 +397,13 @@ var HttpClient = class {
|
|
|
397
397
|
headers
|
|
398
398
|
});
|
|
399
399
|
}
|
|
400
|
+
async postFormData(path, formData, headers) {
|
|
401
|
+
return this.request(path, {
|
|
402
|
+
method: "POST",
|
|
403
|
+
formData,
|
|
404
|
+
headers
|
|
405
|
+
});
|
|
406
|
+
}
|
|
400
407
|
/**
|
|
401
408
|
* Send a DELETE request.
|
|
402
409
|
*
|
|
@@ -480,7 +487,7 @@ function isRecord(value) {
|
|
|
480
487
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
481
488
|
}
|
|
482
489
|
function normalizePlayStatus(raw) {
|
|
483
|
-
const status = typeof raw.status === "string" ? raw.status :
|
|
490
|
+
const status = typeof raw.status === "string" ? raw.status : "running";
|
|
484
491
|
const runId = typeof raw.runId === "string" ? raw.runId : typeof raw.workflowId === "string" ? raw.workflowId : "";
|
|
485
492
|
return {
|
|
486
493
|
...raw,
|
|
@@ -488,22 +495,86 @@ function normalizePlayStatus(raw) {
|
|
|
488
495
|
status
|
|
489
496
|
};
|
|
490
497
|
}
|
|
491
|
-
function
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
498
|
+
function decodeBase64Bytes(value) {
|
|
499
|
+
const binary = atob(value);
|
|
500
|
+
const bytes = new Uint8Array(binary.length);
|
|
501
|
+
for (let index = 0; index < binary.length; index += 1) {
|
|
502
|
+
bytes[index] = binary.charCodeAt(index);
|
|
503
|
+
}
|
|
504
|
+
return bytes;
|
|
505
|
+
}
|
|
506
|
+
function readStringArray(value) {
|
|
507
|
+
return Array.isArray(value) ? value.filter((line) => typeof line === "string") : [];
|
|
508
|
+
}
|
|
509
|
+
function getPlayLiveEventPayload(event) {
|
|
510
|
+
return event.payload && typeof event.payload === "object" ? event.payload : {};
|
|
511
|
+
}
|
|
512
|
+
function normalizeLiveStatus(value) {
|
|
513
|
+
if (value === "queued" || value === "running" || value === "waiting" || value === "completed" || value === "failed" || value === "cancelled") {
|
|
514
|
+
return value;
|
|
515
|
+
}
|
|
516
|
+
return null;
|
|
517
|
+
}
|
|
518
|
+
function updatePlayLiveStatusState(state, event) {
|
|
519
|
+
const payload = getPlayLiveEventPayload(event);
|
|
520
|
+
if (event.type === "play.run.log") {
|
|
521
|
+
state.logs.push(...readStringArray(payload.lines));
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
if (event.type !== "play.run.snapshot" && event.type !== "play.run.status" && event.type !== "play.run.final_status") {
|
|
525
|
+
return null;
|
|
526
|
+
}
|
|
527
|
+
const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : state.runId;
|
|
528
|
+
const status = normalizeLiveStatus(payload.status) ?? state.status;
|
|
529
|
+
const logs = readStringArray(payload.logs);
|
|
530
|
+
if (logs.length > 0 || event.type === "play.run.snapshot") {
|
|
531
|
+
state.logs = logs;
|
|
532
|
+
}
|
|
533
|
+
if ("result" in payload) {
|
|
534
|
+
state.result = payload.result;
|
|
506
535
|
}
|
|
536
|
+
if (typeof payload.error === "string" && payload.error.trim()) {
|
|
537
|
+
state.error = payload.error;
|
|
538
|
+
}
|
|
539
|
+
state.runId = runId;
|
|
540
|
+
state.status = status;
|
|
541
|
+
const progressRecord = payload.progress && typeof payload.progress === "object" && !Array.isArray(payload.progress) ? payload.progress : {};
|
|
542
|
+
const next = {
|
|
543
|
+
...payload,
|
|
544
|
+
runId,
|
|
545
|
+
status,
|
|
546
|
+
progress: {
|
|
547
|
+
...progressRecord,
|
|
548
|
+
status: typeof progressRecord.status === "string" ? progressRecord.status : status,
|
|
549
|
+
logs: state.logs,
|
|
550
|
+
...state.error ? { error: state.error } : {}
|
|
551
|
+
},
|
|
552
|
+
..."result" in state ? { result: state.result } : {}
|
|
553
|
+
};
|
|
554
|
+
state.latest = next;
|
|
555
|
+
return next;
|
|
556
|
+
}
|
|
557
|
+
function playRunResultFromStatus(status, startedAt, fallbackRunId) {
|
|
558
|
+
return {
|
|
559
|
+
success: status.status === "completed",
|
|
560
|
+
runId: status.runId || fallbackRunId,
|
|
561
|
+
result: status.result,
|
|
562
|
+
logs: status.progress?.logs ?? [],
|
|
563
|
+
durationMs: Date.now() - startedAt,
|
|
564
|
+
error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
|
|
565
|
+
};
|
|
566
|
+
}
|
|
567
|
+
function playRunStatusFromState(state) {
|
|
568
|
+
return {
|
|
569
|
+
runId: state.runId,
|
|
570
|
+
status: state.status,
|
|
571
|
+
progress: {
|
|
572
|
+
status: state.status,
|
|
573
|
+
logs: state.logs,
|
|
574
|
+
...state.error ? { error: state.error } : {}
|
|
575
|
+
},
|
|
576
|
+
..."result" in state ? { result: state.result } : {}
|
|
577
|
+
};
|
|
507
578
|
}
|
|
508
579
|
var DeeplineClient = class {
|
|
509
580
|
http;
|
|
@@ -614,7 +685,7 @@ var DeeplineClient = class {
|
|
|
614
685
|
/**
|
|
615
686
|
* Search available tools using Deepline's ranked backend search.
|
|
616
687
|
*
|
|
617
|
-
* This is the same discovery surface used by the
|
|
688
|
+
* This is the same discovery surface used by the CLI: it ranks across
|
|
618
689
|
* tool metadata, categories, agent guidance, and input schema fields.
|
|
619
690
|
*/
|
|
620
691
|
async searchTools(options = {}) {
|
|
@@ -707,7 +778,7 @@ var DeeplineClient = class {
|
|
|
707
778
|
* `progress.logs`; they are not part of the user output object.
|
|
708
779
|
*
|
|
709
780
|
* @param request - Play run configuration (name, code, input, etc.)
|
|
710
|
-
* @returns
|
|
781
|
+
* @returns Run metadata including the public `workflowId`
|
|
711
782
|
*
|
|
712
783
|
* @example
|
|
713
784
|
* ```typescript
|
|
@@ -956,9 +1027,34 @@ var DeeplineClient = class {
|
|
|
956
1027
|
* ```
|
|
957
1028
|
*/
|
|
958
1029
|
async stagePlayFiles(files) {
|
|
959
|
-
const
|
|
1030
|
+
const formData = new FormData();
|
|
1031
|
+
formData.set(
|
|
1032
|
+
"metadata",
|
|
1033
|
+
JSON.stringify({
|
|
1034
|
+
files: files.map((file, index) => ({
|
|
1035
|
+
index,
|
|
1036
|
+
logicalPath: file.logicalPath,
|
|
1037
|
+
contentHash: file.contentHash,
|
|
1038
|
+
contentType: file.contentType,
|
|
1039
|
+
bytes: file.bytes
|
|
1040
|
+
}))
|
|
1041
|
+
})
|
|
1042
|
+
);
|
|
1043
|
+
for (const [index, file] of files.entries()) {
|
|
1044
|
+
const bytes = decodeBase64Bytes(file.contentBase64);
|
|
1045
|
+
const body = bytes.buffer.slice(
|
|
1046
|
+
bytes.byteOffset,
|
|
1047
|
+
bytes.byteOffset + bytes.byteLength
|
|
1048
|
+
);
|
|
1049
|
+
formData.set(
|
|
1050
|
+
`file:${index}`,
|
|
1051
|
+
new Blob([body], { type: file.contentType }),
|
|
1052
|
+
file.logicalPath
|
|
1053
|
+
);
|
|
1054
|
+
}
|
|
1055
|
+
const response = await this.http.postFormData(
|
|
960
1056
|
"/api/v2/plays/files/stage",
|
|
961
|
-
|
|
1057
|
+
formData
|
|
962
1058
|
);
|
|
963
1059
|
return response.files;
|
|
964
1060
|
}
|
|
@@ -974,9 +1070,6 @@ var DeeplineClient = class {
|
|
|
974
1070
|
* Internal/advanced primitive. Public callers should usually prefer
|
|
975
1071
|
* {@link runPlay}, {@link PlayJob.get}, or `deepline play run --watch`.
|
|
976
1072
|
*
|
|
977
|
-
* Poll this method until `status` reaches a terminal state:
|
|
978
|
-
* `'completed'`, `'failed'`, or `'cancelled'`.
|
|
979
|
-
*
|
|
980
1073
|
* @param workflowId - Play-run id from {@link startPlayRun}
|
|
981
1074
|
* @returns Current status with progress logs and partial results
|
|
982
1075
|
*
|
|
@@ -987,41 +1080,22 @@ var DeeplineClient = class {
|
|
|
987
1080
|
* console.log(`Logs: ${status.progress?.logs.length ?? 0} lines`);
|
|
988
1081
|
* ```
|
|
989
1082
|
*/
|
|
990
|
-
async getPlayStatus(workflowId) {
|
|
991
|
-
const
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
return normalizePlayStatus(response);
|
|
995
|
-
}
|
|
996
|
-
/**
|
|
997
|
-
* Get the lightweight tail-polling status for a play execution.
|
|
998
|
-
*
|
|
999
|
-
* This is intentionally smaller than {@link getPlayStatus}: it returns the
|
|
1000
|
-
* fields needed for CLI log tailing while the run is in flight, without
|
|
1001
|
-
* forcing the API to rebuild final result views on every poll. Call
|
|
1002
|
-
* {@link getPlayStatus} once after a terminal state for the full result.
|
|
1003
|
-
*/
|
|
1004
|
-
async getPlayTailStatus(workflowId, options) {
|
|
1005
|
-
const params = new URLSearchParams({ mode: "tail" });
|
|
1006
|
-
if (typeof options?.afterLogIndex === "number") {
|
|
1007
|
-
params.set("afterLogIndex", String(options.afterLogIndex));
|
|
1008
|
-
}
|
|
1009
|
-
if (typeof options?.waitMs === "number") {
|
|
1010
|
-
params.set("waitMs", String(options.waitMs));
|
|
1011
|
-
}
|
|
1012
|
-
if (options?.terminalOnly) {
|
|
1013
|
-
params.set("terminalOnly", "true");
|
|
1083
|
+
async getPlayStatus(workflowId, options) {
|
|
1084
|
+
const params = new URLSearchParams();
|
|
1085
|
+
if (options?.billing === false) {
|
|
1086
|
+
params.set("billing", "false");
|
|
1014
1087
|
}
|
|
1088
|
+
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
1015
1089
|
const response = await this.http.get(
|
|
1016
|
-
`/api/v2/plays/run/${encodeURIComponent(workflowId)}
|
|
1090
|
+
`/api/v2/plays/run/${encodeURIComponent(workflowId)}${query}`
|
|
1017
1091
|
);
|
|
1018
1092
|
return normalizePlayStatus(response);
|
|
1019
1093
|
}
|
|
1020
1094
|
/**
|
|
1021
1095
|
* Stream semantic play-run events using the same SSE feed as the dashboard.
|
|
1022
1096
|
*
|
|
1023
|
-
*
|
|
1024
|
-
*
|
|
1097
|
+
* The server emits a canonical `play.run.snapshot` event first for every
|
|
1098
|
+
* connection, then incremental live events until terminal state or reconnect.
|
|
1025
1099
|
*/
|
|
1026
1100
|
async *streamPlayRunEvents(workflowId, options) {
|
|
1027
1101
|
const headers = options?.lastEventId && options.lastEventId.trim() ? { "Last-Event-ID": options.lastEventId.trim() } : void 0;
|
|
@@ -1041,7 +1115,7 @@ var DeeplineClient = class {
|
|
|
1041
1115
|
*
|
|
1042
1116
|
* Sends a stop request for the run.
|
|
1043
1117
|
*
|
|
1044
|
-
* @param workflowId -
|
|
1118
|
+
* @param workflowId - Public Deepline play-run id to cancel
|
|
1045
1119
|
*
|
|
1046
1120
|
* @example
|
|
1047
1121
|
* ```typescript
|
|
@@ -1057,7 +1131,7 @@ var DeeplineClient = class {
|
|
|
1057
1131
|
/**
|
|
1058
1132
|
* Stop a running play execution, including open HITL waits.
|
|
1059
1133
|
*
|
|
1060
|
-
* @param workflowId -
|
|
1134
|
+
* @param workflowId - Public Deepline play-run id to stop
|
|
1061
1135
|
* @param options.reason - Optional audit/debug reason
|
|
1062
1136
|
*/
|
|
1063
1137
|
async stopPlay(workflowId, options) {
|
|
@@ -1129,32 +1203,42 @@ var DeeplineClient = class {
|
|
|
1129
1203
|
);
|
|
1130
1204
|
return response.runs ?? [];
|
|
1131
1205
|
}
|
|
1132
|
-
/**
|
|
1133
|
-
* Fetch the lightweight tail status for a run using the public runs resource model.
|
|
1134
|
-
*
|
|
1135
|
-
* This is the SDK equivalent of:
|
|
1136
|
-
*
|
|
1137
|
-
* ```bash
|
|
1138
|
-
* deepline runs tail <run-id> --json
|
|
1139
|
-
* ```
|
|
1140
|
-
*/
|
|
1206
|
+
/** Read the canonical run stream and return the latest run snapshot. */
|
|
1141
1207
|
async tailRun(runId, options) {
|
|
1142
|
-
const
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1208
|
+
const state = {
|
|
1209
|
+
runId,
|
|
1210
|
+
status: "running",
|
|
1211
|
+
logs: [],
|
|
1212
|
+
latest: null
|
|
1213
|
+
};
|
|
1214
|
+
let terminal = false;
|
|
1215
|
+
for await (const event of this.streamPlayRunEvents(runId, {
|
|
1216
|
+
mode: "cli",
|
|
1217
|
+
signal: options?.signal
|
|
1218
|
+
})) {
|
|
1219
|
+
const status = updatePlayLiveStatusState(state, event);
|
|
1220
|
+
if (!status) {
|
|
1221
|
+
continue;
|
|
1222
|
+
}
|
|
1223
|
+
terminal = TERMINAL_PLAY_STATUSES.has(status.status);
|
|
1224
|
+
if (terminal) {
|
|
1225
|
+
break;
|
|
1226
|
+
}
|
|
1146
1227
|
}
|
|
1147
|
-
if (
|
|
1148
|
-
|
|
1228
|
+
if (terminal && state.latest) {
|
|
1229
|
+
return await this.getRunStatus(state.latest.runId || runId).catch(
|
|
1230
|
+
() => state.latest ?? playRunStatusFromState(state)
|
|
1231
|
+
);
|
|
1149
1232
|
}
|
|
1150
|
-
if (
|
|
1151
|
-
|
|
1233
|
+
if (state.latest) {
|
|
1234
|
+
return state.latest;
|
|
1152
1235
|
}
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1236
|
+
throw new DeeplineError(
|
|
1237
|
+
`Run stream for ${runId} ended before the initial snapshot.`,
|
|
1238
|
+
void 0,
|
|
1239
|
+
"PLAY_RUN_STREAM_EMPTY",
|
|
1240
|
+
{ runId }
|
|
1156
1241
|
);
|
|
1157
|
-
return normalizePlayStatus(response);
|
|
1158
1242
|
}
|
|
1159
1243
|
/**
|
|
1160
1244
|
* Fetch persisted logs for a run using the public runs resource model.
|
|
@@ -1311,11 +1395,11 @@ var DeeplineClient = class {
|
|
|
1311
1395
|
// Plays — high-level orchestration
|
|
1312
1396
|
// ——————————————————————————————————————————————————————————
|
|
1313
1397
|
/**
|
|
1314
|
-
* Run a play end-to-end: submit,
|
|
1398
|
+
* Run a play end-to-end: submit, stream until terminal, return result.
|
|
1315
1399
|
*
|
|
1316
1400
|
* This is the highest-level play execution method. It submits the play,
|
|
1317
|
-
*
|
|
1318
|
-
* and timing. Supports cancellation via `AbortSignal`.
|
|
1401
|
+
* reads the canonical run stream for status updates, and returns a structured
|
|
1402
|
+
* result with logs and timing. Supports cancellation via `AbortSignal`.
|
|
1319
1403
|
*
|
|
1320
1404
|
* @param code - Source string fallback; pass the bundled artifact in `options.artifact`
|
|
1321
1405
|
* @param csvPath - Input CSV path, or `null`
|
|
@@ -1331,7 +1415,6 @@ var DeeplineClient = class {
|
|
|
1331
1415
|
* const logs = status.progress?.logs ?? [];
|
|
1332
1416
|
* console.log(`[${status.status}] ${logs.length} log lines`);
|
|
1333
1417
|
* },
|
|
1334
|
-
* pollIntervalMs: 1000,
|
|
1335
1418
|
* });
|
|
1336
1419
|
*
|
|
1337
1420
|
* if (result.success) {
|
|
@@ -1362,33 +1445,53 @@ var DeeplineClient = class {
|
|
|
1362
1445
|
packagedFiles: options?.packagedFiles,
|
|
1363
1446
|
force: options?.force
|
|
1364
1447
|
});
|
|
1365
|
-
const pollInterval = options?.pollIntervalMs ?? 500;
|
|
1366
1448
|
const start = Date.now();
|
|
1367
|
-
|
|
1449
|
+
const state = {
|
|
1450
|
+
runId: workflowId,
|
|
1451
|
+
status: "running",
|
|
1452
|
+
logs: [],
|
|
1453
|
+
latest: null
|
|
1454
|
+
};
|
|
1455
|
+
if (options?.signal?.aborted) {
|
|
1456
|
+
await this.cancelPlay(workflowId);
|
|
1457
|
+
return {
|
|
1458
|
+
success: false,
|
|
1459
|
+
runId: workflowId,
|
|
1460
|
+
logs: [],
|
|
1461
|
+
durationMs: Date.now() - start,
|
|
1462
|
+
error: "Cancelled by user"
|
|
1463
|
+
};
|
|
1464
|
+
}
|
|
1465
|
+
for await (const event of this.streamPlayRunEvents(workflowId, {
|
|
1466
|
+
mode: "cli",
|
|
1467
|
+
signal: options?.signal
|
|
1468
|
+
})) {
|
|
1368
1469
|
if (options?.signal?.aborted) {
|
|
1369
1470
|
await this.cancelPlay(workflowId);
|
|
1370
1471
|
return {
|
|
1371
1472
|
success: false,
|
|
1372
1473
|
runId: workflowId,
|
|
1373
|
-
logs:
|
|
1474
|
+
logs: state.logs,
|
|
1374
1475
|
durationMs: Date.now() - start,
|
|
1375
1476
|
error: "Cancelled by user"
|
|
1376
1477
|
};
|
|
1377
1478
|
}
|
|
1378
|
-
const status =
|
|
1479
|
+
const status = updatePlayLiveStatusState(state, event);
|
|
1480
|
+
if (!status) {
|
|
1481
|
+
continue;
|
|
1482
|
+
}
|
|
1379
1483
|
options?.onProgress?.(status);
|
|
1380
1484
|
if (TERMINAL_PLAY_STATUSES.has(status.status)) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
runId: status.runId || workflowId,
|
|
1384
|
-
result: status.result,
|
|
1385
|
-
logs: status.progress?.logs ?? [],
|
|
1386
|
-
durationMs: Date.now() - start,
|
|
1387
|
-
error: status.progress?.error ?? (status.status !== "completed" ? status.status : void 0)
|
|
1388
|
-
};
|
|
1485
|
+
const finalStatus = await this.getPlayStatus(status.runId || workflowId).catch(() => status);
|
|
1486
|
+
return playRunResultFromStatus(finalStatus, start, workflowId);
|
|
1389
1487
|
}
|
|
1390
|
-
await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
|
|
1391
1488
|
}
|
|
1489
|
+
throw new DeeplineError(
|
|
1490
|
+
`Run stream for ${workflowId} ended before the run reached a terminal state.`,
|
|
1491
|
+
void 0,
|
|
1492
|
+
"PLAY_RUN_STREAM_ENDED",
|
|
1493
|
+
{ runId: workflowId, workflowId }
|
|
1494
|
+
);
|
|
1392
1495
|
}
|
|
1393
1496
|
// ——————————————————————————————————————————————————————————
|
|
1394
1497
|
// Health
|