deepline 0.1.108 → 0.1.109
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 +689 -202
- package/dist/cli/index.mjs +689 -202
- package/dist/index.d.mts +60 -3
- package/dist/index.d.ts +60 -3
- package/dist/index.js +84 -30
- package/dist/index.mjs +84 -30
- package/dist/repo/apps/play-runner-workers/src/child-play-submit.ts +196 -0
- package/dist/repo/apps/play-runner-workers/src/coordinator-entry.ts +0 -1
- package/dist/repo/apps/play-runner-workers/src/entry.ts +31 -279
- package/dist/repo/apps/play-runner-workers/src/runtime/csv-rows.ts +102 -0
- package/dist/repo/apps/play-runner-workers/src/runtime/dataset-handles.ts +8 -3
- package/dist/repo/sdk/src/http.ts +22 -2
- package/dist/repo/sdk/src/index.ts +4 -0
- package/dist/repo/sdk/src/play.ts +76 -6
- package/dist/repo/sdk/src/release.ts +3 -3
- package/dist/repo/shared_libs/play-data-plane/cell-policy.ts +76 -0
- package/dist/repo/shared_libs/play-data-plane/column-names.ts +17 -0
- package/dist/repo/shared_libs/play-data-plane/sheet-contract.ts +190 -0
- package/dist/repo/shared_libs/play-runtime/coordinator-headers.ts +2 -0
- package/dist/repo/shared_libs/play-runtime/db-session.ts +4 -0
- package/dist/repo/shared_libs/play-runtime/providers.ts +5 -24
- package/dist/repo/shared_libs/play-runtime/run-ledger.ts +70 -31
- package/dist/repo/shared_libs/play-runtime/run-snapshot-stream.ts +49 -0
- package/dist/repo/shared_libs/play-runtime/scheduler-backend.ts +18 -7
- package/dist/repo/shared_libs/plays/static-pipeline.ts +3 -11
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -215,7 +215,7 @@ var SDK_RELEASE = {
|
|
|
215
215
|
// preflight (existence, data rows, quotes, duplicate headers), HTML error
|
|
216
216
|
// scrubbing, and word-boundary watch truncation.
|
|
217
217
|
// 0.1.103 ships the refined SDK CLI command surface.
|
|
218
|
-
// 0.1.104
|
|
218
|
+
// 0.1.104 shipped the retired Postgres scheduler suspension/billing parity and runtime worker hardening.
|
|
219
219
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
220
220
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
221
221
|
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
@@ -223,10 +223,10 @@ var SDK_RELEASE = {
|
|
|
223
223
|
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
224
224
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
225
225
|
// the SDK enrich generator's one-second stale policy.
|
|
226
|
-
version: "0.1.
|
|
226
|
+
version: "0.1.109",
|
|
227
227
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
228
228
|
supportPolicy: {
|
|
229
|
-
latest: "0.1.
|
|
229
|
+
latest: "0.1.109",
|
|
230
230
|
minimumSupported: "0.1.53",
|
|
231
231
|
deprecatedBelow: "0.1.53",
|
|
232
232
|
commandMinimumSupported: [
|
|
@@ -248,6 +248,7 @@ var SDK_API_CONTRACT = SDK_RELEASE.apiContract;
|
|
|
248
248
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
249
249
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
250
250
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
251
|
+
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
251
252
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
252
253
|
|
|
253
254
|
// src/http.ts
|
|
@@ -316,6 +317,10 @@ var HttpClient = class {
|
|
|
316
317
|
if (workerCallbackUrl?.trim()) {
|
|
317
318
|
headers[WORKER_CALLBACK_URL_OVERRIDE_HEADER] = workerCallbackUrl.trim();
|
|
318
319
|
}
|
|
320
|
+
const runtimeSchedulerSchema = typeof process !== "undefined" ? process.env?.DEEPLINE_RUNTIME_SCHEDULER_SCHEMA : void 0;
|
|
321
|
+
if (runtimeSchedulerSchema?.trim()) {
|
|
322
|
+
headers[RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER] = runtimeSchedulerSchema.trim();
|
|
323
|
+
}
|
|
319
324
|
const syntheticRun = typeof process !== "undefined" ? process.env?.DEEPLINE_SYNTHETIC_RUN : void 0;
|
|
320
325
|
if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
|
|
321
326
|
headers[SYNTHETIC_RUN_HEADER] = "1";
|
|
@@ -522,8 +527,19 @@ var HttpClient = class {
|
|
|
522
527
|
headers
|
|
523
528
|
});
|
|
524
529
|
}
|
|
530
|
+
/**
|
|
531
|
+
* Send a PATCH request with a JSON body.
|
|
532
|
+
*
|
|
533
|
+
* @typeParam T - Expected response body type
|
|
534
|
+
* @param path - API path
|
|
535
|
+
* @param body - JSON-serializable request body
|
|
536
|
+
*/
|
|
525
537
|
async patch(path, body, headers) {
|
|
526
|
-
return this.request(path, {
|
|
538
|
+
return this.request(path, {
|
|
539
|
+
method: "PATCH",
|
|
540
|
+
body,
|
|
541
|
+
headers
|
|
542
|
+
});
|
|
527
543
|
}
|
|
528
544
|
/**
|
|
529
545
|
* Send a DELETE request.
|
|
@@ -874,6 +890,35 @@ function normalizePlayRunLiveStatus(value) {
|
|
|
874
890
|
function isTerminalPlayRunLiveStatus(status) {
|
|
875
891
|
return status === "completed" || status === "failed" || status === "cancelled" || status === "terminated" || status === "timed_out";
|
|
876
892
|
}
|
|
893
|
+
function isRecord2(value) {
|
|
894
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
895
|
+
}
|
|
896
|
+
function finiteNumber2(value) {
|
|
897
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
898
|
+
}
|
|
899
|
+
function extractTerminalRunLogTail(result) {
|
|
900
|
+
if (!isRecord2(result) || !isRecord2(result._metadata)) {
|
|
901
|
+
return null;
|
|
902
|
+
}
|
|
903
|
+
const runLogTail = result._metadata.runLogTail;
|
|
904
|
+
if (!isRecord2(runLogTail) || !Array.isArray(runLogTail.tail)) {
|
|
905
|
+
return null;
|
|
906
|
+
}
|
|
907
|
+
const logTail = runLogTail.tail.filter(
|
|
908
|
+
(line) => typeof line === "string" && line.trim().length > 0
|
|
909
|
+
);
|
|
910
|
+
if (logTail.length === 0) {
|
|
911
|
+
return null;
|
|
912
|
+
}
|
|
913
|
+
const totalLogCount = Math.max(
|
|
914
|
+
finiteNumber2(runLogTail.totalLogCount) ?? logTail.length,
|
|
915
|
+
logTail.length
|
|
916
|
+
);
|
|
917
|
+
return {
|
|
918
|
+
logTail: logTail.slice(-LOG_TAIL_LIMIT),
|
|
919
|
+
totalLogCount
|
|
920
|
+
};
|
|
921
|
+
}
|
|
877
922
|
function buildSnapshotFromLedger(snapshot) {
|
|
878
923
|
const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
|
|
879
924
|
nodeId: step.stepId,
|
|
@@ -920,6 +965,14 @@ function buildPlayRunStatusSnapshot(input2) {
|
|
|
920
965
|
updatedAt: input2.run.updatedAt ?? null,
|
|
921
966
|
finishedAt: input2.run.finishedAt ?? null
|
|
922
967
|
});
|
|
968
|
+
const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
|
|
969
|
+
if (terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount) {
|
|
970
|
+
return buildSnapshotFromLedger({
|
|
971
|
+
...ledgerSnapshot,
|
|
972
|
+
logTail: terminalRunLogTail.logTail,
|
|
973
|
+
totalLogCount: terminalRunLogTail.totalLogCount
|
|
974
|
+
});
|
|
975
|
+
}
|
|
923
976
|
return buildSnapshotFromLedger(ledgerSnapshot);
|
|
924
977
|
}
|
|
925
978
|
function makeRunStreamEvent(input2) {
|
|
@@ -1514,7 +1567,7 @@ function chunkRegisterPlayArtifacts(artifacts) {
|
|
|
1514
1567
|
return chunks;
|
|
1515
1568
|
}
|
|
1516
1569
|
var RUN_LOGS_PAGE_LIMIT = 1e3;
|
|
1517
|
-
function
|
|
1570
|
+
function isRecord3(value) {
|
|
1518
1571
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1519
1572
|
}
|
|
1520
1573
|
function isPrebuiltPlayDescription(play) {
|
|
@@ -1616,7 +1669,7 @@ function updatePlayLiveStatusState(state, event) {
|
|
|
1616
1669
|
}
|
|
1617
1670
|
const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
|
|
1618
1671
|
const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
|
|
1619
|
-
const progressPayload =
|
|
1672
|
+
const progressPayload = isRecord3(payload.progress) ? payload.progress : {};
|
|
1620
1673
|
if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
|
|
1621
1674
|
const payloadLogs = readStringArray(payload.logs);
|
|
1622
1675
|
const progressLogs = readStringArray(progressPayload.logs);
|
|
@@ -1729,9 +1782,9 @@ var DeeplineClient = class {
|
|
|
1729
1782
|
return fields.length > 0 ? { fields } : schema;
|
|
1730
1783
|
}
|
|
1731
1784
|
schemaMetadata(schema, key) {
|
|
1732
|
-
if (!
|
|
1785
|
+
if (!isRecord3(schema)) return null;
|
|
1733
1786
|
const value = schema[key];
|
|
1734
|
-
return
|
|
1787
|
+
return isRecord3(value) ? value : null;
|
|
1735
1788
|
}
|
|
1736
1789
|
playRunCommand(play, options) {
|
|
1737
1790
|
const target = play.reference || play.name;
|
|
@@ -1778,7 +1831,7 @@ var DeeplineClient = class {
|
|
|
1778
1831
|
aliases,
|
|
1779
1832
|
inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
|
|
1780
1833
|
outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
|
|
1781
|
-
staticPipeline:
|
|
1834
|
+
staticPipeline: isRecord3(play.staticPipeline) ? play.staticPipeline : isRecord3(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord3(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
|
|
1782
1835
|
...csvInput ? { csvInput } : {},
|
|
1783
1836
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
1784
1837
|
runCommand: runCommand2,
|
|
@@ -5284,14 +5337,14 @@ function sanitizeCsvProjectionInfo(input2) {
|
|
|
5284
5337
|
const rows = input2.rows.map(stripCsvProjectionFields);
|
|
5285
5338
|
return { rows, columns };
|
|
5286
5339
|
}
|
|
5287
|
-
function
|
|
5340
|
+
function isRecord4(value) {
|
|
5288
5341
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
5289
5342
|
}
|
|
5290
5343
|
function isSerializedDataset(value) {
|
|
5291
|
-
return
|
|
5344
|
+
return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && Array.isArray(value.preview);
|
|
5292
5345
|
}
|
|
5293
5346
|
function isPackagedDatasetOutput(value) {
|
|
5294
|
-
return
|
|
5347
|
+
return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
|
|
5295
5348
|
}
|
|
5296
5349
|
function pathParts(path) {
|
|
5297
5350
|
return path.split(".").map((part) => part.trim()).filter(Boolean);
|
|
@@ -5299,7 +5352,7 @@ function pathParts(path) {
|
|
|
5299
5352
|
function valueAtPath(root, path) {
|
|
5300
5353
|
let cursor = root;
|
|
5301
5354
|
for (const part of pathParts(path)) {
|
|
5302
|
-
if (!
|
|
5355
|
+
if (!isRecord4(cursor)) {
|
|
5303
5356
|
return void 0;
|
|
5304
5357
|
}
|
|
5305
5358
|
cursor = cursor[part];
|
|
@@ -5307,17 +5360,17 @@ function valueAtPath(root, path) {
|
|
|
5307
5360
|
return cursor;
|
|
5308
5361
|
}
|
|
5309
5362
|
function totalRowsForDataset(result, datasetPath) {
|
|
5310
|
-
const metadata =
|
|
5363
|
+
const metadata = isRecord4(result._metadata) ? result._metadata : null;
|
|
5311
5364
|
const parentPath = datasetPath.split(".").slice(0, -1).join(".");
|
|
5312
5365
|
const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
|
|
5313
|
-
return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (
|
|
5366
|
+
return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord4(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
|
|
5314
5367
|
}
|
|
5315
5368
|
function rowArray(value) {
|
|
5316
5369
|
if (!Array.isArray(value)) {
|
|
5317
5370
|
return null;
|
|
5318
5371
|
}
|
|
5319
5372
|
const rows = value.filter(
|
|
5320
|
-
(row) =>
|
|
5373
|
+
(row) => isRecord4(row)
|
|
5321
5374
|
);
|
|
5322
5375
|
return rows.length === value.length ? rows : null;
|
|
5323
5376
|
}
|
|
@@ -5341,7 +5394,7 @@ function inferColumns(rows) {
|
|
|
5341
5394
|
return columns;
|
|
5342
5395
|
}
|
|
5343
5396
|
function columnsFromDatasetSummary(summary) {
|
|
5344
|
-
if (!
|
|
5397
|
+
if (!isRecord4(summary) || !isRecord4(summary.columnStats)) {
|
|
5345
5398
|
return [];
|
|
5346
5399
|
}
|
|
5347
5400
|
return Object.keys(summary.columnStats).filter((column) => column);
|
|
@@ -5370,7 +5423,7 @@ function canonicalRowsInfoFromCandidate(input2) {
|
|
|
5370
5423
|
}
|
|
5371
5424
|
if (isPackagedDatasetOutput(candidate.value)) {
|
|
5372
5425
|
const rawRows = rowArray(candidate.value.preview?.rows) ?? [];
|
|
5373
|
-
const totalRows2 = readNumber(candidate.value.
|
|
5426
|
+
const totalRows2 = readNumber(candidate.value.rowCount) ?? readNumber(candidate.value.preview?.totalRows) ?? rawRows.length;
|
|
5374
5427
|
const explicitColumns = Array.isArray(candidate.value.columns) ? candidate.value.columns.filter(
|
|
5375
5428
|
(column) => typeof column === "string"
|
|
5376
5429
|
) : [];
|
|
@@ -5431,7 +5484,7 @@ function collectDatasetCandidates(input2) {
|
|
|
5431
5484
|
});
|
|
5432
5485
|
return;
|
|
5433
5486
|
}
|
|
5434
|
-
if (!
|
|
5487
|
+
if (!isRecord4(input2.value)) {
|
|
5435
5488
|
return;
|
|
5436
5489
|
}
|
|
5437
5490
|
for (const [key, child] of Object.entries(input2.value)) {
|
|
@@ -5448,12 +5501,12 @@ function collectDatasetCandidates(input2) {
|
|
|
5448
5501
|
}
|
|
5449
5502
|
}
|
|
5450
5503
|
function collectCanonicalRowsInfos(statusOrResult) {
|
|
5451
|
-
const root =
|
|
5452
|
-
const result =
|
|
5504
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5505
|
+
const result = isRecord4(root?.result) ? root.result : root;
|
|
5453
5506
|
if (!result) {
|
|
5454
5507
|
return [];
|
|
5455
5508
|
}
|
|
5456
|
-
const metadata =
|
|
5509
|
+
const metadata = isRecord4(result._metadata) ? result._metadata : null;
|
|
5457
5510
|
const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
|
|
5458
5511
|
const candidates = [
|
|
5459
5512
|
{
|
|
@@ -5477,8 +5530,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5477
5530
|
total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
|
|
5478
5531
|
}
|
|
5479
5532
|
];
|
|
5480
|
-
if (
|
|
5481
|
-
const outputMetadata =
|
|
5533
|
+
if (isRecord4(result.output)) {
|
|
5534
|
+
const outputMetadata = isRecord4(result.output._metadata) ? result.output._metadata : null;
|
|
5482
5535
|
const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
|
|
5483
5536
|
candidates.push(
|
|
5484
5537
|
{
|
|
@@ -5505,14 +5558,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5505
5558
|
}
|
|
5506
5559
|
if (Array.isArray(result.steps)) {
|
|
5507
5560
|
result.steps.forEach((step, index) => {
|
|
5508
|
-
if (!
|
|
5561
|
+
if (!isRecord4(step) || !isRecord4(step.output)) {
|
|
5509
5562
|
return;
|
|
5510
5563
|
}
|
|
5511
5564
|
const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
|
|
5512
5565
|
candidates.push({
|
|
5513
5566
|
source,
|
|
5514
5567
|
value: step.output,
|
|
5515
|
-
total: step.output.rowCount ?? (
|
|
5568
|
+
total: step.output.rowCount ?? (isRecord4(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
|
|
5516
5569
|
});
|
|
5517
5570
|
});
|
|
5518
5571
|
}
|
|
@@ -5539,15 +5592,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5539
5592
|
return infos;
|
|
5540
5593
|
}
|
|
5541
5594
|
function collectPackagedStepDatasetCandidates(statusOrResult) {
|
|
5542
|
-
const root =
|
|
5595
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5543
5596
|
if (!root) {
|
|
5544
5597
|
return [];
|
|
5545
5598
|
}
|
|
5546
|
-
const pkg =
|
|
5599
|
+
const pkg = isRecord4(root.package) ? root.package : root;
|
|
5547
5600
|
const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
|
|
5548
5601
|
const candidates = [];
|
|
5549
5602
|
for (const step of steps) {
|
|
5550
|
-
if (!
|
|
5603
|
+
if (!isRecord4(step) || !isRecord4(step.output)) {
|
|
5551
5604
|
continue;
|
|
5552
5605
|
}
|
|
5553
5606
|
const output2 = step.output;
|
|
@@ -5561,14 +5614,14 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
|
|
|
5561
5614
|
candidates.push({
|
|
5562
5615
|
source,
|
|
5563
5616
|
value: output2,
|
|
5564
|
-
total: output2.rowCount ?? (
|
|
5617
|
+
total: output2.rowCount ?? (isRecord4(output2.preview) ? output2.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
|
|
5565
5618
|
});
|
|
5566
5619
|
}
|
|
5567
5620
|
return candidates;
|
|
5568
5621
|
}
|
|
5569
5622
|
function collectSerializedDatasetRowsInfos(statusOrResult) {
|
|
5570
|
-
const root =
|
|
5571
|
-
const result =
|
|
5623
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5624
|
+
const result = isRecord4(root?.result) ? root.result : root;
|
|
5572
5625
|
const candidates = [];
|
|
5573
5626
|
if (result) {
|
|
5574
5627
|
collectDatasetCandidates({
|
|
@@ -5604,17 +5657,17 @@ function percentText(numerator, denominator) {
|
|
|
5604
5657
|
return datasetSummaryPercentText(numerator, denominator);
|
|
5605
5658
|
}
|
|
5606
5659
|
function isDatasetExecutionStatsInput(value) {
|
|
5607
|
-
return
|
|
5660
|
+
return isRecord4(value) && isRecord4(value.columnStats) && Object.values(value.columnStats).every(isRecord4);
|
|
5608
5661
|
}
|
|
5609
5662
|
function extractDatasetExecutionStats(statusOrResult) {
|
|
5610
|
-
if (!
|
|
5663
|
+
if (!isRecord4(statusOrResult)) {
|
|
5611
5664
|
return null;
|
|
5612
5665
|
}
|
|
5613
5666
|
const direct = statusOrResult.dataset_execution_stats;
|
|
5614
5667
|
if (isDatasetExecutionStatsInput(direct)) {
|
|
5615
5668
|
return direct;
|
|
5616
5669
|
}
|
|
5617
|
-
const nested =
|
|
5670
|
+
const nested = isRecord4(statusOrResult.result) ? statusOrResult.result.dataset_execution_stats : null;
|
|
5618
5671
|
return isDatasetExecutionStatsInput(nested) ? nested : null;
|
|
5619
5672
|
}
|
|
5620
5673
|
function countPercentText(count, denominator) {
|
|
@@ -5655,13 +5708,13 @@ function summarizeSampleValue(value, depth = 0) {
|
|
|
5655
5708
|
if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
|
|
5656
5709
|
if (depth >= 3) {
|
|
5657
5710
|
if (Array.isArray(parsed)) return [];
|
|
5658
|
-
if (
|
|
5711
|
+
if (isRecord4(parsed)) return {};
|
|
5659
5712
|
return compactScalar(parsed);
|
|
5660
5713
|
}
|
|
5661
5714
|
if (Array.isArray(parsed)) {
|
|
5662
5715
|
return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
|
|
5663
5716
|
}
|
|
5664
|
-
if (
|
|
5717
|
+
if (isRecord4(parsed)) {
|
|
5665
5718
|
const out = {};
|
|
5666
5719
|
for (const [key, nested] of Object.entries(parsed)) {
|
|
5667
5720
|
if (["__dl", "meta", "metadata"].includes(key)) {
|
|
@@ -5692,7 +5745,7 @@ function compactCell(value) {
|
|
|
5692
5745
|
}
|
|
5693
5746
|
return `[${parsed.length} items]`;
|
|
5694
5747
|
}
|
|
5695
|
-
if (
|
|
5748
|
+
if (isRecord4(parsed)) {
|
|
5696
5749
|
for (const key of ["matched_result", "output"]) {
|
|
5697
5750
|
if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
|
|
5698
5751
|
return compactCell(parsed[key]);
|
|
@@ -7483,16 +7536,19 @@ var PLAY_DEDUP_BACKENDS = {
|
|
|
7483
7536
|
var PLAY_SCHEDULER_BACKENDS = {
|
|
7484
7537
|
temporal: "temporal",
|
|
7485
7538
|
cfWorkflows: "cf-workflows",
|
|
7539
|
+
/**
|
|
7540
|
+
* Private legacy id retained only so old persisted rows can be interpreted.
|
|
7541
|
+
* It is not a selectable scheduler backend after the Hatchet hard cutover.
|
|
7542
|
+
*/
|
|
7486
7543
|
postgres: "postgres",
|
|
7544
|
+
hatchet: "hatchet",
|
|
7487
7545
|
inProcess: "in-process"
|
|
7488
7546
|
};
|
|
7489
7547
|
|
|
7490
7548
|
// ../shared_libs/play-runtime/providers.ts
|
|
7491
7549
|
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
7492
7550
|
workersEdge: "workers_edge",
|
|
7493
|
-
|
|
7494
|
-
postgresFastSandbox: "postgres_fast_sandbox",
|
|
7495
|
-
postgresFastWorkers: "postgres_fast_workers",
|
|
7551
|
+
hatchet: "hatchet",
|
|
7496
7552
|
local: "local"
|
|
7497
7553
|
};
|
|
7498
7554
|
var PLAY_RUNTIME_PROVIDERS = {
|
|
@@ -7504,29 +7560,13 @@ var PLAY_RUNTIME_PROVIDERS = {
|
|
|
7504
7560
|
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
7505
7561
|
label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
|
|
7506
7562
|
},
|
|
7507
|
-
|
|
7508
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.
|
|
7509
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.
|
|
7510
|
-
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
7511
|
-
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7512
|
-
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
7513
|
-
label: "BETA: Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
7514
|
-
},
|
|
7515
|
-
postgres_fast_sandbox: {
|
|
7516
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastSandbox,
|
|
7517
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
7563
|
+
hatchet: {
|
|
7564
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
|
|
7565
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
|
|
7518
7566
|
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
7519
7567
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7520
7568
|
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
7521
|
-
label: "
|
|
7522
|
-
},
|
|
7523
|
-
postgres_fast_workers: {
|
|
7524
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastWorkers,
|
|
7525
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
7526
|
-
runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
|
|
7527
|
-
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7528
|
-
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
7529
|
-
label: "Experimental Postgres Scheduler + Queue/DO-woken Workers + DO dedup"
|
|
7569
|
+
label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
|
|
7530
7570
|
},
|
|
7531
7571
|
local: {
|
|
7532
7572
|
id: PLAY_RUNTIME_PROVIDER_IDS.local,
|
|
@@ -8045,17 +8085,17 @@ function parsePositiveInteger2(value, flagName) {
|
|
|
8045
8085
|
}
|
|
8046
8086
|
return parsed;
|
|
8047
8087
|
}
|
|
8048
|
-
function
|
|
8088
|
+
function isRecord5(value) {
|
|
8049
8089
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
8050
8090
|
}
|
|
8051
8091
|
function stringValue(value) {
|
|
8052
8092
|
return typeof value === "string" ? value.trim() : "";
|
|
8053
8093
|
}
|
|
8054
8094
|
function extractionEntries(value) {
|
|
8055
|
-
if (Array.isArray(value)) return value.filter(
|
|
8056
|
-
if (!
|
|
8095
|
+
if (Array.isArray(value)) return value.filter(isRecord5);
|
|
8096
|
+
if (!isRecord5(value)) return [];
|
|
8057
8097
|
return Object.entries(value).map(
|
|
8058
|
-
([name, entry]) =>
|
|
8098
|
+
([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
|
|
8059
8099
|
);
|
|
8060
8100
|
}
|
|
8061
8101
|
var PlayBootstrapError = class extends Error {
|
|
@@ -8475,7 +8515,7 @@ function readCsvSampleRows(sample) {
|
|
|
8475
8515
|
relax_column_count: true,
|
|
8476
8516
|
trim: true
|
|
8477
8517
|
});
|
|
8478
|
-
return Array.isArray(parsedRows) ? parsedRows.filter(
|
|
8518
|
+
return Array.isArray(parsedRows) ? parsedRows.filter(isRecord5) : [];
|
|
8479
8519
|
}
|
|
8480
8520
|
function readSourceCsvColumnSpecs(csvPath) {
|
|
8481
8521
|
const sample = readCsvSample(csvPath);
|
|
@@ -8508,16 +8548,16 @@ function packagedCsvPathForPlay(csvPath) {
|
|
|
8508
8548
|
return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
|
|
8509
8549
|
}
|
|
8510
8550
|
function getterNamesFromTool(tool, kind) {
|
|
8511
|
-
const usageGuidance =
|
|
8512
|
-
const resultGuidance =
|
|
8551
|
+
const usageGuidance = isRecord5(tool?.usageGuidance) ? tool.usageGuidance : {};
|
|
8552
|
+
const resultGuidance = isRecord5(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord5(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
|
|
8513
8553
|
const key = kind === "list" ? "extractedLists" : "extractedValues";
|
|
8514
8554
|
const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
|
|
8515
8555
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
8516
8556
|
}
|
|
8517
8557
|
function targetGettersFromTool(tool) {
|
|
8518
|
-
const record =
|
|
8558
|
+
const record = isRecord5(tool) ? tool : {};
|
|
8519
8559
|
const raw = record.targetGetters ?? record.target_getters;
|
|
8520
|
-
if (!
|
|
8560
|
+
if (!isRecord5(raw)) return {};
|
|
8521
8561
|
const entries = [];
|
|
8522
8562
|
for (const [target, value] of Object.entries(raw)) {
|
|
8523
8563
|
const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
|
|
@@ -8538,10 +8578,10 @@ function listRowCandidateKeysFromTool(tool) {
|
|
|
8538
8578
|
return [...keys].sort();
|
|
8539
8579
|
}
|
|
8540
8580
|
function inputPropertyNames(schema) {
|
|
8541
|
-
if (!
|
|
8542
|
-
if (
|
|
8581
|
+
if (!isRecord5(schema)) return [];
|
|
8582
|
+
if (isRecord5(schema.properties)) return Object.keys(schema.properties);
|
|
8543
8583
|
if (Array.isArray(schema.fields)) {
|
|
8544
|
-
return schema.fields.filter(
|
|
8584
|
+
return schema.fields.filter(isRecord5).map((field) => stringValue(field.name)).filter(Boolean);
|
|
8545
8585
|
}
|
|
8546
8586
|
return [];
|
|
8547
8587
|
}
|
|
@@ -8555,7 +8595,7 @@ function schemaFieldDetails(schema) {
|
|
|
8555
8595
|
return { required, optional };
|
|
8556
8596
|
}
|
|
8557
8597
|
function jsonSchemaTypeExpression(schema) {
|
|
8558
|
-
if (!
|
|
8598
|
+
if (!isRecord5(schema)) return "unknown";
|
|
8559
8599
|
const type = schema.type;
|
|
8560
8600
|
if (Array.isArray(type)) {
|
|
8561
8601
|
return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
|
|
@@ -8585,7 +8625,7 @@ function jsonSchemaTypeExpression(schema) {
|
|
|
8585
8625
|
}
|
|
8586
8626
|
}
|
|
8587
8627
|
function objectPropertySchema(schema, property) {
|
|
8588
|
-
return
|
|
8628
|
+
return isRecord5(schema) && isRecord5(schema.properties) ? schema.properties[property] : null;
|
|
8589
8629
|
}
|
|
8590
8630
|
function playOutputHasField(schema, field) {
|
|
8591
8631
|
return objectPropertySchema(schema, field) != null;
|
|
@@ -8761,14 +8801,14 @@ ${indent2.slice(2)}}`;
|
|
|
8761
8801
|
}
|
|
8762
8802
|
function requiredPlayInputFields(play) {
|
|
8763
8803
|
const schema = play?.inputSchema;
|
|
8764
|
-
if (!
|
|
8804
|
+
if (!isRecord5(schema)) return [];
|
|
8765
8805
|
if (Array.isArray(schema.required)) {
|
|
8766
8806
|
return schema.required.filter(
|
|
8767
8807
|
(value) => typeof value === "string"
|
|
8768
8808
|
);
|
|
8769
8809
|
}
|
|
8770
8810
|
if (Array.isArray(schema.fields)) {
|
|
8771
|
-
return schema.fields.filter(
|
|
8811
|
+
return schema.fields.filter(isRecord5).filter(
|
|
8772
8812
|
(field) => field.required === true && typeof field.name === "string"
|
|
8773
8813
|
).map((field) => String(field.name));
|
|
8774
8814
|
}
|
|
@@ -8949,7 +8989,7 @@ function validateBootstrapRoutes(input2) {
|
|
|
8949
8989
|
}
|
|
8950
8990
|
}
|
|
8951
8991
|
function staticPipelineSubsteps(pipeline) {
|
|
8952
|
-
if (!
|
|
8992
|
+
if (!isRecord5(pipeline)) return [];
|
|
8953
8993
|
return [
|
|
8954
8994
|
...extractionEntries(pipeline.stages),
|
|
8955
8995
|
...extractionEntries(pipeline.substeps)
|
|
@@ -8957,7 +8997,7 @@ function staticPipelineSubsteps(pipeline) {
|
|
|
8957
8997
|
}
|
|
8958
8998
|
function playUsesMapBackedRuntime(play) {
|
|
8959
8999
|
const pipeline = play?.staticPipeline;
|
|
8960
|
-
if (!
|
|
9000
|
+
if (!isRecord5(pipeline)) return false;
|
|
8961
9001
|
if (stringValue(pipeline.tableNamespace)) return true;
|
|
8962
9002
|
return staticPipelineSubsteps(pipeline).some((substep) => {
|
|
8963
9003
|
if (stringValue(substep.type) === "map") return true;
|
|
@@ -8966,7 +9006,7 @@ function playUsesMapBackedRuntime(play) {
|
|
|
8966
9006
|
aliases: [],
|
|
8967
9007
|
runCommand: "",
|
|
8968
9008
|
examples: [],
|
|
8969
|
-
staticPipeline:
|
|
9009
|
+
staticPipeline: isRecord5(substep.pipeline) ? substep.pipeline : null
|
|
8970
9010
|
});
|
|
8971
9011
|
});
|
|
8972
9012
|
}
|
|
@@ -10528,10 +10568,12 @@ function playStatusValue(value) {
|
|
|
10528
10568
|
return value === "queued" || value === "running" || value === "waiting" || value === "completed" || value === "failed" || value === "cancelled" ? value : null;
|
|
10529
10569
|
}
|
|
10530
10570
|
function getRunRecordFromPackage(value) {
|
|
10531
|
-
|
|
10571
|
+
const nestedPackage = value.package;
|
|
10572
|
+
const playRunPackage = isPlayRunPackageValue(value) ? value : isPlayRunPackageValue(nestedPackage) ? nestedPackage : null;
|
|
10573
|
+
if (!playRunPackage) {
|
|
10532
10574
|
return null;
|
|
10533
10575
|
}
|
|
10534
|
-
const run =
|
|
10576
|
+
const run = playRunPackage.run;
|
|
10535
10577
|
return run && typeof run === "object" && !Array.isArray(run) ? run : null;
|
|
10536
10578
|
}
|
|
10537
10579
|
function getRunIdFromLiveEvent(event) {
|
|
@@ -10561,10 +10603,12 @@ function getFinalStatusFromLiveEvent(event) {
|
|
|
10561
10603
|
return null;
|
|
10562
10604
|
}
|
|
10563
10605
|
const runId = typeof payload.runId === "string" ? payload.runId : typeof packageRun?.id === "string" ? packageRun.id : "";
|
|
10606
|
+
const error = typeof payload.error === "string" ? payload.error : typeof packageRun?.error === "string" ? packageRun.error : void 0;
|
|
10564
10607
|
return {
|
|
10565
10608
|
...payload,
|
|
10566
10609
|
runId,
|
|
10567
|
-
status
|
|
10610
|
+
status,
|
|
10611
|
+
...error ? { error } : {}
|
|
10568
10612
|
};
|
|
10569
10613
|
}
|
|
10570
10614
|
function getLogLinesFromLiveEvent(event) {
|
|
@@ -11883,7 +11927,16 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
11883
11927
|
function compactPlayStatus(status) {
|
|
11884
11928
|
const packaged = getPlayRunPackage(status);
|
|
11885
11929
|
if (packaged) {
|
|
11886
|
-
|
|
11930
|
+
const error2 = selectRunErrorForDisplay(status) ?? (typeof status.error === "string" ? String(status.error) : null);
|
|
11931
|
+
if (!error2) {
|
|
11932
|
+
return packaged;
|
|
11933
|
+
}
|
|
11934
|
+
const run = packaged.run && typeof packaged.run === "object" ? packaged.run : null;
|
|
11935
|
+
return {
|
|
11936
|
+
...packaged,
|
|
11937
|
+
error: error2,
|
|
11938
|
+
...run ? { run: { ...run, error: error2 } } : {}
|
|
11939
|
+
};
|
|
11887
11940
|
}
|
|
11888
11941
|
const rowsInfo = extractCanonicalRowsInfo(status);
|
|
11889
11942
|
const result = status && typeof status === "object" ? status.result : null;
|
|
@@ -12223,10 +12276,17 @@ function writePlayResult(status, jsonOutput, options) {
|
|
|
12223
12276
|
` }
|
|
12224
12277
|
);
|
|
12225
12278
|
}
|
|
12226
|
-
function
|
|
12227
|
-
if (!pkg) return
|
|
12228
|
-
const steps = pkg.steps;
|
|
12229
|
-
|
|
12279
|
+
function playRunPackageTextLedgerIncomplete(pkg) {
|
|
12280
|
+
if (!pkg) return true;
|
|
12281
|
+
const steps = readRecordArray(pkg.steps);
|
|
12282
|
+
if (steps.length === 0) return true;
|
|
12283
|
+
for (const step of steps) {
|
|
12284
|
+
if (step.kind !== "dataset" || step.status !== "completed") continue;
|
|
12285
|
+
const output2 = readRecord(step.output);
|
|
12286
|
+
if (!output2 || typeof output2.rowCount !== "number") return true;
|
|
12287
|
+
if (!readRecord(output2.summary)) return true;
|
|
12288
|
+
}
|
|
12289
|
+
return false;
|
|
12230
12290
|
}
|
|
12231
12291
|
async function resolvePlayRunOutputStatus(input2) {
|
|
12232
12292
|
const runId = input2.status.runId;
|
|
@@ -12235,7 +12295,7 @@ async function resolvePlayRunOutputStatus(input2) {
|
|
|
12235
12295
|
}
|
|
12236
12296
|
const streamedPackage = getPlayRunPackage(input2.status);
|
|
12237
12297
|
const refreshForFullJson = input2.fullJson && streamedPackage !== null;
|
|
12238
|
-
const streamedTextPackageIncomplete = !input2.jsonOutput && input2.status.status === "completed" &&
|
|
12298
|
+
const streamedTextPackageIncomplete = !input2.jsonOutput && input2.status.status === "completed" && playRunPackageTextLedgerIncomplete(streamedPackage);
|
|
12239
12299
|
if (!refreshForFullJson && !streamedTextPackageIncomplete) {
|
|
12240
12300
|
return input2.status;
|
|
12241
12301
|
}
|
|
@@ -12243,7 +12303,7 @@ async function resolvePlayRunOutputStatus(input2) {
|
|
|
12243
12303
|
billing: false,
|
|
12244
12304
|
full: input2.fullJson
|
|
12245
12305
|
});
|
|
12246
|
-
for (let attempt = 0; attempt < 3 && streamedTextPackageIncomplete && refreshedStatus.status === "completed" &&
|
|
12306
|
+
for (let attempt = 0; attempt < 3 && streamedTextPackageIncomplete && refreshedStatus.status === "completed" && playRunPackageTextLedgerIncomplete(getPlayRunPackage(refreshedStatus)); attempt += 1) {
|
|
12247
12307
|
await sleep5(250);
|
|
12248
12308
|
refreshedStatus = await input2.client.getPlayStatus(runId, {
|
|
12249
12309
|
billing: false,
|
|
@@ -12552,7 +12612,7 @@ function extractPlayValidationErrors(value) {
|
|
|
12552
12612
|
if (value instanceof DeeplineError) {
|
|
12553
12613
|
return extractPlayValidationErrors(value.details);
|
|
12554
12614
|
}
|
|
12555
|
-
if (!
|
|
12615
|
+
if (!isRecord6(value)) {
|
|
12556
12616
|
return [];
|
|
12557
12617
|
}
|
|
12558
12618
|
const directErrors = stringArrayField(value, "errors");
|
|
@@ -12765,7 +12825,7 @@ function writeStartedPlayRun(input2) {
|
|
|
12765
12825
|
);
|
|
12766
12826
|
}
|
|
12767
12827
|
function parsePlayRunOptions(args) {
|
|
12768
|
-
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n --profile defaults to workers_edge;
|
|
12828
|
+
const usage = "Usage: deepline plays run <play-name> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run <play-file.ts> [--input '{...}'] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --file <play-file.ts> [--input '{...}'] [--profile <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--full] [--<input> value]\n deepline plays run --name <name> [--input '{...}'] [--profile <id>] [--live|--latest|--revision-id <id>] [--no-wait] [--tail-timeout-ms 30000] [--force] [--no-open] [--json] [--full] [--<input> value]\n --profile defaults to workers_edge; hatchet is the durable Daytona-backed preview runtime.\n Unknown --<input> value flags, such as --limit 5, are passed into play input.\nRun `deepline plays run --help` for idempotency, tool call id, and ctx.dataset guidance.";
|
|
12769
12829
|
let filePath = null;
|
|
12770
12830
|
let playName = null;
|
|
12771
12831
|
let input2 = null;
|
|
@@ -12910,7 +12970,7 @@ function shouldUseLocalOnlyPlayCheck() {
|
|
|
12910
12970
|
const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
|
|
12911
12971
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
12912
12972
|
}
|
|
12913
|
-
function
|
|
12973
|
+
function isRecord6(value) {
|
|
12914
12974
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12915
12975
|
}
|
|
12916
12976
|
function stringValue2(value) {
|
|
@@ -12920,14 +12980,14 @@ function asArray(value) {
|
|
|
12920
12980
|
return Array.isArray(value) ? value : [];
|
|
12921
12981
|
}
|
|
12922
12982
|
function extractionEntries2(value) {
|
|
12923
|
-
if (Array.isArray(value)) return value.filter(
|
|
12924
|
-
if (!
|
|
12983
|
+
if (Array.isArray(value)) return value.filter(isRecord6);
|
|
12984
|
+
if (!isRecord6(value)) return [];
|
|
12925
12985
|
return Object.entries(value).map(
|
|
12926
|
-
([name, entry]) =>
|
|
12986
|
+
([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
|
|
12927
12987
|
);
|
|
12928
12988
|
}
|
|
12929
12989
|
function firstRawPath(entry) {
|
|
12930
|
-
const details =
|
|
12990
|
+
const details = isRecord6(entry.details) ? entry.details : {};
|
|
12931
12991
|
const paths = [
|
|
12932
12992
|
...asArray(details.rawToolOutputPaths),
|
|
12933
12993
|
...asArray(details.raw_tool_output_paths),
|
|
@@ -12945,12 +13005,12 @@ function checkHintRawPath(value) {
|
|
|
12945
13005
|
function collectStaticPipelineToolIds(staticPipeline) {
|
|
12946
13006
|
const seen = /* @__PURE__ */ new Set();
|
|
12947
13007
|
const visitPipeline = (pipeline) => {
|
|
12948
|
-
if (!
|
|
13008
|
+
if (!isRecord6(pipeline)) return;
|
|
12949
13009
|
for (const step of [
|
|
12950
13010
|
...asArray(pipeline.stages),
|
|
12951
13011
|
...asArray(pipeline.substeps)
|
|
12952
13012
|
]) {
|
|
12953
|
-
if (!
|
|
13013
|
+
if (!isRecord6(step)) continue;
|
|
12954
13014
|
if (step.type === "tool") {
|
|
12955
13015
|
const toolId = stringValue2(step.toolId) || stringValue2(step.tool);
|
|
12956
13016
|
if (toolId) seen.add(toolId);
|
|
@@ -12964,9 +13024,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
|
|
|
12964
13024
|
return [...seen].sort();
|
|
12965
13025
|
}
|
|
12966
13026
|
function toolGetterHintFromMetadata(toolId, tool) {
|
|
12967
|
-
const usageGuidance =
|
|
12968
|
-
const resultGuidance =
|
|
12969
|
-
const toolResponse =
|
|
13027
|
+
const usageGuidance = isRecord6(tool.usageGuidance) ? tool.usageGuidance : {};
|
|
13028
|
+
const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
|
|
13029
|
+
const toolResponse = isRecord6(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord6(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
|
|
12970
13030
|
const lists = extractionEntries2(
|
|
12971
13031
|
resultGuidance.extractedLists ?? resultGuidance.extracted_lists
|
|
12972
13032
|
).map((entry) => ({
|
|
@@ -14291,6 +14351,40 @@ async function handlePlayDescribe(args) {
|
|
|
14291
14351
|
);
|
|
14292
14352
|
return 2;
|
|
14293
14353
|
}
|
|
14354
|
+
if (isFileTarget(playName) || looksLikeFilePath(playName)) {
|
|
14355
|
+
const message = "Local play files can be checked and run, but describe only supports saved/prebuilt play references.";
|
|
14356
|
+
const definedName = isFileTarget(playName) ? (() => {
|
|
14357
|
+
try {
|
|
14358
|
+
return extractPlayName(
|
|
14359
|
+
readFileSync6(resolve10(playName), "utf-8"),
|
|
14360
|
+
playName
|
|
14361
|
+
);
|
|
14362
|
+
} catch {
|
|
14363
|
+
return null;
|
|
14364
|
+
}
|
|
14365
|
+
})() : null;
|
|
14366
|
+
const next = [
|
|
14367
|
+
`deepline plays check ${playName}`,
|
|
14368
|
+
...definedName ? [`deepline plays describe <workspace>/${definedName}`] : []
|
|
14369
|
+
];
|
|
14370
|
+
if (argsWantJson(args)) {
|
|
14371
|
+
process.stdout.write(
|
|
14372
|
+
`${JSON.stringify({
|
|
14373
|
+
ok: false,
|
|
14374
|
+
error: { message },
|
|
14375
|
+
next
|
|
14376
|
+
})}
|
|
14377
|
+
`
|
|
14378
|
+
);
|
|
14379
|
+
} else {
|
|
14380
|
+
console.error(message);
|
|
14381
|
+
console.error(`Try: ${next[0]}`);
|
|
14382
|
+
if (next[1]) {
|
|
14383
|
+
console.error(`Or after publishing/running: ${next[1]}`);
|
|
14384
|
+
}
|
|
14385
|
+
}
|
|
14386
|
+
return 2;
|
|
14387
|
+
}
|
|
14294
14388
|
const client2 = new DeeplineClient();
|
|
14295
14389
|
await assertCanonicalNamedPlayReference(client2, playName);
|
|
14296
14390
|
const play = await client2.describePlay(
|
|
@@ -15372,6 +15466,18 @@ function getterFromLegacyExtractJs(extractJs, fallbackAlias) {
|
|
|
15372
15466
|
return null;
|
|
15373
15467
|
}
|
|
15374
15468
|
|
|
15469
|
+
// src/cli/enrich-compat-adapter.ts
|
|
15470
|
+
var ENRICH_COMPAT_DEFAULT_PLAY_NAME = "deepline-enrich-v1-compat";
|
|
15471
|
+
var ENRICH_COMPAT_DEFAULT_MAP_NAME = "deepline_enrich_rows";
|
|
15472
|
+
var ENRICH_COMPAT_METADATA_CELL_POLICY_SOURCE = "{ recompute: true }";
|
|
15473
|
+
function buildEnrichCompatibilityPlan(options = {}) {
|
|
15474
|
+
return {
|
|
15475
|
+
playName: options.playName?.trim() || ENRICH_COMPAT_DEFAULT_PLAY_NAME,
|
|
15476
|
+
mapName: options.mapName?.trim() || ENRICH_COMPAT_DEFAULT_MAP_NAME,
|
|
15477
|
+
metadataCellPolicySource: ENRICH_COMPAT_METADATA_CELL_POLICY_SOURCE
|
|
15478
|
+
};
|
|
15479
|
+
}
|
|
15480
|
+
|
|
15375
15481
|
// src/cli/user-code-safety.ts
|
|
15376
15482
|
var FORBIDDEN = [
|
|
15377
15483
|
// Non-deterministic — breaks replay.
|
|
@@ -15543,12 +15649,16 @@ function renderPlayStep(command, options) {
|
|
|
15543
15649
|
const runIfJs = command.run_if_js ? `(row) => { const input = row; const context = row;
|
|
15544
15650
|
${indent(renderJavascriptBody(command.run_if_js), 6)}
|
|
15545
15651
|
}` : "null";
|
|
15546
|
-
const runIfLines = command.run_if_js ? [
|
|
15652
|
+
const runIfLines = command.run_if_js ? [
|
|
15653
|
+
` const __dlRunIf = ${runIfJs};`,
|
|
15654
|
+
` if (!__dlRunIf(templateRow)) return null;`
|
|
15655
|
+
] : [];
|
|
15547
15656
|
return [
|
|
15548
15657
|
`async (row, stepCtx) => {`,
|
|
15549
15658
|
...options.precheck ? [` if (${options.precheck}) return null;`] : [],
|
|
15659
|
+
` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
|
|
15550
15660
|
...runIfLines,
|
|
15551
|
-
` const payload = __dlTemplate(${payload},
|
|
15661
|
+
` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
|
|
15552
15662
|
` const result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
|
|
15553
15663
|
` description: ${stringLiteral(command.description ?? command.alias)}`,
|
|
15554
15664
|
` });`,
|
|
@@ -15649,7 +15759,7 @@ function collectGeneratedAliases(commands) {
|
|
|
15649
15759
|
}
|
|
15650
15760
|
return aliases;
|
|
15651
15761
|
}
|
|
15652
|
-
function renderMetadataColumnStep(config) {
|
|
15762
|
+
function renderMetadataColumnStep(config, policySource) {
|
|
15653
15763
|
const columns = collectMetadataColumns(config.commands);
|
|
15654
15764
|
if (Object.keys(columns).length === 0) {
|
|
15655
15765
|
return "";
|
|
@@ -15657,7 +15767,7 @@ function renderMetadataColumnStep(config) {
|
|
|
15657
15767
|
return [
|
|
15658
15768
|
` .withColumn('_metadata',`,
|
|
15659
15769
|
` (row) => __dlMergeMetadata(__dlMetadataFromRow(row), ${stableJson({ columns })}),`,
|
|
15660
|
-
` {
|
|
15770
|
+
` ${policySource},`,
|
|
15661
15771
|
` )`
|
|
15662
15772
|
].join("\n");
|
|
15663
15773
|
}
|
|
@@ -15711,8 +15821,8 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
|
|
|
15711
15821
|
];
|
|
15712
15822
|
}
|
|
15713
15823
|
function compileEnrichConfigToPlaySource(config, options = {}) {
|
|
15714
|
-
const
|
|
15715
|
-
const
|
|
15824
|
+
const compatibility = buildEnrichCompatibilityPlan(options);
|
|
15825
|
+
const { playName, mapName } = compatibility;
|
|
15716
15826
|
const inlineRunJavascript = options.inlineRunJavascript ?? false;
|
|
15717
15827
|
const idiomaticGetters = options.idiomaticGetters ?? false;
|
|
15718
15828
|
const forceAliases = new Set(
|
|
@@ -15748,15 +15858,25 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
|
|
|
15748
15858
|
);
|
|
15749
15859
|
});
|
|
15750
15860
|
const columnStepSource = columnSteps.length > 0 ? columnSteps.join("\n") : ` .withColumn('noop', () => null)`;
|
|
15751
|
-
const metadataColumnSource = renderMetadataColumnStep(
|
|
15861
|
+
const metadataColumnSource = renderMetadataColumnStep(
|
|
15862
|
+
config,
|
|
15863
|
+
compatibility.metadataCellPolicySource
|
|
15864
|
+
);
|
|
15752
15865
|
const generatedAliases = collectGeneratedAliases(config.commands);
|
|
15753
15866
|
const body = [
|
|
15754
15867
|
`export default definePlay(${stringLiteral(playName)}, async (ctx, input: EnrichInput) => {`,
|
|
15755
15868
|
` const sourceRows = await ctx.csv<Record<string, unknown>>(input.file);`,
|
|
15756
15869
|
` const rowStart = __dlNonNegativeInteger(input.rowStart, 0);`,
|
|
15757
15870
|
` const rowEndExclusive = Number.isFinite(input.rowEnd) ? Math.max(rowStart, __dlWholeNumber(input.rowEnd, rowStart) + 1) : undefined;`,
|
|
15758
|
-
` const
|
|
15759
|
-
`
|
|
15871
|
+
` const rows: Array<Record<string, unknown>> = [];`,
|
|
15872
|
+
` let sourceRowIndex = 0;`,
|
|
15873
|
+
` for await (const row of sourceRows) {`,
|
|
15874
|
+
` if (rowEndExclusive !== undefined && sourceRowIndex >= rowEndExclusive) break;`,
|
|
15875
|
+
` if (sourceRowIndex >= rowStart) {`,
|
|
15876
|
+
` rows.push(__dlPrepareEnrichRow(row, ${stableJson(generatedAliases)}));`,
|
|
15877
|
+
` }`,
|
|
15878
|
+
` sourceRowIndex += 1;`,
|
|
15879
|
+
` }`,
|
|
15760
15880
|
` const enriched = await ctx`,
|
|
15761
15881
|
` .dataset(${stringLiteral(mapName)}, rows)`,
|
|
15762
15882
|
columnStepSource,
|
|
@@ -15887,17 +16007,55 @@ function helperSource() {
|
|
|
15887
16007
|
` return parts;`,
|
|
15888
16008
|
`}`,
|
|
15889
16009
|
``,
|
|
16010
|
+
`function __dlNormalizeHeader(value: string): string {`,
|
|
16011
|
+
` return value.trim().replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');`,
|
|
16012
|
+
`}`,
|
|
16013
|
+
``,
|
|
16014
|
+
`function __dlOwnStringKeys(record: Record<string, unknown>): string[] {`,
|
|
16015
|
+
` return Object.keys(record);`,
|
|
16016
|
+
`}`,
|
|
16017
|
+
``,
|
|
16018
|
+
`function __dlReadOwnField(record: Record<string, unknown>, key: string): unknown {`,
|
|
16019
|
+
` return record[key];`,
|
|
16020
|
+
`}`,
|
|
16021
|
+
``,
|
|
16022
|
+
`function __dlGetNormalizedKey(record: Record<string, unknown>, part: string): string | null {`,
|
|
16023
|
+
` const normalized = __dlNormalizeHeader(part);`,
|
|
16024
|
+
` for (const key of __dlOwnStringKeys(record)) {`,
|
|
16025
|
+
` if (__dlNormalizeHeader(key) === normalized) return key;`,
|
|
16026
|
+
` }`,
|
|
16027
|
+
` return null;`,
|
|
16028
|
+
`}`,
|
|
16029
|
+
``,
|
|
16030
|
+
`function __dlGetRecordField(record: Record<string, unknown>, part: string): { found: boolean; value: unknown } {`,
|
|
16031
|
+
` if (part in record) return { found: true, value: record[part] };`,
|
|
16032
|
+
` const normalizedKey = __dlGetNormalizedKey(record, part);`,
|
|
16033
|
+
` if (normalizedKey) return { found: true, value: __dlReadOwnField(record, normalizedKey) };`,
|
|
16034
|
+
` const projectedValues = record.__deeplineCsvProjectedValues;`,
|
|
16035
|
+
` if (projectedValues && typeof projectedValues === 'object' && !Array.isArray(projectedValues)) {`,
|
|
16036
|
+
` const projectedRecord = projectedValues as Record<string, unknown>;`,
|
|
16037
|
+
` if (part in projectedRecord) return { found: true, value: projectedRecord[part] };`,
|
|
16038
|
+
` const projectedKey = __dlGetNormalizedKey(projectedRecord, part);`,
|
|
16039
|
+
` if (projectedKey) return { found: true, value: __dlReadOwnField(projectedRecord, projectedKey) };`,
|
|
16040
|
+
` }`,
|
|
16041
|
+
` const data = record.data;`,
|
|
16042
|
+
` if (data && typeof data === 'object' && !Array.isArray(data)) {`,
|
|
16043
|
+
` const dataRecord = data as Record<string, unknown>;`,
|
|
16044
|
+
` if (part in dataRecord) return { found: true, value: dataRecord[part] };`,
|
|
16045
|
+
` const dataKey = __dlGetNormalizedKey(dataRecord, part);`,
|
|
16046
|
+
` if (dataKey) return { found: true, value: __dlReadOwnField(dataRecord, dataKey) };`,
|
|
16047
|
+
` }`,
|
|
16048
|
+
` return { found: false, value: undefined };`,
|
|
16049
|
+
`}`,
|
|
16050
|
+
``,
|
|
15890
16051
|
`function __dlGetByPath(root: unknown, path: string): unknown {`,
|
|
15891
16052
|
` let cursor = root;`,
|
|
15892
16053
|
` for (const part of __dlPathParts(path)) {`,
|
|
15893
16054
|
` if (!cursor || typeof cursor !== 'object') return undefined;`,
|
|
15894
16055
|
` const record = cursor as Record<string, unknown>;`,
|
|
15895
|
-
`
|
|
15896
|
-
`
|
|
15897
|
-
`
|
|
15898
|
-
` }`,
|
|
15899
|
-
` const data = record.data;`,
|
|
15900
|
-
` cursor = data && typeof data === 'object' ? (data as Record<string, unknown>)[part] : undefined;`,
|
|
16056
|
+
` const field = __dlGetRecordField(record, part);`,
|
|
16057
|
+
` if (!field.found) return undefined;`,
|
|
16058
|
+
` cursor = field.value;`,
|
|
15901
16059
|
` }`,
|
|
15902
16060
|
` return cursor;`,
|
|
15903
16061
|
`}`,
|
|
@@ -15962,6 +16120,30 @@ function helperSource() {
|
|
|
15962
16120
|
` return next ?? row;`,
|
|
15963
16121
|
`}`,
|
|
15964
16122
|
``,
|
|
16123
|
+
`function __dlTemplateContext(row: Record<string, unknown>): Record<string, unknown> {`,
|
|
16124
|
+
` const context: Record<string, unknown> = {};`,
|
|
16125
|
+
` const projectedValues = row.__deeplineCsvProjectedValues;`,
|
|
16126
|
+
` if (__dlRecord(projectedValues)) {`,
|
|
16127
|
+
` for (const [key, value] of Object.entries(projectedValues)) context[key] = value;`,
|
|
16128
|
+
` }`,
|
|
16129
|
+
` for (const [key, value] of Object.entries(row)) {`,
|
|
16130
|
+
` if (key.startsWith('__deepline')) continue;`,
|
|
16131
|
+
` context[key] = value;`,
|
|
16132
|
+
` }`,
|
|
16133
|
+
` return context;`,
|
|
16134
|
+
`}`,
|
|
16135
|
+
``,
|
|
16136
|
+
`function __dlPrepareEnrichRow(row: Record<string, unknown>, aliases: string[]): Record<string, unknown> {`,
|
|
16137
|
+
` const cleaned = __dlStripErroredGeneratedColumns(row, aliases);`,
|
|
16138
|
+
` const templateContext = __dlTemplateContext(cleaned);`,
|
|
16139
|
+
` return {`,
|
|
16140
|
+
` ...templateContext,`,
|
|
16141
|
+
` ...cleaned,`,
|
|
16142
|
+
` __deeplineCsvProjectedFields: Object.keys(templateContext),`,
|
|
16143
|
+
` __deeplineCsvProjectedValues: templateContext,`,
|
|
16144
|
+
` };`,
|
|
16145
|
+
`}`,
|
|
16146
|
+
``,
|
|
15965
16147
|
`function __dlRawToolOutput(result: unknown): unknown {`,
|
|
15966
16148
|
` if (!result || typeof result !== 'object') return result;`,
|
|
15967
16149
|
` const record = result as Record<string, unknown>;`,
|
|
@@ -16999,7 +17181,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
|
|
|
16999
17181
|
}
|
|
17000
17182
|
return input2.client.runs.get(runId, { full: true });
|
|
17001
17183
|
}
|
|
17002
|
-
function
|
|
17184
|
+
function isRecord7(value) {
|
|
17003
17185
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
17004
17186
|
}
|
|
17005
17187
|
async function captureStdout(run, options = {}) {
|
|
@@ -17047,12 +17229,12 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
17047
17229
|
if (!rowsInfo) {
|
|
17048
17230
|
throw new Error("The generated play did not return row-shaped output.");
|
|
17049
17231
|
}
|
|
17050
|
-
if (
|
|
17232
|
+
if (options?.client) {
|
|
17051
17233
|
rowsInfo = await fetchBackingRowsForCsvExport({
|
|
17052
17234
|
client: options.client,
|
|
17053
17235
|
status,
|
|
17054
17236
|
rowsInfo
|
|
17055
|
-
}) ?? rowsInfo;
|
|
17237
|
+
}).catch(() => null) ?? rowsInfo;
|
|
17056
17238
|
}
|
|
17057
17239
|
assertCompleteRowsForCsvExport(rowsInfo, status, outputPath);
|
|
17058
17240
|
const merged = mergeRowsForCsvExport(rowsInfo.rows, options);
|
|
@@ -17068,10 +17250,14 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
17068
17250
|
csvStringFromRows(merged.rows, columns),
|
|
17069
17251
|
"utf8"
|
|
17070
17252
|
);
|
|
17253
|
+
const sourceCsvRows = options?.sourceCsvPath ? readCsvRows(options.sourceCsvPath).length : null;
|
|
17071
17254
|
return {
|
|
17255
|
+
sourceCsvRows,
|
|
17256
|
+
selectedRows: rowsInfo.totalRows,
|
|
17257
|
+
enrichedRows: rowsInfo.rows.length,
|
|
17072
17258
|
rows: merged.rows.length,
|
|
17073
17259
|
path: resolve11(outputPath),
|
|
17074
|
-
|
|
17260
|
+
enrichedDataRows: rowsInfo.rows
|
|
17075
17261
|
};
|
|
17076
17262
|
}
|
|
17077
17263
|
function recordField(value, key) {
|
|
@@ -17152,12 +17338,12 @@ function collectHardFailureAliases(config) {
|
|
|
17152
17338
|
}
|
|
17153
17339
|
function cellFailureError(value) {
|
|
17154
17340
|
const parsed = parseMaybeJsonObject(value);
|
|
17155
|
-
if (!
|
|
17341
|
+
if (!isRecord7(parsed)) {
|
|
17156
17342
|
return null;
|
|
17157
17343
|
}
|
|
17158
17344
|
const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
|
|
17159
17345
|
const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
|
|
17160
|
-
const result =
|
|
17346
|
+
const result = isRecord7(parsed.result) ? parsed.result : null;
|
|
17161
17347
|
const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
|
|
17162
17348
|
if (!directError && !resultError && status !== "error" && status !== "failed") {
|
|
17163
17349
|
return null;
|
|
@@ -17223,6 +17409,136 @@ function collectEnrichFailureJobs(input2) {
|
|
|
17223
17409
|
});
|
|
17224
17410
|
return jobs;
|
|
17225
17411
|
}
|
|
17412
|
+
function parseExecutionCount(value) {
|
|
17413
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
17414
|
+
return Math.max(0, Math.trunc(value));
|
|
17415
|
+
}
|
|
17416
|
+
if (typeof value !== "string") {
|
|
17417
|
+
return null;
|
|
17418
|
+
}
|
|
17419
|
+
const match = value.trim().match(/^(\d+)\s*\//);
|
|
17420
|
+
return match?.[1] ? Number.parseInt(match[1], 10) : null;
|
|
17421
|
+
}
|
|
17422
|
+
function executionSummaryText(count, total) {
|
|
17423
|
+
const percent = total > 0 ? Math.round(count / total * 100) : 0;
|
|
17424
|
+
return `${count}/${total} (${percent}%)`;
|
|
17425
|
+
}
|
|
17426
|
+
function collectColumnStats(status) {
|
|
17427
|
+
const summaries = [];
|
|
17428
|
+
const visit = (value) => {
|
|
17429
|
+
if (Array.isArray(value)) {
|
|
17430
|
+
value.forEach(visit);
|
|
17431
|
+
return;
|
|
17432
|
+
}
|
|
17433
|
+
if (!isRecord7(value)) {
|
|
17434
|
+
return;
|
|
17435
|
+
}
|
|
17436
|
+
if (isRecord7(value.columnStats)) {
|
|
17437
|
+
summaries.push(value.columnStats);
|
|
17438
|
+
}
|
|
17439
|
+
Object.values(value).forEach(visit);
|
|
17440
|
+
};
|
|
17441
|
+
visit(status);
|
|
17442
|
+
return summaries;
|
|
17443
|
+
}
|
|
17444
|
+
function firstAliasExecutionCounts(input2) {
|
|
17445
|
+
const aliases = collectConfigScalarAliasOrder(input2.config);
|
|
17446
|
+
const summaries = collectColumnStats(input2.status);
|
|
17447
|
+
for (const alias of aliases) {
|
|
17448
|
+
const stat4 = summaries.map((summary) => summary[alias]).find(isRecord7);
|
|
17449
|
+
if (!stat4) continue;
|
|
17450
|
+
if (input2.forceAliases.has(normalizeAlias2(alias))) {
|
|
17451
|
+
return { executed: input2.selectedRows, reused: 0 };
|
|
17452
|
+
}
|
|
17453
|
+
const execution = isRecord7(stat4.execution) ? stat4.execution : null;
|
|
17454
|
+
if (!execution) continue;
|
|
17455
|
+
return {
|
|
17456
|
+
executed: parseExecutionCount(execution["completed:executed"]),
|
|
17457
|
+
reused: parseExecutionCount(execution["completed:reused"])
|
|
17458
|
+
};
|
|
17459
|
+
}
|
|
17460
|
+
return { executed: null, reused: null };
|
|
17461
|
+
}
|
|
17462
|
+
function rewriteEnrichJsonStatus(input2) {
|
|
17463
|
+
const selectedRows = input2.output?.selectedRows ?? extractCanonicalRowsInfo(input2.status)?.totalRows ?? 0;
|
|
17464
|
+
const failedRows = new Set(
|
|
17465
|
+
input2.failureReport?.jobs.map((job) => job.row_id) ?? []
|
|
17466
|
+
).size;
|
|
17467
|
+
const executionCounts = firstAliasExecutionCounts({
|
|
17468
|
+
status: input2.status,
|
|
17469
|
+
config: input2.config,
|
|
17470
|
+
forceAliases: input2.forceAliases,
|
|
17471
|
+
selectedRows
|
|
17472
|
+
});
|
|
17473
|
+
const forcedAliases = new Set(
|
|
17474
|
+
collectConfigScalarAliasOrder(input2.config).filter((alias) => input2.forceAliases.has(normalizeAlias2(alias))).map((alias) => alias)
|
|
17475
|
+
);
|
|
17476
|
+
const rewrite = (value) => {
|
|
17477
|
+
if (Array.isArray(value)) {
|
|
17478
|
+
return value.map(rewrite);
|
|
17479
|
+
}
|
|
17480
|
+
if (!isRecord7(value)) {
|
|
17481
|
+
return value;
|
|
17482
|
+
}
|
|
17483
|
+
const next = {};
|
|
17484
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
17485
|
+
next[key] = rewrite(entry);
|
|
17486
|
+
}
|
|
17487
|
+
if (isRecord7(next.progress)) {
|
|
17488
|
+
next.progress = {
|
|
17489
|
+
...next.progress,
|
|
17490
|
+
...selectedRows > 0 ? { total: selectedRows } : {},
|
|
17491
|
+
...executionCounts.executed !== null ? { executed: executionCounts.executed } : {},
|
|
17492
|
+
...executionCounts.reused !== null ? { reused: executionCounts.reused } : {},
|
|
17493
|
+
...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
|
|
17494
|
+
};
|
|
17495
|
+
}
|
|
17496
|
+
if (isRecord7(next.summary)) {
|
|
17497
|
+
const rowCounts = isRecord7(next.summary.rowCounts) ? next.summary.rowCounts : null;
|
|
17498
|
+
if (failedRows > 0) {
|
|
17499
|
+
next.summary = {
|
|
17500
|
+
...next.summary,
|
|
17501
|
+
rowCounts: {
|
|
17502
|
+
...rowCounts ?? {},
|
|
17503
|
+
persisted: selectedRows,
|
|
17504
|
+
succeeded: Math.max(0, selectedRows - failedRows),
|
|
17505
|
+
failed: failedRows
|
|
17506
|
+
}
|
|
17507
|
+
};
|
|
17508
|
+
}
|
|
17509
|
+
}
|
|
17510
|
+
if (isRecord7(next.columnStats) && selectedRows > 0) {
|
|
17511
|
+
const columnStats = { ...next.columnStats };
|
|
17512
|
+
for (const alias of forcedAliases) {
|
|
17513
|
+
const stat4 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
|
|
17514
|
+
const execution = isRecord7(stat4?.execution) ? stat4.execution : null;
|
|
17515
|
+
if (!stat4 || !execution) continue;
|
|
17516
|
+
columnStats[alias] = {
|
|
17517
|
+
...stat4,
|
|
17518
|
+
execution: {
|
|
17519
|
+
...execution,
|
|
17520
|
+
"completed:executed": executionSummaryText(
|
|
17521
|
+
selectedRows,
|
|
17522
|
+
selectedRows
|
|
17523
|
+
),
|
|
17524
|
+
"completed:reused": executionSummaryText(0, selectedRows)
|
|
17525
|
+
}
|
|
17526
|
+
};
|
|
17527
|
+
}
|
|
17528
|
+
next.columnStats = columnStats;
|
|
17529
|
+
}
|
|
17530
|
+
return next;
|
|
17531
|
+
};
|
|
17532
|
+
const rewritten = rewrite(input2.status);
|
|
17533
|
+
if (failedRows === 0 || !isRecord7(rewritten)) {
|
|
17534
|
+
return rewritten;
|
|
17535
|
+
}
|
|
17536
|
+
return {
|
|
17537
|
+
...rewritten,
|
|
17538
|
+
...rewritten.status === "completed" ? { status: "failed" } : {},
|
|
17539
|
+
...isRecord7(rewritten.run) && rewritten.run.status === "completed" ? { run: { ...rewritten.run, status: "failed" } } : {}
|
|
17540
|
+
};
|
|
17541
|
+
}
|
|
17226
17542
|
function summarizeFailedJobError(value) {
|
|
17227
17543
|
const text = String(value ?? "").trim();
|
|
17228
17544
|
return text.length > 500 ? `${text.slice(0, 497)}...` : text;
|
|
@@ -17491,11 +17807,11 @@ function normalizeEnrichRowsForCsvExport(rows) {
|
|
|
17491
17807
|
}
|
|
17492
17808
|
function legacyMetadataFromRow(row) {
|
|
17493
17809
|
const direct = parseLegacyMetadataCell(row._metadata);
|
|
17494
|
-
if (direct &&
|
|
17810
|
+
if (direct && isRecord7(direct.columns)) {
|
|
17495
17811
|
return direct;
|
|
17496
17812
|
}
|
|
17497
17813
|
const relocated = parseLegacyMetadataCell(row.metadata);
|
|
17498
|
-
if (relocated &&
|
|
17814
|
+
if (relocated && isRecord7(relocated.columns)) {
|
|
17499
17815
|
return relocated;
|
|
17500
17816
|
}
|
|
17501
17817
|
const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
|
|
@@ -17512,7 +17828,7 @@ function legacyMetadataFromRow(row) {
|
|
|
17512
17828
|
}
|
|
17513
17829
|
function parseLegacyMetadataCell(value) {
|
|
17514
17830
|
const parsed = parseMaybeJsonObject(value);
|
|
17515
|
-
if (
|
|
17831
|
+
if (isRecord7(parsed)) {
|
|
17516
17832
|
return parsed;
|
|
17517
17833
|
}
|
|
17518
17834
|
if (typeof value !== "string") {
|
|
@@ -17529,12 +17845,12 @@ function parseLegacyMetadataCell(value) {
|
|
|
17529
17845
|
for (const candidate of candidates) {
|
|
17530
17846
|
try {
|
|
17531
17847
|
const decoded = JSON.parse(candidate);
|
|
17532
|
-
if (
|
|
17848
|
+
if (isRecord7(decoded)) {
|
|
17533
17849
|
return decoded;
|
|
17534
17850
|
}
|
|
17535
17851
|
if (typeof decoded === "string") {
|
|
17536
17852
|
const nested = JSON.parse(decoded);
|
|
17537
|
-
if (
|
|
17853
|
+
if (isRecord7(nested)) {
|
|
17538
17854
|
return nested;
|
|
17539
17855
|
}
|
|
17540
17856
|
}
|
|
@@ -17544,8 +17860,8 @@ function parseLegacyMetadataCell(value) {
|
|
|
17544
17860
|
return null;
|
|
17545
17861
|
}
|
|
17546
17862
|
function mergeLegacyMetadataRecords(base, enriched) {
|
|
17547
|
-
const baseColumns =
|
|
17548
|
-
const enrichedColumns =
|
|
17863
|
+
const baseColumns = isRecord7(base.columns) ? base.columns : null;
|
|
17864
|
+
const enrichedColumns = isRecord7(enriched.columns) ? enriched.columns : null;
|
|
17549
17865
|
const merged = {
|
|
17550
17866
|
...base,
|
|
17551
17867
|
...enriched
|
|
@@ -17747,7 +18063,7 @@ function registerEnrichCommand(program) {
|
|
|
17747
18063
|
sourceCsvPath,
|
|
17748
18064
|
rows
|
|
17749
18065
|
}) : null;
|
|
17750
|
-
const rowsForFailureReport = exportResult?.
|
|
18066
|
+
const rowsForFailureReport = exportResult?.enrichedDataRows ?? extractCanonicalRowsInfo(status)?.rows ?? [];
|
|
17751
18067
|
if (options.json) {
|
|
17752
18068
|
const failureReport2 = await maybeEmitEnrichFailureReport({
|
|
17753
18069
|
config,
|
|
@@ -17756,10 +18072,22 @@ function registerEnrichCommand(program) {
|
|
|
17756
18072
|
client: client2,
|
|
17757
18073
|
outputPath: exportResult?.path ?? outputPath ?? null
|
|
17758
18074
|
});
|
|
18075
|
+
const run = rewriteEnrichJsonStatus({
|
|
18076
|
+
status,
|
|
18077
|
+
config,
|
|
18078
|
+
forceAliases,
|
|
18079
|
+
output: exportResult,
|
|
18080
|
+
failureReport: failureReport2
|
|
18081
|
+
});
|
|
17759
18082
|
printJson({
|
|
17760
18083
|
ok: !failureReport2,
|
|
17761
|
-
run
|
|
17762
|
-
output: exportResult ? {
|
|
18084
|
+
run,
|
|
18085
|
+
output: exportResult ? {
|
|
18086
|
+
sourceCsvRows: exportResult.sourceCsvRows,
|
|
18087
|
+
selectedRows: exportResult.selectedRows,
|
|
18088
|
+
enrichedRows: exportResult.enrichedRows,
|
|
18089
|
+
path: exportResult.path
|
|
18090
|
+
} : null,
|
|
17763
18091
|
...failureReport2 ? {
|
|
17764
18092
|
failure_report: {
|
|
17765
18093
|
path: failureReport2.path,
|
|
@@ -17779,7 +18107,7 @@ function registerEnrichCommand(program) {
|
|
|
17779
18107
|
);
|
|
17780
18108
|
const waterfallSummaryLines = buildEnrichWaterfallSummaryLines(
|
|
17781
18109
|
config,
|
|
17782
|
-
exportResult.
|
|
18110
|
+
exportResult.enrichedDataRows
|
|
17783
18111
|
);
|
|
17784
18112
|
if (waterfallSummaryLines.length > 0) {
|
|
17785
18113
|
process.stdout.write(`${waterfallSummaryLines.join("\n")}
|
|
@@ -17846,6 +18174,129 @@ Examples:
|
|
|
17846
18174
|
).argument("<text>", "Feedback text").option("--command <command>", "Command that reproduced the issue").option("--payload <payload>", "JSON or plain-text payload for the repro").option("--json", "Emit JSON output").action(handleFeedback);
|
|
17847
18175
|
}
|
|
17848
18176
|
|
|
18177
|
+
// src/cli/commands/legacy-noops.ts
|
|
18178
|
+
var SESSION_SUBCOMMANDS = [
|
|
18179
|
+
"start",
|
|
18180
|
+
"status",
|
|
18181
|
+
"output",
|
|
18182
|
+
"alert",
|
|
18183
|
+
"usage",
|
|
18184
|
+
"limit",
|
|
18185
|
+
"render",
|
|
18186
|
+
"send"
|
|
18187
|
+
];
|
|
18188
|
+
var BACKEND_SUBCOMMANDS = [
|
|
18189
|
+
"start",
|
|
18190
|
+
"stop",
|
|
18191
|
+
"status",
|
|
18192
|
+
"refresh-runtime",
|
|
18193
|
+
"sync-runtime"
|
|
18194
|
+
];
|
|
18195
|
+
function legacyNoopEnvelope(input2) {
|
|
18196
|
+
const command = [
|
|
18197
|
+
"deepline",
|
|
18198
|
+
input2.family,
|
|
18199
|
+
input2.subcommand
|
|
18200
|
+
].filter(Boolean).join(" ");
|
|
18201
|
+
const subject = input2.family === "session" ? "Legacy Session UI/playground command" : "Legacy local playground backend command";
|
|
18202
|
+
const note = input2.family === "session" ? "The SDK CLI does not manage the legacy Python Session UI. This command is accepted for backwards compatibility and intentionally does nothing." : "The SDK CLI does not start or stop the legacy Python local playground backend. This command is accepted for backwards compatibility and intentionally does nothing.";
|
|
18203
|
+
return {
|
|
18204
|
+
ok: true,
|
|
18205
|
+
noop: true,
|
|
18206
|
+
command,
|
|
18207
|
+
compatibility: {
|
|
18208
|
+
family: "legacy_python_cli",
|
|
18209
|
+
sdk_behavior: "noop"
|
|
18210
|
+
},
|
|
18211
|
+
render: {
|
|
18212
|
+
sections: [
|
|
18213
|
+
{
|
|
18214
|
+
title: subject,
|
|
18215
|
+
lines: [note]
|
|
18216
|
+
}
|
|
18217
|
+
]
|
|
18218
|
+
}
|
|
18219
|
+
};
|
|
18220
|
+
}
|
|
18221
|
+
function printLegacyNoop(input2) {
|
|
18222
|
+
printCommandEnvelope(legacyNoopEnvelope(input2), { json: input2.options.json });
|
|
18223
|
+
}
|
|
18224
|
+
function legacySubcommandFromArgv(family) {
|
|
18225
|
+
const args = process.argv.slice(2);
|
|
18226
|
+
const familyIndex = args.indexOf(family);
|
|
18227
|
+
const nextToken = familyIndex >= 0 ? args[familyIndex + 1] : void 0;
|
|
18228
|
+
return nextToken && !nextToken.startsWith("-") ? nextToken : void 0;
|
|
18229
|
+
}
|
|
18230
|
+
function addLegacyNoopSubcommand(parent, family, subcommand, description) {
|
|
18231
|
+
parent.command(subcommand).description(description).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").action((_args, options) => {
|
|
18232
|
+
printLegacyNoop({ family, subcommand, options });
|
|
18233
|
+
});
|
|
18234
|
+
}
|
|
18235
|
+
function registerLegacyNoopCommands(program) {
|
|
18236
|
+
const session = program.command("session").description(
|
|
18237
|
+
"Compatibility no-ops for legacy Python Session UI commands."
|
|
18238
|
+
).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
|
|
18239
|
+
"after",
|
|
18240
|
+
`
|
|
18241
|
+
Notes:
|
|
18242
|
+
The SDK CLI accepts singular session commands from older agent skills so they
|
|
18243
|
+
do not fail, but it does not manage the legacy Python Session UI.
|
|
18244
|
+
Use "deepline sessions send" or "deepline sessions render" for real SDK
|
|
18245
|
+
transcript workflows.
|
|
18246
|
+
|
|
18247
|
+
Examples:
|
|
18248
|
+
deepline session start --steps '["Inspect CSV","Run pilot"]'
|
|
18249
|
+
deepline session status --message "Running pilot"
|
|
18250
|
+
deepline session output --csv ./results.csv --label "Results"
|
|
18251
|
+
`
|
|
18252
|
+
).action((args, options) => {
|
|
18253
|
+
void args;
|
|
18254
|
+
printLegacyNoop({
|
|
18255
|
+
family: "session",
|
|
18256
|
+
subcommand: legacySubcommandFromArgv("session"),
|
|
18257
|
+
options
|
|
18258
|
+
});
|
|
18259
|
+
});
|
|
18260
|
+
for (const subcommand of SESSION_SUBCOMMANDS) {
|
|
18261
|
+
addLegacyNoopSubcommand(
|
|
18262
|
+
session,
|
|
18263
|
+
"session",
|
|
18264
|
+
subcommand,
|
|
18265
|
+
`Accept legacy "deepline session ${subcommand}" as an SDK no-op.`
|
|
18266
|
+
);
|
|
18267
|
+
}
|
|
18268
|
+
const backend = program.command("backend").description(
|
|
18269
|
+
"Compatibility no-ops for legacy Python local backend commands."
|
|
18270
|
+
).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
|
|
18271
|
+
"after",
|
|
18272
|
+
`
|
|
18273
|
+
Notes:
|
|
18274
|
+
The SDK CLI uses the configured Deepline host and V2 play runtime. It does not
|
|
18275
|
+
start, stop, or refresh the legacy Python local playground backend.
|
|
18276
|
+
|
|
18277
|
+
Examples:
|
|
18278
|
+
deepline backend start
|
|
18279
|
+
deepline backend stop --just-backend
|
|
18280
|
+
deepline backend status --json
|
|
18281
|
+
`
|
|
18282
|
+
).action((args, options) => {
|
|
18283
|
+
void args;
|
|
18284
|
+
printLegacyNoop({
|
|
18285
|
+
family: "backend",
|
|
18286
|
+
subcommand: legacySubcommandFromArgv("backend"),
|
|
18287
|
+
options
|
|
18288
|
+
});
|
|
18289
|
+
});
|
|
18290
|
+
for (const subcommand of BACKEND_SUBCOMMANDS) {
|
|
18291
|
+
addLegacyNoopSubcommand(
|
|
18292
|
+
backend,
|
|
18293
|
+
"backend",
|
|
18294
|
+
subcommand,
|
|
18295
|
+
`Accept legacy "deepline backend ${subcommand}" as an SDK no-op.`
|
|
18296
|
+
);
|
|
18297
|
+
}
|
|
18298
|
+
}
|
|
18299
|
+
|
|
17849
18300
|
// src/cli/commands/org.ts
|
|
17850
18301
|
async function fetchOrganizations(http, apiKey) {
|
|
17851
18302
|
return http.post("/api/v2/auth/cli/organizations", { api_key: apiKey });
|
|
@@ -19761,11 +20212,13 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
19761
20212
|
"deeplineUsdPerPricingUnit",
|
|
19762
20213
|
"deepline_usd_per_pricing_unit"
|
|
19763
20214
|
);
|
|
19764
|
-
const starterScript =
|
|
19765
|
-
|
|
19766
|
-
|
|
19767
|
-
|
|
19768
|
-
|
|
20215
|
+
const starterScript = extractedLists.length > 0 ? starterScriptJson(
|
|
20216
|
+
seedToolListScript({
|
|
20217
|
+
toolId,
|
|
20218
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
20219
|
+
rows: []
|
|
20220
|
+
})
|
|
20221
|
+
) : null;
|
|
19769
20222
|
return {
|
|
19770
20223
|
schemaVersion: 1,
|
|
19771
20224
|
toolId,
|
|
@@ -19791,20 +20244,12 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
19791
20244
|
extractedValues
|
|
19792
20245
|
},
|
|
19793
20246
|
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
19794
|
-
starterScript: {
|
|
19795
|
-
path: starterScript.path,
|
|
19796
|
-
sourceCode: starterScript.sourceCode,
|
|
19797
|
-
projectDir: starterScript.projectDir,
|
|
19798
|
-
copyToProject: {
|
|
19799
|
-
macosLinux: starterScript.macCopyCommand,
|
|
19800
|
-
windowsPowerShell: starterScript.windowsCopyCommand
|
|
19801
|
-
}
|
|
19802
|
-
}
|
|
20247
|
+
...starterScript ? { starterScript } : {}
|
|
19803
20248
|
};
|
|
19804
20249
|
}
|
|
19805
20250
|
function extractionContractEntries(entries) {
|
|
19806
20251
|
return entries.flatMap((entry) => {
|
|
19807
|
-
if (!
|
|
20252
|
+
if (!isRecord8(entry)) return [];
|
|
19808
20253
|
const name = stringField(entry, "name");
|
|
19809
20254
|
const expression = stringField(entry, "expression");
|
|
19810
20255
|
return name && expression ? [{ name, expression }] : [];
|
|
@@ -19812,8 +20257,8 @@ function extractionContractEntries(entries) {
|
|
|
19812
20257
|
}
|
|
19813
20258
|
function printCompactToolContract(tool, requestedToolId) {
|
|
19814
20259
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19815
|
-
const cost =
|
|
19816
|
-
const getters =
|
|
20260
|
+
const cost = isRecord8(contract.cost) ? contract.cost : {};
|
|
20261
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19817
20262
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19818
20263
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19819
20264
|
const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
|
|
@@ -19830,7 +20275,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19830
20275
|
console.log("");
|
|
19831
20276
|
console.log("Inputs:");
|
|
19832
20277
|
for (const field of inputFields) {
|
|
19833
|
-
if (!
|
|
20278
|
+
if (!isRecord8(field)) continue;
|
|
19834
20279
|
const name = stringField(field, "name");
|
|
19835
20280
|
if (!name) continue;
|
|
19836
20281
|
const required = field.required ? "*" : "";
|
|
@@ -19843,7 +20288,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19843
20288
|
}
|
|
19844
20289
|
console.log("");
|
|
19845
20290
|
printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
|
|
19846
|
-
const starterScript =
|
|
20291
|
+
const starterScript = isRecord8(contract.starterScript) ? contract.starterScript : {};
|
|
19847
20292
|
const starterPath = stringField(starterScript, "path");
|
|
19848
20293
|
if (starterPath) {
|
|
19849
20294
|
console.log("");
|
|
@@ -19857,14 +20302,14 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19857
20302
|
console.log("Getters:");
|
|
19858
20303
|
if (listGetters.length) console.log("Lists:");
|
|
19859
20304
|
for (const entry of listGetters) {
|
|
19860
|
-
if (
|
|
20305
|
+
if (isRecord8(entry))
|
|
19861
20306
|
console.log(
|
|
19862
20307
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19863
20308
|
);
|
|
19864
20309
|
}
|
|
19865
20310
|
if (valueGetters.length) console.log("Values:");
|
|
19866
20311
|
for (const entry of valueGetters) {
|
|
19867
|
-
if (
|
|
20312
|
+
if (isRecord8(entry))
|
|
19868
20313
|
console.log(
|
|
19869
20314
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19870
20315
|
);
|
|
@@ -19877,7 +20322,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19877
20322
|
}
|
|
19878
20323
|
function printToolPricingOnly(tool, requestedToolId, options = {}) {
|
|
19879
20324
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19880
|
-
const cost =
|
|
20325
|
+
const cost = isRecord8(contract.cost) ? contract.cost : {};
|
|
19881
20326
|
const pricingModel = stringField(cost, "pricingModel") || "unknown";
|
|
19882
20327
|
const billingMode = stringField(cost, "billingMode") || "unknown";
|
|
19883
20328
|
const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
|
|
@@ -19897,7 +20342,7 @@ function printToolSchemaOnly(tool, requestedToolId) {
|
|
|
19897
20342
|
}
|
|
19898
20343
|
console.log("Inputs:");
|
|
19899
20344
|
for (const field of inputFields) {
|
|
19900
|
-
if (!
|
|
20345
|
+
if (!isRecord8(field)) continue;
|
|
19901
20346
|
const name = stringField(field, "name");
|
|
19902
20347
|
if (!name) continue;
|
|
19903
20348
|
const required = field.required ? "*" : "";
|
|
@@ -19923,10 +20368,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
19923
20368
|
` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
|
|
19924
20369
|
);
|
|
19925
20370
|
console.log("});");
|
|
19926
|
-
const getters =
|
|
20371
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19927
20372
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19928
20373
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19929
|
-
const firstGetter = [...valueGetters, ...listGetters].find(
|
|
20374
|
+
const firstGetter = [...valueGetters, ...listGetters].find(isRecord8);
|
|
19930
20375
|
if (firstGetter) {
|
|
19931
20376
|
const name = stringField(firstGetter, "name") || "value";
|
|
19932
20377
|
const expression = stringField(firstGetter, "expression");
|
|
@@ -19943,7 +20388,7 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
19943
20388
|
}
|
|
19944
20389
|
function printToolGettersOnly(tool, requestedToolId) {
|
|
19945
20390
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19946
|
-
const getters =
|
|
20391
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19947
20392
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19948
20393
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19949
20394
|
console.log(`Getters: ${contract.toolId}`);
|
|
@@ -19956,7 +20401,7 @@ function printToolGettersOnly(tool, requestedToolId) {
|
|
|
19956
20401
|
if (listGetters.length) {
|
|
19957
20402
|
console.log("Lists:");
|
|
19958
20403
|
for (const entry of listGetters) {
|
|
19959
|
-
if (
|
|
20404
|
+
if (isRecord8(entry))
|
|
19960
20405
|
console.log(
|
|
19961
20406
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19962
20407
|
);
|
|
@@ -19965,7 +20410,7 @@ function printToolGettersOnly(tool, requestedToolId) {
|
|
|
19965
20410
|
if (valueGetters.length) {
|
|
19966
20411
|
console.log("Values:");
|
|
19967
20412
|
for (const entry of valueGetters) {
|
|
19968
|
-
if (
|
|
20413
|
+
if (isRecord8(entry))
|
|
19969
20414
|
console.log(
|
|
19970
20415
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19971
20416
|
);
|
|
@@ -19991,7 +20436,7 @@ function sampleValueForField(field) {
|
|
|
19991
20436
|
function samplePayloadForInputFields(fields) {
|
|
19992
20437
|
return Object.fromEntries(
|
|
19993
20438
|
fields.slice(0, 4).flatMap((field) => {
|
|
19994
|
-
if (!
|
|
20439
|
+
if (!isRecord8(field)) return [];
|
|
19995
20440
|
const name = stringField(field, "name");
|
|
19996
20441
|
if (!name) return [];
|
|
19997
20442
|
return [[name, sampleValueForField(field)]];
|
|
@@ -20016,11 +20461,24 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
20016
20461
|
const inputFields = toolInputFieldsForDisplay(
|
|
20017
20462
|
recordField2(tool, "inputSchema", "input_schema")
|
|
20018
20463
|
);
|
|
20019
|
-
const
|
|
20020
|
-
|
|
20021
|
-
|
|
20022
|
-
|
|
20023
|
-
|
|
20464
|
+
const usageGuidance = usageGuidanceWithAccessDefaults(
|
|
20465
|
+
recordField2(tool, "usageGuidance", "usage_guidance")
|
|
20466
|
+
);
|
|
20467
|
+
const toolExecutionResult = recordField2(
|
|
20468
|
+
usageGuidance,
|
|
20469
|
+
"toolExecutionResult",
|
|
20470
|
+
"tool_execution_result"
|
|
20471
|
+
);
|
|
20472
|
+
const extractedLists = extractionContractEntries(
|
|
20473
|
+
arrayField(toolExecutionResult, "extractedLists", "extracted_lists")
|
|
20474
|
+
);
|
|
20475
|
+
const starterScript = extractedLists.length > 0 ? starterScriptJson(
|
|
20476
|
+
seedToolListScript({
|
|
20477
|
+
toolId,
|
|
20478
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
20479
|
+
rows: []
|
|
20480
|
+
})
|
|
20481
|
+
) : null;
|
|
20024
20482
|
const {
|
|
20025
20483
|
cost: _cost,
|
|
20026
20484
|
deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
|
|
@@ -20040,9 +20498,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
20040
20498
|
toolId,
|
|
20041
20499
|
provider: tool.provider,
|
|
20042
20500
|
displayName: tool.displayName,
|
|
20043
|
-
usageGuidance
|
|
20044
|
-
recordField2(tool, "usageGuidance", "usage_guidance")
|
|
20045
|
-
),
|
|
20501
|
+
usageGuidance,
|
|
20046
20502
|
runtimeOutputHelp: {
|
|
20047
20503
|
contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
|
|
20048
20504
|
getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
|
|
@@ -20053,15 +20509,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
20053
20509
|
forPlayGetterBugs: "Run a tiny play, inspect `deepline runs get <run-id> --full --json`, and export returned dataset handles with `deepline runs export`. Backing tables exist only for ctx.map(...).run(...) stages that actually executed.",
|
|
20054
20510
|
executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
|
|
20055
20511
|
},
|
|
20056
|
-
starterScript: {
|
|
20057
|
-
path: starterScript.path,
|
|
20058
|
-
sourceCode: starterScript.sourceCode,
|
|
20059
|
-
projectDir: starterScript.projectDir,
|
|
20060
|
-
copyToProject: {
|
|
20061
|
-
macosLinux: starterScript.macCopyCommand,
|
|
20062
|
-
windowsPowerShell: starterScript.windowsCopyCommand
|
|
20063
|
-
}
|
|
20064
|
-
}
|
|
20512
|
+
...starterScript ? { starterScript } : {}
|
|
20065
20513
|
};
|
|
20066
20514
|
}
|
|
20067
20515
|
function usageGuidanceWithAccessDefaults(usageGuidance) {
|
|
@@ -20105,12 +20553,12 @@ function formatListedToolCost(tool) {
|
|
|
20105
20553
|
}
|
|
20106
20554
|
function toolInputFieldsForDisplay(inputSchema) {
|
|
20107
20555
|
if (Array.isArray(inputSchema.fields))
|
|
20108
|
-
return inputSchema.fields.filter(
|
|
20109
|
-
const jsonSchema =
|
|
20110
|
-
const properties =
|
|
20556
|
+
return inputSchema.fields.filter(isRecord8);
|
|
20557
|
+
const jsonSchema = isRecord8(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
|
|
20558
|
+
const properties = isRecord8(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
20111
20559
|
const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
|
|
20112
20560
|
return Object.entries(properties).map(([name, value]) => {
|
|
20113
|
-
const property =
|
|
20561
|
+
const property = isRecord8(value) ? value : {};
|
|
20114
20562
|
return {
|
|
20115
20563
|
name,
|
|
20116
20564
|
type: typeof property.type === "string" ? property.type : "unknown",
|
|
@@ -20139,15 +20587,15 @@ function printJsonPreview(label, payload) {
|
|
|
20139
20587
|
}
|
|
20140
20588
|
function samplePayload(samples, key) {
|
|
20141
20589
|
const entry = samples[key];
|
|
20142
|
-
if (!
|
|
20590
|
+
if (!isRecord8(entry)) return void 0;
|
|
20143
20591
|
return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
|
|
20144
20592
|
}
|
|
20145
20593
|
function commandEnvelopeFromRawResponse(rawResponse) {
|
|
20146
|
-
return
|
|
20594
|
+
return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
|
|
20147
20595
|
}
|
|
20148
20596
|
function listExtractorPathsFromUsageGuidance(tool) {
|
|
20149
20597
|
const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
|
|
20150
|
-
const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists :
|
|
20598
|
+
const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
|
|
20151
20599
|
return extractedLists.flatMap((entry) => {
|
|
20152
20600
|
const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
|
|
20153
20601
|
if (!Array.isArray(paths)) return [];
|
|
@@ -20163,7 +20611,7 @@ function formatDecimal(value) {
|
|
|
20163
20611
|
function formatUsd(value) {
|
|
20164
20612
|
return `$${formatDecimal(value)}`;
|
|
20165
20613
|
}
|
|
20166
|
-
function
|
|
20614
|
+
function isRecord8(value) {
|
|
20167
20615
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
20168
20616
|
}
|
|
20169
20617
|
function stringField(source, ...keys) {
|
|
@@ -20190,7 +20638,7 @@ function arrayField(source, ...keys) {
|
|
|
20190
20638
|
function recordField2(source, ...keys) {
|
|
20191
20639
|
for (const key of keys) {
|
|
20192
20640
|
const value = source[key];
|
|
20193
|
-
if (
|
|
20641
|
+
if (isRecord8(value)) return value;
|
|
20194
20642
|
}
|
|
20195
20643
|
return {};
|
|
20196
20644
|
}
|
|
@@ -20256,7 +20704,7 @@ function parseJsonObjectArgument(raw, flagName) {
|
|
|
20256
20704
|
}
|
|
20257
20705
|
throw invalidJsonError(flagName, message);
|
|
20258
20706
|
}
|
|
20259
|
-
if (!
|
|
20707
|
+
if (!isRecord8(parsed)) {
|
|
20260
20708
|
throw invalidJsonError(flagName, "expected an object.");
|
|
20261
20709
|
}
|
|
20262
20710
|
return parsed;
|
|
@@ -20315,6 +20763,17 @@ function shellQuote2(value) {
|
|
|
20315
20763
|
function powerShellQuote(value) {
|
|
20316
20764
|
return `'${value.replace(/'/g, "''")}'`;
|
|
20317
20765
|
}
|
|
20766
|
+
function starterScriptJson(script) {
|
|
20767
|
+
return {
|
|
20768
|
+
path: script.path,
|
|
20769
|
+
sourceCode: script.sourceCode,
|
|
20770
|
+
projectDir: script.projectDir,
|
|
20771
|
+
copyToProject: {
|
|
20772
|
+
macosLinux: script.macCopyCommand,
|
|
20773
|
+
windowsPowerShell: script.windowsCopyCommand
|
|
20774
|
+
}
|
|
20775
|
+
};
|
|
20776
|
+
}
|
|
20318
20777
|
function seedToolListScript(input2) {
|
|
20319
20778
|
const stem = safeFileStem(input2.toolId);
|
|
20320
20779
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
@@ -20379,7 +20838,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20379
20838
|
kind: summaryEntries.length > 0 ? "object" : "raw",
|
|
20380
20839
|
summary: input2.summary
|
|
20381
20840
|
};
|
|
20382
|
-
const envelopeHasCanonicalOutput =
|
|
20841
|
+
const envelopeHasCanonicalOutput = isRecord8(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
|
|
20383
20842
|
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
|
|
20384
20843
|
const actions = input2.listConversion ? [
|
|
20385
20844
|
{
|
|
@@ -20488,7 +20947,7 @@ async function executeTool(args) {
|
|
|
20488
20947
|
{
|
|
20489
20948
|
...baseEnvelope,
|
|
20490
20949
|
local: {
|
|
20491
|
-
...
|
|
20950
|
+
...isRecord8(baseEnvelope.local) ? baseEnvelope.local : {},
|
|
20492
20951
|
payload_file: jsonPath
|
|
20493
20952
|
}
|
|
20494
20953
|
},
|
|
@@ -21248,10 +21707,6 @@ var command_compatibility_default = {
|
|
|
21248
21707
|
label: "a legacy Python CLI workflow command",
|
|
21249
21708
|
sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
|
|
21250
21709
|
},
|
|
21251
|
-
backend: {
|
|
21252
|
-
family: "python",
|
|
21253
|
-
label: "a legacy Python CLI playground backend command"
|
|
21254
|
-
},
|
|
21255
21710
|
events: {
|
|
21256
21711
|
family: "python",
|
|
21257
21712
|
label: "a legacy Python CLI event command"
|
|
@@ -21487,7 +21942,11 @@ import { homedir as homedir7 } from "os";
|
|
|
21487
21942
|
import { dirname as dirname12, join as join14 } from "path";
|
|
21488
21943
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
21489
21944
|
var SDK_SKILL_NAME = "deepline-plays";
|
|
21490
|
-
var SDK_SKILL_NAMES = [
|
|
21945
|
+
var SDK_SKILL_NAMES = [
|
|
21946
|
+
SDK_SKILL_NAME,
|
|
21947
|
+
"deepline-plays-feedback",
|
|
21948
|
+
"deepline-plays-quickstart"
|
|
21949
|
+
];
|
|
21491
21950
|
var attemptedSync = false;
|
|
21492
21951
|
function shouldSkipSkillsSync() {
|
|
21493
21952
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
@@ -21709,7 +22168,9 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
|
21709
22168
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
21710
22169
|
return;
|
|
21711
22170
|
}
|
|
21712
|
-
writeSdkSkillsStatusLine(
|
|
22171
|
+
writeSdkSkillsStatusLine(
|
|
22172
|
+
"SDK skills changed; syncing Deepline SDK skills..."
|
|
22173
|
+
);
|
|
21713
22174
|
const installed = await runSkillsInstall(baseUrl);
|
|
21714
22175
|
if (!installed) return;
|
|
21715
22176
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
@@ -21749,6 +22210,19 @@ function shouldDeferSkillsSyncForCommand() {
|
|
|
21749
22210
|
const subcommand = args[1];
|
|
21750
22211
|
return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
|
|
21751
22212
|
}
|
|
22213
|
+
function isLegacyNoopInvocation() {
|
|
22214
|
+
const command = process.argv.slice(2)[0];
|
|
22215
|
+
return command === "session" || command === "backend";
|
|
22216
|
+
}
|
|
22217
|
+
function topLevelCommandKnown(program, commandName) {
|
|
22218
|
+
const normalized = commandName.trim();
|
|
22219
|
+
if (!normalized || normalized.startsWith("-")) {
|
|
22220
|
+
return true;
|
|
22221
|
+
}
|
|
22222
|
+
return program.commands.some(
|
|
22223
|
+
(command) => command.name() === normalized || command.aliases().includes(normalized)
|
|
22224
|
+
);
|
|
22225
|
+
}
|
|
21752
22226
|
async function runPlayRunnerHealthCheck() {
|
|
21753
22227
|
const dir = await mkdtemp2(join15(tmpdir5(), "deepline-health-play-"));
|
|
21754
22228
|
const file = join15(dir, "health-check.play.ts");
|
|
@@ -21968,7 +22442,7 @@ Exit codes:
|
|
|
21968
22442
|
`
|
|
21969
22443
|
);
|
|
21970
22444
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
21971
|
-
if (actionCommand.name() === "version" || actionCommand.name() === "update") {
|
|
22445
|
+
if (actionCommand.name() === "version" || actionCommand.name() === "update" || isLegacyNoopInvocation()) {
|
|
21972
22446
|
return;
|
|
21973
22447
|
}
|
|
21974
22448
|
if (printStartupPhase) {
|
|
@@ -21985,9 +22459,7 @@ Exit codes:
|
|
|
21985
22459
|
if (compatibility.error) {
|
|
21986
22460
|
return;
|
|
21987
22461
|
}
|
|
21988
|
-
const relaunched = await maybeAutoUpdateAndRelaunch(
|
|
21989
|
-
compatibility.response
|
|
21990
|
-
);
|
|
22462
|
+
const relaunched = await maybeAutoUpdateAndRelaunch(compatibility.response);
|
|
21991
22463
|
if (relaunched) {
|
|
21992
22464
|
return;
|
|
21993
22465
|
}
|
|
@@ -22015,6 +22487,7 @@ Exit codes:
|
|
|
22015
22487
|
registerCsvCommands(program);
|
|
22016
22488
|
registerDbCommands(program);
|
|
22017
22489
|
registerFeedbackCommands(program);
|
|
22490
|
+
registerLegacyNoopCommands(program);
|
|
22018
22491
|
registerUpdateCommand(program);
|
|
22019
22492
|
registerQuickstartCommands(program);
|
|
22020
22493
|
program.command("preflight").description("Run compact health, auth, and Deepline billing checks.").option("--json", "Force JSON output.").addHelpText(
|
|
@@ -22115,6 +22588,20 @@ Examples:
|
|
|
22115
22588
|
process.exitCode = 2;
|
|
22116
22589
|
return;
|
|
22117
22590
|
}
|
|
22591
|
+
const requestedTopLevelCommand = process.argv.slice(2)[0] ?? "";
|
|
22592
|
+
if (!topLevelCommandKnown(program, requestedTopLevelCommand)) {
|
|
22593
|
+
console.error(`error: unknown command '${requestedTopLevelCommand}'`);
|
|
22594
|
+
const hint = commandCompatibilityHint(
|
|
22595
|
+
"sdk",
|
|
22596
|
+
requestedTopLevelCommand,
|
|
22597
|
+
autoDetectBaseUrl()
|
|
22598
|
+
);
|
|
22599
|
+
if (hint && !process.argv.includes("--json")) {
|
|
22600
|
+
console.error(hint);
|
|
22601
|
+
}
|
|
22602
|
+
process.exitCode = 2;
|
|
22603
|
+
return;
|
|
22604
|
+
}
|
|
22118
22605
|
try {
|
|
22119
22606
|
await program.parseAsync(process.argv);
|
|
22120
22607
|
recordCliTrace({
|