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.js
CHANGED
|
@@ -238,7 +238,7 @@ var SDK_RELEASE = {
|
|
|
238
238
|
// preflight (existence, data rows, quotes, duplicate headers), HTML error
|
|
239
239
|
// scrubbing, and word-boundary watch truncation.
|
|
240
240
|
// 0.1.103 ships the refined SDK CLI command surface.
|
|
241
|
-
// 0.1.104
|
|
241
|
+
// 0.1.104 shipped the retired Postgres scheduler suspension/billing parity and runtime worker hardening.
|
|
242
242
|
// 0.1.105 ships the billing catalog surface: billing plans, subscribe,
|
|
243
243
|
// subscription status/cancel, invoices, and the client.billing namespace.
|
|
244
244
|
// 0.1.106 ships play cell provenance metadata and v2 preview retry hardening.
|
|
@@ -246,10 +246,10 @@ var SDK_RELEASE = {
|
|
|
246
246
|
// skill on the sdk sync surface, and the people-search-to-email prebuilt.
|
|
247
247
|
// 0.1.108 ships explicit dataset column/tool recompute policy and removes
|
|
248
248
|
// the SDK enrich generator's one-second stale policy.
|
|
249
|
-
version: "0.1.
|
|
249
|
+
version: "0.1.109",
|
|
250
250
|
apiContract: "2026-06-dataset-column-cell-stale-hard-cutover",
|
|
251
251
|
supportPolicy: {
|
|
252
|
-
latest: "0.1.
|
|
252
|
+
latest: "0.1.109",
|
|
253
253
|
minimumSupported: "0.1.53",
|
|
254
254
|
deprecatedBelow: "0.1.53",
|
|
255
255
|
commandMinimumSupported: [
|
|
@@ -271,6 +271,7 @@ var SDK_API_CONTRACT = SDK_RELEASE.apiContract;
|
|
|
271
271
|
var COORDINATOR_INTERNAL_TOKEN_HEADER = "x-deepline-internal-token";
|
|
272
272
|
var COORDINATOR_URL_OVERRIDE_HEADER = "x-deepline-coordinator-url";
|
|
273
273
|
var WORKER_CALLBACK_URL_OVERRIDE_HEADER = "x-deepline-worker-callback-url";
|
|
274
|
+
var RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER = "x-deepline-runtime-scheduler-schema";
|
|
274
275
|
var SYNTHETIC_RUN_HEADER = "x-deepline-synthetic-run";
|
|
275
276
|
|
|
276
277
|
// src/http.ts
|
|
@@ -339,6 +340,10 @@ var HttpClient = class {
|
|
|
339
340
|
if (workerCallbackUrl?.trim()) {
|
|
340
341
|
headers[WORKER_CALLBACK_URL_OVERRIDE_HEADER] = workerCallbackUrl.trim();
|
|
341
342
|
}
|
|
343
|
+
const runtimeSchedulerSchema = typeof process !== "undefined" ? process.env?.DEEPLINE_RUNTIME_SCHEDULER_SCHEMA : void 0;
|
|
344
|
+
if (runtimeSchedulerSchema?.trim()) {
|
|
345
|
+
headers[RUNTIME_SCHEDULER_SCHEMA_OVERRIDE_HEADER] = runtimeSchedulerSchema.trim();
|
|
346
|
+
}
|
|
342
347
|
const syntheticRun = typeof process !== "undefined" ? process.env?.DEEPLINE_SYNTHETIC_RUN : void 0;
|
|
343
348
|
if (syntheticRun && syntheticRun.trim() && syntheticRun.trim() !== "0") {
|
|
344
349
|
headers[SYNTHETIC_RUN_HEADER] = "1";
|
|
@@ -545,8 +550,19 @@ var HttpClient = class {
|
|
|
545
550
|
headers
|
|
546
551
|
});
|
|
547
552
|
}
|
|
553
|
+
/**
|
|
554
|
+
* Send a PATCH request with a JSON body.
|
|
555
|
+
*
|
|
556
|
+
* @typeParam T - Expected response body type
|
|
557
|
+
* @param path - API path
|
|
558
|
+
* @param body - JSON-serializable request body
|
|
559
|
+
*/
|
|
548
560
|
async patch(path, body, headers) {
|
|
549
|
-
return this.request(path, {
|
|
561
|
+
return this.request(path, {
|
|
562
|
+
method: "PATCH",
|
|
563
|
+
body,
|
|
564
|
+
headers
|
|
565
|
+
});
|
|
550
566
|
}
|
|
551
567
|
/**
|
|
552
568
|
* Send a DELETE request.
|
|
@@ -897,6 +913,35 @@ function normalizePlayRunLiveStatus(value) {
|
|
|
897
913
|
function isTerminalPlayRunLiveStatus(status) {
|
|
898
914
|
return status === "completed" || status === "failed" || status === "cancelled" || status === "terminated" || status === "timed_out";
|
|
899
915
|
}
|
|
916
|
+
function isRecord2(value) {
|
|
917
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
918
|
+
}
|
|
919
|
+
function finiteNumber2(value) {
|
|
920
|
+
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
921
|
+
}
|
|
922
|
+
function extractTerminalRunLogTail(result) {
|
|
923
|
+
if (!isRecord2(result) || !isRecord2(result._metadata)) {
|
|
924
|
+
return null;
|
|
925
|
+
}
|
|
926
|
+
const runLogTail = result._metadata.runLogTail;
|
|
927
|
+
if (!isRecord2(runLogTail) || !Array.isArray(runLogTail.tail)) {
|
|
928
|
+
return null;
|
|
929
|
+
}
|
|
930
|
+
const logTail = runLogTail.tail.filter(
|
|
931
|
+
(line) => typeof line === "string" && line.trim().length > 0
|
|
932
|
+
);
|
|
933
|
+
if (logTail.length === 0) {
|
|
934
|
+
return null;
|
|
935
|
+
}
|
|
936
|
+
const totalLogCount = Math.max(
|
|
937
|
+
finiteNumber2(runLogTail.totalLogCount) ?? logTail.length,
|
|
938
|
+
logTail.length
|
|
939
|
+
);
|
|
940
|
+
return {
|
|
941
|
+
logTail: logTail.slice(-LOG_TAIL_LIMIT),
|
|
942
|
+
totalLogCount
|
|
943
|
+
};
|
|
944
|
+
}
|
|
900
945
|
function buildSnapshotFromLedger(snapshot) {
|
|
901
946
|
const nodeStates = snapshot.orderedStepIds.map((stepId) => snapshot.stepsById[stepId]).filter((step) => Boolean(step)).map((step) => ({
|
|
902
947
|
nodeId: step.stepId,
|
|
@@ -943,6 +988,14 @@ function buildPlayRunStatusSnapshot(input2) {
|
|
|
943
988
|
updatedAt: input2.run.updatedAt ?? null,
|
|
944
989
|
finishedAt: input2.run.finishedAt ?? null
|
|
945
990
|
});
|
|
991
|
+
const terminalRunLogTail = extractTerminalRunLogTail(input2.run.result);
|
|
992
|
+
if (terminalRunLogTail && terminalRunLogTail.totalLogCount > ledgerSnapshot.totalLogCount) {
|
|
993
|
+
return buildSnapshotFromLedger({
|
|
994
|
+
...ledgerSnapshot,
|
|
995
|
+
logTail: terminalRunLogTail.logTail,
|
|
996
|
+
totalLogCount: terminalRunLogTail.totalLogCount
|
|
997
|
+
});
|
|
998
|
+
}
|
|
946
999
|
return buildSnapshotFromLedger(ledgerSnapshot);
|
|
947
1000
|
}
|
|
948
1001
|
function makeRunStreamEvent(input2) {
|
|
@@ -1537,7 +1590,7 @@ function chunkRegisterPlayArtifacts(artifacts) {
|
|
|
1537
1590
|
return chunks;
|
|
1538
1591
|
}
|
|
1539
1592
|
var RUN_LOGS_PAGE_LIMIT = 1e3;
|
|
1540
|
-
function
|
|
1593
|
+
function isRecord3(value) {
|
|
1541
1594
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
1542
1595
|
}
|
|
1543
1596
|
function isPrebuiltPlayDescription(play) {
|
|
@@ -1639,7 +1692,7 @@ function updatePlayLiveStatusState(state, event) {
|
|
|
1639
1692
|
}
|
|
1640
1693
|
const runId = typeof payload.runId === "string" && payload.runId ? payload.runId : isPlayRunPackage(payload) ? payload.run.id : state.runId;
|
|
1641
1694
|
const status = normalizeLiveStatus(payload.status) ?? (isPlayRunPackage(payload) ? normalizeLiveStatus(payload.run.status) : null) ?? state.status;
|
|
1642
|
-
const progressPayload =
|
|
1695
|
+
const progressPayload = isRecord3(payload.progress) ? payload.progress : {};
|
|
1643
1696
|
if (event.type === "play.run.final_status" && state.logs.length === 0 && state.lastLogSeq === 0) {
|
|
1644
1697
|
const payloadLogs = readStringArray(payload.logs);
|
|
1645
1698
|
const progressLogs = readStringArray(progressPayload.logs);
|
|
@@ -1752,9 +1805,9 @@ var DeeplineClient = class {
|
|
|
1752
1805
|
return fields.length > 0 ? { fields } : schema;
|
|
1753
1806
|
}
|
|
1754
1807
|
schemaMetadata(schema, key) {
|
|
1755
|
-
if (!
|
|
1808
|
+
if (!isRecord3(schema)) return null;
|
|
1756
1809
|
const value = schema[key];
|
|
1757
|
-
return
|
|
1810
|
+
return isRecord3(value) ? value : null;
|
|
1758
1811
|
}
|
|
1759
1812
|
playRunCommand(play, options) {
|
|
1760
1813
|
const target = play.reference || play.name;
|
|
@@ -1801,7 +1854,7 @@ var DeeplineClient = class {
|
|
|
1801
1854
|
aliases,
|
|
1802
1855
|
inputSchema: options?.compact ? this.compactSchema(play.inputSchema) : play.inputSchema ?? null,
|
|
1803
1856
|
outputSchema: options?.compact ? this.compactSchema(play.outputSchema) : play.outputSchema ?? null,
|
|
1804
|
-
staticPipeline:
|
|
1857
|
+
staticPipeline: isRecord3(play.staticPipeline) ? play.staticPipeline : isRecord3(play.currentRevision?.staticPipeline) ? play.currentRevision.staticPipeline : isRecord3(play.liveRevision?.staticPipeline) ? play.liveRevision.staticPipeline : null,
|
|
1805
1858
|
...csvInput ? { csvInput } : {},
|
|
1806
1859
|
...rowOutputSchema ? { rowOutputSchema } : {},
|
|
1807
1860
|
runCommand: runCommand2,
|
|
@@ -5295,14 +5348,14 @@ function sanitizeCsvProjectionInfo(input2) {
|
|
|
5295
5348
|
const rows = input2.rows.map(stripCsvProjectionFields);
|
|
5296
5349
|
return { rows, columns };
|
|
5297
5350
|
}
|
|
5298
|
-
function
|
|
5351
|
+
function isRecord4(value) {
|
|
5299
5352
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
5300
5353
|
}
|
|
5301
5354
|
function isSerializedDataset(value) {
|
|
5302
|
-
return
|
|
5355
|
+
return isRecord4(value) && value.kind === "dataset" && typeof value.count === "number" && Array.isArray(value.preview);
|
|
5303
5356
|
}
|
|
5304
5357
|
function isPackagedDatasetOutput(value) {
|
|
5305
|
-
return
|
|
5358
|
+
return isRecord4(value) && value.kind === "dataset" && isRecord4(value.preview) && Array.isArray(value.preview.rows);
|
|
5306
5359
|
}
|
|
5307
5360
|
function pathParts(path) {
|
|
5308
5361
|
return path.split(".").map((part) => part.trim()).filter(Boolean);
|
|
@@ -5310,7 +5363,7 @@ function pathParts(path) {
|
|
|
5310
5363
|
function valueAtPath(root, path) {
|
|
5311
5364
|
let cursor = root;
|
|
5312
5365
|
for (const part of pathParts(path)) {
|
|
5313
|
-
if (!
|
|
5366
|
+
if (!isRecord4(cursor)) {
|
|
5314
5367
|
return void 0;
|
|
5315
5368
|
}
|
|
5316
5369
|
cursor = cursor[part];
|
|
@@ -5318,17 +5371,17 @@ function valueAtPath(root, path) {
|
|
|
5318
5371
|
return cursor;
|
|
5319
5372
|
}
|
|
5320
5373
|
function totalRowsForDataset(result, datasetPath) {
|
|
5321
|
-
const metadata =
|
|
5374
|
+
const metadata = isRecord4(result._metadata) ? result._metadata : null;
|
|
5322
5375
|
const parentPath = datasetPath.split(".").slice(0, -1).join(".");
|
|
5323
5376
|
const parent = parentPath ? valueAtPath({ result }, parentPath) : result;
|
|
5324
|
-
return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (
|
|
5377
|
+
return metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count ?? (isRecord4(parent) ? parent.totalRows ?? parent.rowCount ?? parent.count : void 0) ?? result.totalRows ?? result.rowCount ?? result.count;
|
|
5325
5378
|
}
|
|
5326
5379
|
function rowArray(value) {
|
|
5327
5380
|
if (!Array.isArray(value)) {
|
|
5328
5381
|
return null;
|
|
5329
5382
|
}
|
|
5330
5383
|
const rows = value.filter(
|
|
5331
|
-
(row) =>
|
|
5384
|
+
(row) => isRecord4(row)
|
|
5332
5385
|
);
|
|
5333
5386
|
return rows.length === value.length ? rows : null;
|
|
5334
5387
|
}
|
|
@@ -5352,7 +5405,7 @@ function inferColumns(rows) {
|
|
|
5352
5405
|
return columns;
|
|
5353
5406
|
}
|
|
5354
5407
|
function columnsFromDatasetSummary(summary) {
|
|
5355
|
-
if (!
|
|
5408
|
+
if (!isRecord4(summary) || !isRecord4(summary.columnStats)) {
|
|
5356
5409
|
return [];
|
|
5357
5410
|
}
|
|
5358
5411
|
return Object.keys(summary.columnStats).filter((column) => column);
|
|
@@ -5381,7 +5434,7 @@ function canonicalRowsInfoFromCandidate(input2) {
|
|
|
5381
5434
|
}
|
|
5382
5435
|
if (isPackagedDatasetOutput(candidate.value)) {
|
|
5383
5436
|
const rawRows = rowArray(candidate.value.preview?.rows) ?? [];
|
|
5384
|
-
const totalRows2 = readNumber(candidate.value.
|
|
5437
|
+
const totalRows2 = readNumber(candidate.value.rowCount) ?? readNumber(candidate.value.preview?.totalRows) ?? rawRows.length;
|
|
5385
5438
|
const explicitColumns = Array.isArray(candidate.value.columns) ? candidate.value.columns.filter(
|
|
5386
5439
|
(column) => typeof column === "string"
|
|
5387
5440
|
) : [];
|
|
@@ -5442,7 +5495,7 @@ function collectDatasetCandidates(input2) {
|
|
|
5442
5495
|
});
|
|
5443
5496
|
return;
|
|
5444
5497
|
}
|
|
5445
|
-
if (!
|
|
5498
|
+
if (!isRecord4(input2.value)) {
|
|
5446
5499
|
return;
|
|
5447
5500
|
}
|
|
5448
5501
|
for (const [key, child] of Object.entries(input2.value)) {
|
|
@@ -5459,12 +5512,12 @@ function collectDatasetCandidates(input2) {
|
|
|
5459
5512
|
}
|
|
5460
5513
|
}
|
|
5461
5514
|
function collectCanonicalRowsInfos(statusOrResult) {
|
|
5462
|
-
const root =
|
|
5463
|
-
const result =
|
|
5515
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5516
|
+
const result = isRecord4(root?.result) ? root.result : root;
|
|
5464
5517
|
if (!result) {
|
|
5465
5518
|
return [];
|
|
5466
5519
|
}
|
|
5467
|
-
const metadata =
|
|
5520
|
+
const metadata = isRecord4(result._metadata) ? result._metadata : null;
|
|
5468
5521
|
const totalFromMetadata = metadata?.totalRows ?? metadata?.rowCount ?? metadata?.count;
|
|
5469
5522
|
const candidates = [
|
|
5470
5523
|
{
|
|
@@ -5488,8 +5541,8 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5488
5541
|
total: totalFromMetadata ?? result.totalRows ?? result.rowCount ?? result.count
|
|
5489
5542
|
}
|
|
5490
5543
|
];
|
|
5491
|
-
if (
|
|
5492
|
-
const outputMetadata =
|
|
5544
|
+
if (isRecord4(result.output)) {
|
|
5545
|
+
const outputMetadata = isRecord4(result.output._metadata) ? result.output._metadata : null;
|
|
5493
5546
|
const outputTotalFromMetadata = outputMetadata?.totalRows ?? outputMetadata?.rowCount ?? outputMetadata?.count;
|
|
5494
5547
|
candidates.push(
|
|
5495
5548
|
{
|
|
@@ -5516,14 +5569,14 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5516
5569
|
}
|
|
5517
5570
|
if (Array.isArray(result.steps)) {
|
|
5518
5571
|
result.steps.forEach((step, index) => {
|
|
5519
|
-
if (!
|
|
5572
|
+
if (!isRecord4(step) || !isRecord4(step.output)) {
|
|
5520
5573
|
return;
|
|
5521
5574
|
}
|
|
5522
5575
|
const source = typeof step.output.path === "string" ? step.output.path : typeof step.id === "string" ? `steps.${step.id}.output` : `steps.${index}.output`;
|
|
5523
5576
|
candidates.push({
|
|
5524
5577
|
source,
|
|
5525
5578
|
value: step.output,
|
|
5526
|
-
total: step.output.rowCount ?? (
|
|
5579
|
+
total: step.output.rowCount ?? (isRecord4(step.output.preview) ? step.output.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
|
|
5527
5580
|
});
|
|
5528
5581
|
});
|
|
5529
5582
|
}
|
|
@@ -5550,15 +5603,15 @@ function collectCanonicalRowsInfos(statusOrResult) {
|
|
|
5550
5603
|
return infos;
|
|
5551
5604
|
}
|
|
5552
5605
|
function collectPackagedStepDatasetCandidates(statusOrResult) {
|
|
5553
|
-
const root =
|
|
5606
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5554
5607
|
if (!root) {
|
|
5555
5608
|
return [];
|
|
5556
5609
|
}
|
|
5557
|
-
const pkg =
|
|
5610
|
+
const pkg = isRecord4(root.package) ? root.package : root;
|
|
5558
5611
|
const steps = Array.isArray(pkg.steps) ? pkg.steps : [];
|
|
5559
5612
|
const candidates = [];
|
|
5560
5613
|
for (const step of steps) {
|
|
5561
|
-
if (!
|
|
5614
|
+
if (!isRecord4(step) || !isRecord4(step.output)) {
|
|
5562
5615
|
continue;
|
|
5563
5616
|
}
|
|
5564
5617
|
const output2 = step.output;
|
|
@@ -5572,14 +5625,14 @@ function collectPackagedStepDatasetCandidates(statusOrResult) {
|
|
|
5572
5625
|
candidates.push({
|
|
5573
5626
|
source,
|
|
5574
5627
|
value: output2,
|
|
5575
|
-
total: output2.rowCount ?? (
|
|
5628
|
+
total: output2.rowCount ?? (isRecord4(output2.preview) ? output2.preview.totalRows : void 0) ?? (isRecord4(step.progress) ? step.progress.total : void 0)
|
|
5576
5629
|
});
|
|
5577
5630
|
}
|
|
5578
5631
|
return candidates;
|
|
5579
5632
|
}
|
|
5580
5633
|
function collectSerializedDatasetRowsInfos(statusOrResult) {
|
|
5581
|
-
const root =
|
|
5582
|
-
const result =
|
|
5634
|
+
const root = isRecord4(statusOrResult) ? statusOrResult : null;
|
|
5635
|
+
const result = isRecord4(root?.result) ? root.result : root;
|
|
5583
5636
|
const candidates = [];
|
|
5584
5637
|
if (result) {
|
|
5585
5638
|
collectDatasetCandidates({
|
|
@@ -5615,17 +5668,17 @@ function percentText(numerator, denominator) {
|
|
|
5615
5668
|
return datasetSummaryPercentText(numerator, denominator);
|
|
5616
5669
|
}
|
|
5617
5670
|
function isDatasetExecutionStatsInput(value) {
|
|
5618
|
-
return
|
|
5671
|
+
return isRecord4(value) && isRecord4(value.columnStats) && Object.values(value.columnStats).every(isRecord4);
|
|
5619
5672
|
}
|
|
5620
5673
|
function extractDatasetExecutionStats(statusOrResult) {
|
|
5621
|
-
if (!
|
|
5674
|
+
if (!isRecord4(statusOrResult)) {
|
|
5622
5675
|
return null;
|
|
5623
5676
|
}
|
|
5624
5677
|
const direct = statusOrResult.dataset_execution_stats;
|
|
5625
5678
|
if (isDatasetExecutionStatsInput(direct)) {
|
|
5626
5679
|
return direct;
|
|
5627
5680
|
}
|
|
5628
|
-
const nested =
|
|
5681
|
+
const nested = isRecord4(statusOrResult.result) ? statusOrResult.result.dataset_execution_stats : null;
|
|
5629
5682
|
return isDatasetExecutionStatsInput(nested) ? nested : null;
|
|
5630
5683
|
}
|
|
5631
5684
|
function countPercentText(count, denominator) {
|
|
@@ -5666,13 +5719,13 @@ function summarizeSampleValue(value, depth = 0) {
|
|
|
5666
5719
|
if (typeof parsed === "number" || typeof parsed === "boolean") return parsed;
|
|
5667
5720
|
if (depth >= 3) {
|
|
5668
5721
|
if (Array.isArray(parsed)) return [];
|
|
5669
|
-
if (
|
|
5722
|
+
if (isRecord4(parsed)) return {};
|
|
5670
5723
|
return compactScalar(parsed);
|
|
5671
5724
|
}
|
|
5672
5725
|
if (Array.isArray(parsed)) {
|
|
5673
5726
|
return parsed.slice(0, 3).map((item) => summarizeSampleValue(item, depth + 1));
|
|
5674
5727
|
}
|
|
5675
|
-
if (
|
|
5728
|
+
if (isRecord4(parsed)) {
|
|
5676
5729
|
const out = {};
|
|
5677
5730
|
for (const [key, nested] of Object.entries(parsed)) {
|
|
5678
5731
|
if (["__dl", "meta", "metadata"].includes(key)) {
|
|
@@ -5703,7 +5756,7 @@ function compactCell(value) {
|
|
|
5703
5756
|
}
|
|
5704
5757
|
return `[${parsed.length} items]`;
|
|
5705
5758
|
}
|
|
5706
|
-
if (
|
|
5759
|
+
if (isRecord4(parsed)) {
|
|
5707
5760
|
for (const key of ["matched_result", "output"]) {
|
|
5708
5761
|
if (parsed[key] !== null && parsed[key] !== void 0 && parsed[key] !== "") {
|
|
5709
5762
|
return compactCell(parsed[key]);
|
|
@@ -7473,16 +7526,19 @@ var PLAY_DEDUP_BACKENDS = {
|
|
|
7473
7526
|
var PLAY_SCHEDULER_BACKENDS = {
|
|
7474
7527
|
temporal: "temporal",
|
|
7475
7528
|
cfWorkflows: "cf-workflows",
|
|
7529
|
+
/**
|
|
7530
|
+
* Private legacy id retained only so old persisted rows can be interpreted.
|
|
7531
|
+
* It is not a selectable scheduler backend after the Hatchet hard cutover.
|
|
7532
|
+
*/
|
|
7476
7533
|
postgres: "postgres",
|
|
7534
|
+
hatchet: "hatchet",
|
|
7477
7535
|
inProcess: "in-process"
|
|
7478
7536
|
};
|
|
7479
7537
|
|
|
7480
7538
|
// ../shared_libs/play-runtime/providers.ts
|
|
7481
7539
|
var PLAY_RUNTIME_PROVIDER_IDS = {
|
|
7482
7540
|
workersEdge: "workers_edge",
|
|
7483
|
-
|
|
7484
|
-
postgresFastSandbox: "postgres_fast_sandbox",
|
|
7485
|
-
postgresFastWorkers: "postgres_fast_workers",
|
|
7541
|
+
hatchet: "hatchet",
|
|
7486
7542
|
local: "local"
|
|
7487
7543
|
};
|
|
7488
7544
|
var PLAY_RUNTIME_PROVIDERS = {
|
|
@@ -7494,29 +7550,13 @@ var PLAY_RUNTIME_PROVIDERS = {
|
|
|
7494
7550
|
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
7495
7551
|
label: "Cloudflare Dynamic Workflows + Dynamic Workers + DO dedup"
|
|
7496
7552
|
},
|
|
7497
|
-
|
|
7498
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.
|
|
7499
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.
|
|
7500
|
-
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
7501
|
-
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7502
|
-
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
7503
|
-
label: "BETA: Postgres Scheduler + warm sandbox runner + DO dedup"
|
|
7504
|
-
},
|
|
7505
|
-
postgres_fast_sandbox: {
|
|
7506
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastSandbox,
|
|
7507
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
7553
|
+
hatchet: {
|
|
7554
|
+
id: PLAY_RUNTIME_PROVIDER_IDS.hatchet,
|
|
7555
|
+
scheduler: PLAY_SCHEDULER_BACKENDS.hatchet,
|
|
7508
7556
|
runner: PLAY_RUNTIME_BACKENDS.daytona,
|
|
7509
7557
|
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7510
7558
|
artifactKind: PLAY_ARTIFACT_KINDS.cjsNode20,
|
|
7511
|
-
label: "
|
|
7512
|
-
},
|
|
7513
|
-
postgres_fast_workers: {
|
|
7514
|
-
id: PLAY_RUNTIME_PROVIDER_IDS.postgresFastWorkers,
|
|
7515
|
-
scheduler: PLAY_SCHEDULER_BACKENDS.postgres,
|
|
7516
|
-
runner: PLAY_RUNTIME_BACKENDS.cloudflareWorkers,
|
|
7517
|
-
dedup: PLAY_DEDUP_BACKENDS.durableObject,
|
|
7518
|
-
artifactKind: PLAY_ARTIFACT_KINDS.esmWorkers,
|
|
7519
|
-
label: "Experimental Postgres Scheduler + Queue/DO-woken Workers + DO dedup"
|
|
7559
|
+
label: "Hatchet scheduler + one-shot Daytona runner + DO dedup"
|
|
7520
7560
|
},
|
|
7521
7561
|
local: {
|
|
7522
7562
|
id: PLAY_RUNTIME_PROVIDER_IDS.local,
|
|
@@ -8028,17 +8068,17 @@ function parsePositiveInteger2(value, flagName) {
|
|
|
8028
8068
|
}
|
|
8029
8069
|
return parsed;
|
|
8030
8070
|
}
|
|
8031
|
-
function
|
|
8071
|
+
function isRecord5(value) {
|
|
8032
8072
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
8033
8073
|
}
|
|
8034
8074
|
function stringValue(value) {
|
|
8035
8075
|
return typeof value === "string" ? value.trim() : "";
|
|
8036
8076
|
}
|
|
8037
8077
|
function extractionEntries(value) {
|
|
8038
|
-
if (Array.isArray(value)) return value.filter(
|
|
8039
|
-
if (!
|
|
8078
|
+
if (Array.isArray(value)) return value.filter(isRecord5);
|
|
8079
|
+
if (!isRecord5(value)) return [];
|
|
8040
8080
|
return Object.entries(value).map(
|
|
8041
|
-
([name, entry]) =>
|
|
8081
|
+
([name, entry]) => isRecord5(entry) ? { name, ...entry } : { name }
|
|
8042
8082
|
);
|
|
8043
8083
|
}
|
|
8044
8084
|
var PlayBootstrapError = class extends Error {
|
|
@@ -8458,7 +8498,7 @@ function readCsvSampleRows(sample) {
|
|
|
8458
8498
|
relax_column_count: true,
|
|
8459
8499
|
trim: true
|
|
8460
8500
|
});
|
|
8461
|
-
return Array.isArray(parsedRows) ? parsedRows.filter(
|
|
8501
|
+
return Array.isArray(parsedRows) ? parsedRows.filter(isRecord5) : [];
|
|
8462
8502
|
}
|
|
8463
8503
|
function readSourceCsvColumnSpecs(csvPath) {
|
|
8464
8504
|
const sample = readCsvSample(csvPath);
|
|
@@ -8491,16 +8531,16 @@ function packagedCsvPathForPlay(csvPath) {
|
|
|
8491
8531
|
return portablePath.startsWith(".") ? portablePath : `./${portablePath}`;
|
|
8492
8532
|
}
|
|
8493
8533
|
function getterNamesFromTool(tool, kind) {
|
|
8494
|
-
const usageGuidance =
|
|
8495
|
-
const resultGuidance =
|
|
8534
|
+
const usageGuidance = isRecord5(tool?.usageGuidance) ? tool.usageGuidance : {};
|
|
8535
|
+
const resultGuidance = isRecord5(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord5(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
|
|
8496
8536
|
const key = kind === "list" ? "extractedLists" : "extractedValues";
|
|
8497
8537
|
const snakeKey = kind === "list" ? "extracted_lists" : "extracted_values";
|
|
8498
8538
|
return extractionEntries(resultGuidance[key] ?? resultGuidance[snakeKey]).map((entry) => stringValue(entry.name)).filter(Boolean);
|
|
8499
8539
|
}
|
|
8500
8540
|
function targetGettersFromTool(tool) {
|
|
8501
|
-
const record =
|
|
8541
|
+
const record = isRecord5(tool) ? tool : {};
|
|
8502
8542
|
const raw = record.targetGetters ?? record.target_getters;
|
|
8503
|
-
if (!
|
|
8543
|
+
if (!isRecord5(raw)) return {};
|
|
8504
8544
|
const entries = [];
|
|
8505
8545
|
for (const [target, value] of Object.entries(raw)) {
|
|
8506
8546
|
const paths = Array.isArray(value) ? value.map((path) => typeof path === "string" ? path.trim() : "").filter(Boolean) : [];
|
|
@@ -8521,10 +8561,10 @@ function listRowCandidateKeysFromTool(tool) {
|
|
|
8521
8561
|
return [...keys].sort();
|
|
8522
8562
|
}
|
|
8523
8563
|
function inputPropertyNames(schema) {
|
|
8524
|
-
if (!
|
|
8525
|
-
if (
|
|
8564
|
+
if (!isRecord5(schema)) return [];
|
|
8565
|
+
if (isRecord5(schema.properties)) return Object.keys(schema.properties);
|
|
8526
8566
|
if (Array.isArray(schema.fields)) {
|
|
8527
|
-
return schema.fields.filter(
|
|
8567
|
+
return schema.fields.filter(isRecord5).map((field) => stringValue(field.name)).filter(Boolean);
|
|
8528
8568
|
}
|
|
8529
8569
|
return [];
|
|
8530
8570
|
}
|
|
@@ -8538,7 +8578,7 @@ function schemaFieldDetails(schema) {
|
|
|
8538
8578
|
return { required, optional };
|
|
8539
8579
|
}
|
|
8540
8580
|
function jsonSchemaTypeExpression(schema) {
|
|
8541
|
-
if (!
|
|
8581
|
+
if (!isRecord5(schema)) return "unknown";
|
|
8542
8582
|
const type = schema.type;
|
|
8543
8583
|
if (Array.isArray(type)) {
|
|
8544
8584
|
return type.map((entry) => jsonSchemaTypeExpression({ ...schema, type: entry })).join(" | ");
|
|
@@ -8568,7 +8608,7 @@ function jsonSchemaTypeExpression(schema) {
|
|
|
8568
8608
|
}
|
|
8569
8609
|
}
|
|
8570
8610
|
function objectPropertySchema(schema, property) {
|
|
8571
|
-
return
|
|
8611
|
+
return isRecord5(schema) && isRecord5(schema.properties) ? schema.properties[property] : null;
|
|
8572
8612
|
}
|
|
8573
8613
|
function playOutputHasField(schema, field) {
|
|
8574
8614
|
return objectPropertySchema(schema, field) != null;
|
|
@@ -8744,14 +8784,14 @@ ${indent2.slice(2)}}`;
|
|
|
8744
8784
|
}
|
|
8745
8785
|
function requiredPlayInputFields(play) {
|
|
8746
8786
|
const schema = play?.inputSchema;
|
|
8747
|
-
if (!
|
|
8787
|
+
if (!isRecord5(schema)) return [];
|
|
8748
8788
|
if (Array.isArray(schema.required)) {
|
|
8749
8789
|
return schema.required.filter(
|
|
8750
8790
|
(value) => typeof value === "string"
|
|
8751
8791
|
);
|
|
8752
8792
|
}
|
|
8753
8793
|
if (Array.isArray(schema.fields)) {
|
|
8754
|
-
return schema.fields.filter(
|
|
8794
|
+
return schema.fields.filter(isRecord5).filter(
|
|
8755
8795
|
(field) => field.required === true && typeof field.name === "string"
|
|
8756
8796
|
).map((field) => String(field.name));
|
|
8757
8797
|
}
|
|
@@ -8932,7 +8972,7 @@ function validateBootstrapRoutes(input2) {
|
|
|
8932
8972
|
}
|
|
8933
8973
|
}
|
|
8934
8974
|
function staticPipelineSubsteps(pipeline) {
|
|
8935
|
-
if (!
|
|
8975
|
+
if (!isRecord5(pipeline)) return [];
|
|
8936
8976
|
return [
|
|
8937
8977
|
...extractionEntries(pipeline.stages),
|
|
8938
8978
|
...extractionEntries(pipeline.substeps)
|
|
@@ -8940,7 +8980,7 @@ function staticPipelineSubsteps(pipeline) {
|
|
|
8940
8980
|
}
|
|
8941
8981
|
function playUsesMapBackedRuntime(play) {
|
|
8942
8982
|
const pipeline = play?.staticPipeline;
|
|
8943
|
-
if (!
|
|
8983
|
+
if (!isRecord5(pipeline)) return false;
|
|
8944
8984
|
if (stringValue(pipeline.tableNamespace)) return true;
|
|
8945
8985
|
return staticPipelineSubsteps(pipeline).some((substep) => {
|
|
8946
8986
|
if (stringValue(substep.type) === "map") return true;
|
|
@@ -8949,7 +8989,7 @@ function playUsesMapBackedRuntime(play) {
|
|
|
8949
8989
|
aliases: [],
|
|
8950
8990
|
runCommand: "",
|
|
8951
8991
|
examples: [],
|
|
8952
|
-
staticPipeline:
|
|
8992
|
+
staticPipeline: isRecord5(substep.pipeline) ? substep.pipeline : null
|
|
8953
8993
|
});
|
|
8954
8994
|
});
|
|
8955
8995
|
}
|
|
@@ -10511,10 +10551,12 @@ function playStatusValue(value) {
|
|
|
10511
10551
|
return value === "queued" || value === "running" || value === "waiting" || value === "completed" || value === "failed" || value === "cancelled" ? value : null;
|
|
10512
10552
|
}
|
|
10513
10553
|
function getRunRecordFromPackage(value) {
|
|
10514
|
-
|
|
10554
|
+
const nestedPackage = value.package;
|
|
10555
|
+
const playRunPackage = isPlayRunPackageValue(value) ? value : isPlayRunPackageValue(nestedPackage) ? nestedPackage : null;
|
|
10556
|
+
if (!playRunPackage) {
|
|
10515
10557
|
return null;
|
|
10516
10558
|
}
|
|
10517
|
-
const run =
|
|
10559
|
+
const run = playRunPackage.run;
|
|
10518
10560
|
return run && typeof run === "object" && !Array.isArray(run) ? run : null;
|
|
10519
10561
|
}
|
|
10520
10562
|
function getRunIdFromLiveEvent(event) {
|
|
@@ -10544,10 +10586,12 @@ function getFinalStatusFromLiveEvent(event) {
|
|
|
10544
10586
|
return null;
|
|
10545
10587
|
}
|
|
10546
10588
|
const runId = typeof payload.runId === "string" ? payload.runId : typeof packageRun?.id === "string" ? packageRun.id : "";
|
|
10589
|
+
const error = typeof payload.error === "string" ? payload.error : typeof packageRun?.error === "string" ? packageRun.error : void 0;
|
|
10547
10590
|
return {
|
|
10548
10591
|
...payload,
|
|
10549
10592
|
runId,
|
|
10550
|
-
status
|
|
10593
|
+
status,
|
|
10594
|
+
...error ? { error } : {}
|
|
10551
10595
|
};
|
|
10552
10596
|
}
|
|
10553
10597
|
function getLogLinesFromLiveEvent(event) {
|
|
@@ -11866,7 +11910,16 @@ function withTerminalPlayIdentity(status, playName) {
|
|
|
11866
11910
|
function compactPlayStatus(status) {
|
|
11867
11911
|
const packaged = getPlayRunPackage(status);
|
|
11868
11912
|
if (packaged) {
|
|
11869
|
-
|
|
11913
|
+
const error2 = selectRunErrorForDisplay(status) ?? (typeof status.error === "string" ? String(status.error) : null);
|
|
11914
|
+
if (!error2) {
|
|
11915
|
+
return packaged;
|
|
11916
|
+
}
|
|
11917
|
+
const run = packaged.run && typeof packaged.run === "object" ? packaged.run : null;
|
|
11918
|
+
return {
|
|
11919
|
+
...packaged,
|
|
11920
|
+
error: error2,
|
|
11921
|
+
...run ? { run: { ...run, error: error2 } } : {}
|
|
11922
|
+
};
|
|
11870
11923
|
}
|
|
11871
11924
|
const rowsInfo = extractCanonicalRowsInfo(status);
|
|
11872
11925
|
const result = status && typeof status === "object" ? status.result : null;
|
|
@@ -12206,10 +12259,17 @@ function writePlayResult(status, jsonOutput, options) {
|
|
|
12206
12259
|
` }
|
|
12207
12260
|
);
|
|
12208
12261
|
}
|
|
12209
|
-
function
|
|
12210
|
-
if (!pkg) return
|
|
12211
|
-
const steps = pkg.steps;
|
|
12212
|
-
|
|
12262
|
+
function playRunPackageTextLedgerIncomplete(pkg) {
|
|
12263
|
+
if (!pkg) return true;
|
|
12264
|
+
const steps = readRecordArray(pkg.steps);
|
|
12265
|
+
if (steps.length === 0) return true;
|
|
12266
|
+
for (const step of steps) {
|
|
12267
|
+
if (step.kind !== "dataset" || step.status !== "completed") continue;
|
|
12268
|
+
const output2 = readRecord(step.output);
|
|
12269
|
+
if (!output2 || typeof output2.rowCount !== "number") return true;
|
|
12270
|
+
if (!readRecord(output2.summary)) return true;
|
|
12271
|
+
}
|
|
12272
|
+
return false;
|
|
12213
12273
|
}
|
|
12214
12274
|
async function resolvePlayRunOutputStatus(input2) {
|
|
12215
12275
|
const runId = input2.status.runId;
|
|
@@ -12218,7 +12278,7 @@ async function resolvePlayRunOutputStatus(input2) {
|
|
|
12218
12278
|
}
|
|
12219
12279
|
const streamedPackage = getPlayRunPackage(input2.status);
|
|
12220
12280
|
const refreshForFullJson = input2.fullJson && streamedPackage !== null;
|
|
12221
|
-
const streamedTextPackageIncomplete = !input2.jsonOutput && input2.status.status === "completed" &&
|
|
12281
|
+
const streamedTextPackageIncomplete = !input2.jsonOutput && input2.status.status === "completed" && playRunPackageTextLedgerIncomplete(streamedPackage);
|
|
12222
12282
|
if (!refreshForFullJson && !streamedTextPackageIncomplete) {
|
|
12223
12283
|
return input2.status;
|
|
12224
12284
|
}
|
|
@@ -12226,7 +12286,7 @@ async function resolvePlayRunOutputStatus(input2) {
|
|
|
12226
12286
|
billing: false,
|
|
12227
12287
|
full: input2.fullJson
|
|
12228
12288
|
});
|
|
12229
|
-
for (let attempt = 0; attempt < 3 && streamedTextPackageIncomplete && refreshedStatus.status === "completed" &&
|
|
12289
|
+
for (let attempt = 0; attempt < 3 && streamedTextPackageIncomplete && refreshedStatus.status === "completed" && playRunPackageTextLedgerIncomplete(getPlayRunPackage(refreshedStatus)); attempt += 1) {
|
|
12230
12290
|
await sleep5(250);
|
|
12231
12291
|
refreshedStatus = await input2.client.getPlayStatus(runId, {
|
|
12232
12292
|
billing: false,
|
|
@@ -12535,7 +12595,7 @@ function extractPlayValidationErrors(value) {
|
|
|
12535
12595
|
if (value instanceof DeeplineError) {
|
|
12536
12596
|
return extractPlayValidationErrors(value.details);
|
|
12537
12597
|
}
|
|
12538
|
-
if (!
|
|
12598
|
+
if (!isRecord6(value)) {
|
|
12539
12599
|
return [];
|
|
12540
12600
|
}
|
|
12541
12601
|
const directErrors = stringArrayField(value, "errors");
|
|
@@ -12748,7 +12808,7 @@ function writeStartedPlayRun(input2) {
|
|
|
12748
12808
|
);
|
|
12749
12809
|
}
|
|
12750
12810
|
function parsePlayRunOptions(args) {
|
|
12751
|
-
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;
|
|
12811
|
+
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.";
|
|
12752
12812
|
let filePath = null;
|
|
12753
12813
|
let playName = null;
|
|
12754
12814
|
let input2 = null;
|
|
@@ -12893,7 +12953,7 @@ function shouldUseLocalOnlyPlayCheck() {
|
|
|
12893
12953
|
const value = process.env.DEEPLINE_PLAY_CHECK_LOCAL_ONLY?.trim().toLowerCase();
|
|
12894
12954
|
return value === "1" || value === "true" || value === "yes" || value === "on";
|
|
12895
12955
|
}
|
|
12896
|
-
function
|
|
12956
|
+
function isRecord6(value) {
|
|
12897
12957
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
12898
12958
|
}
|
|
12899
12959
|
function stringValue2(value) {
|
|
@@ -12903,14 +12963,14 @@ function asArray(value) {
|
|
|
12903
12963
|
return Array.isArray(value) ? value : [];
|
|
12904
12964
|
}
|
|
12905
12965
|
function extractionEntries2(value) {
|
|
12906
|
-
if (Array.isArray(value)) return value.filter(
|
|
12907
|
-
if (!
|
|
12966
|
+
if (Array.isArray(value)) return value.filter(isRecord6);
|
|
12967
|
+
if (!isRecord6(value)) return [];
|
|
12908
12968
|
return Object.entries(value).map(
|
|
12909
|
-
([name, entry]) =>
|
|
12969
|
+
([name, entry]) => isRecord6(entry) ? { name, ...entry } : { name }
|
|
12910
12970
|
);
|
|
12911
12971
|
}
|
|
12912
12972
|
function firstRawPath(entry) {
|
|
12913
|
-
const details =
|
|
12973
|
+
const details = isRecord6(entry.details) ? entry.details : {};
|
|
12914
12974
|
const paths = [
|
|
12915
12975
|
...asArray(details.rawToolOutputPaths),
|
|
12916
12976
|
...asArray(details.raw_tool_output_paths),
|
|
@@ -12928,12 +12988,12 @@ function checkHintRawPath(value) {
|
|
|
12928
12988
|
function collectStaticPipelineToolIds(staticPipeline) {
|
|
12929
12989
|
const seen = /* @__PURE__ */ new Set();
|
|
12930
12990
|
const visitPipeline = (pipeline) => {
|
|
12931
|
-
if (!
|
|
12991
|
+
if (!isRecord6(pipeline)) return;
|
|
12932
12992
|
for (const step of [
|
|
12933
12993
|
...asArray(pipeline.stages),
|
|
12934
12994
|
...asArray(pipeline.substeps)
|
|
12935
12995
|
]) {
|
|
12936
|
-
if (!
|
|
12996
|
+
if (!isRecord6(step)) continue;
|
|
12937
12997
|
if (step.type === "tool") {
|
|
12938
12998
|
const toolId = stringValue2(step.toolId) || stringValue2(step.tool);
|
|
12939
12999
|
if (toolId) seen.add(toolId);
|
|
@@ -12947,9 +13007,9 @@ function collectStaticPipelineToolIds(staticPipeline) {
|
|
|
12947
13007
|
return [...seen].sort();
|
|
12948
13008
|
}
|
|
12949
13009
|
function toolGetterHintFromMetadata(toolId, tool) {
|
|
12950
|
-
const usageGuidance =
|
|
12951
|
-
const resultGuidance =
|
|
12952
|
-
const toolResponse =
|
|
13010
|
+
const usageGuidance = isRecord6(tool.usageGuidance) ? tool.usageGuidance : {};
|
|
13011
|
+
const resultGuidance = isRecord6(usageGuidance.toolExecutionResult) ? usageGuidance.toolExecutionResult : isRecord6(usageGuidance.tool_execution_result) ? usageGuidance.tool_execution_result : {};
|
|
13012
|
+
const toolResponse = isRecord6(resultGuidance.toolResponse) ? resultGuidance.toolResponse : isRecord6(resultGuidance.tool_response) ? resultGuidance.tool_response : {};
|
|
12953
13013
|
const lists = extractionEntries2(
|
|
12954
13014
|
resultGuidance.extractedLists ?? resultGuidance.extracted_lists
|
|
12955
13015
|
).map((entry) => ({
|
|
@@ -14274,6 +14334,40 @@ async function handlePlayDescribe(args) {
|
|
|
14274
14334
|
);
|
|
14275
14335
|
return 2;
|
|
14276
14336
|
}
|
|
14337
|
+
if (isFileTarget(playName) || looksLikeFilePath(playName)) {
|
|
14338
|
+
const message = "Local play files can be checked and run, but describe only supports saved/prebuilt play references.";
|
|
14339
|
+
const definedName = isFileTarget(playName) ? (() => {
|
|
14340
|
+
try {
|
|
14341
|
+
return extractPlayName(
|
|
14342
|
+
(0, import_node_fs10.readFileSync)((0, import_node_path12.resolve)(playName), "utf-8"),
|
|
14343
|
+
playName
|
|
14344
|
+
);
|
|
14345
|
+
} catch {
|
|
14346
|
+
return null;
|
|
14347
|
+
}
|
|
14348
|
+
})() : null;
|
|
14349
|
+
const next = [
|
|
14350
|
+
`deepline plays check ${playName}`,
|
|
14351
|
+
...definedName ? [`deepline plays describe <workspace>/${definedName}`] : []
|
|
14352
|
+
];
|
|
14353
|
+
if (argsWantJson(args)) {
|
|
14354
|
+
process.stdout.write(
|
|
14355
|
+
`${JSON.stringify({
|
|
14356
|
+
ok: false,
|
|
14357
|
+
error: { message },
|
|
14358
|
+
next
|
|
14359
|
+
})}
|
|
14360
|
+
`
|
|
14361
|
+
);
|
|
14362
|
+
} else {
|
|
14363
|
+
console.error(message);
|
|
14364
|
+
console.error(`Try: ${next[0]}`);
|
|
14365
|
+
if (next[1]) {
|
|
14366
|
+
console.error(`Or after publishing/running: ${next[1]}`);
|
|
14367
|
+
}
|
|
14368
|
+
}
|
|
14369
|
+
return 2;
|
|
14370
|
+
}
|
|
14277
14371
|
const client2 = new DeeplineClient();
|
|
14278
14372
|
await assertCanonicalNamedPlayReference(client2, playName);
|
|
14279
14373
|
const play = await client2.describePlay(
|
|
@@ -15355,6 +15449,18 @@ function getterFromLegacyExtractJs(extractJs, fallbackAlias) {
|
|
|
15355
15449
|
return null;
|
|
15356
15450
|
}
|
|
15357
15451
|
|
|
15452
|
+
// src/cli/enrich-compat-adapter.ts
|
|
15453
|
+
var ENRICH_COMPAT_DEFAULT_PLAY_NAME = "deepline-enrich-v1-compat";
|
|
15454
|
+
var ENRICH_COMPAT_DEFAULT_MAP_NAME = "deepline_enrich_rows";
|
|
15455
|
+
var ENRICH_COMPAT_METADATA_CELL_POLICY_SOURCE = "{ recompute: true }";
|
|
15456
|
+
function buildEnrichCompatibilityPlan(options = {}) {
|
|
15457
|
+
return {
|
|
15458
|
+
playName: options.playName?.trim() || ENRICH_COMPAT_DEFAULT_PLAY_NAME,
|
|
15459
|
+
mapName: options.mapName?.trim() || ENRICH_COMPAT_DEFAULT_MAP_NAME,
|
|
15460
|
+
metadataCellPolicySource: ENRICH_COMPAT_METADATA_CELL_POLICY_SOURCE
|
|
15461
|
+
};
|
|
15462
|
+
}
|
|
15463
|
+
|
|
15358
15464
|
// src/cli/user-code-safety.ts
|
|
15359
15465
|
var FORBIDDEN = [
|
|
15360
15466
|
// Non-deterministic — breaks replay.
|
|
@@ -15526,12 +15632,16 @@ function renderPlayStep(command, options) {
|
|
|
15526
15632
|
const runIfJs = command.run_if_js ? `(row) => { const input = row; const context = row;
|
|
15527
15633
|
${indent(renderJavascriptBody(command.run_if_js), 6)}
|
|
15528
15634
|
}` : "null";
|
|
15529
|
-
const runIfLines = command.run_if_js ? [
|
|
15635
|
+
const runIfLines = command.run_if_js ? [
|
|
15636
|
+
` const __dlRunIf = ${runIfJs};`,
|
|
15637
|
+
` if (!__dlRunIf(templateRow)) return null;`
|
|
15638
|
+
] : [];
|
|
15530
15639
|
return [
|
|
15531
15640
|
`async (row, stepCtx) => {`,
|
|
15532
15641
|
...options.precheck ? [` if (${options.precheck}) return null;`] : [],
|
|
15642
|
+
` const templateRow = __dlPrepareEnrichRow(row, [${alias}]);`,
|
|
15533
15643
|
...runIfLines,
|
|
15534
|
-
` const payload = __dlTemplate(${payload},
|
|
15644
|
+
` const payload = __dlTemplate(${payload}, templateRow) as Record<string, unknown>;`,
|
|
15535
15645
|
` const result = await stepCtx.runPlay(${callId}, ${playRef}, payload, {`,
|
|
15536
15646
|
` description: ${stringLiteral(command.description ?? command.alias)}`,
|
|
15537
15647
|
` });`,
|
|
@@ -15632,7 +15742,7 @@ function collectGeneratedAliases(commands) {
|
|
|
15632
15742
|
}
|
|
15633
15743
|
return aliases;
|
|
15634
15744
|
}
|
|
15635
|
-
function renderMetadataColumnStep(config) {
|
|
15745
|
+
function renderMetadataColumnStep(config, policySource) {
|
|
15636
15746
|
const columns = collectMetadataColumns(config.commands);
|
|
15637
15747
|
if (Object.keys(columns).length === 0) {
|
|
15638
15748
|
return "";
|
|
@@ -15640,7 +15750,7 @@ function renderMetadataColumnStep(config) {
|
|
|
15640
15750
|
return [
|
|
15641
15751
|
` .withColumn('_metadata',`,
|
|
15642
15752
|
` (row) => __dlMergeMetadata(__dlMetadataFromRow(row), ${stableJson({ columns })}),`,
|
|
15643
|
-
` {
|
|
15753
|
+
` ${policySource},`,
|
|
15644
15754
|
` )`
|
|
15645
15755
|
].join("\n");
|
|
15646
15756
|
}
|
|
@@ -15694,8 +15804,8 @@ function renderWaterfallColumns(command, forceAliases, inlineRunJavascript, idio
|
|
|
15694
15804
|
];
|
|
15695
15805
|
}
|
|
15696
15806
|
function compileEnrichConfigToPlaySource(config, options = {}) {
|
|
15697
|
-
const
|
|
15698
|
-
const
|
|
15807
|
+
const compatibility = buildEnrichCompatibilityPlan(options);
|
|
15808
|
+
const { playName, mapName } = compatibility;
|
|
15699
15809
|
const inlineRunJavascript = options.inlineRunJavascript ?? false;
|
|
15700
15810
|
const idiomaticGetters = options.idiomaticGetters ?? false;
|
|
15701
15811
|
const forceAliases = new Set(
|
|
@@ -15731,15 +15841,25 @@ function compileEnrichConfigToPlaySource(config, options = {}) {
|
|
|
15731
15841
|
);
|
|
15732
15842
|
});
|
|
15733
15843
|
const columnStepSource = columnSteps.length > 0 ? columnSteps.join("\n") : ` .withColumn('noop', () => null)`;
|
|
15734
|
-
const metadataColumnSource = renderMetadataColumnStep(
|
|
15844
|
+
const metadataColumnSource = renderMetadataColumnStep(
|
|
15845
|
+
config,
|
|
15846
|
+
compatibility.metadataCellPolicySource
|
|
15847
|
+
);
|
|
15735
15848
|
const generatedAliases = collectGeneratedAliases(config.commands);
|
|
15736
15849
|
const body = [
|
|
15737
15850
|
`export default definePlay(${stringLiteral(playName)}, async (ctx, input: EnrichInput) => {`,
|
|
15738
15851
|
` const sourceRows = await ctx.csv<Record<string, unknown>>(input.file);`,
|
|
15739
15852
|
` const rowStart = __dlNonNegativeInteger(input.rowStart, 0);`,
|
|
15740
15853
|
` const rowEndExclusive = Number.isFinite(input.rowEnd) ? Math.max(rowStart, __dlWholeNumber(input.rowEnd, rowStart) + 1) : undefined;`,
|
|
15741
|
-
` const
|
|
15742
|
-
`
|
|
15854
|
+
` const rows: Array<Record<string, unknown>> = [];`,
|
|
15855
|
+
` let sourceRowIndex = 0;`,
|
|
15856
|
+
` for await (const row of sourceRows) {`,
|
|
15857
|
+
` if (rowEndExclusive !== undefined && sourceRowIndex >= rowEndExclusive) break;`,
|
|
15858
|
+
` if (sourceRowIndex >= rowStart) {`,
|
|
15859
|
+
` rows.push(__dlPrepareEnrichRow(row, ${stableJson(generatedAliases)}));`,
|
|
15860
|
+
` }`,
|
|
15861
|
+
` sourceRowIndex += 1;`,
|
|
15862
|
+
` }`,
|
|
15743
15863
|
` const enriched = await ctx`,
|
|
15744
15864
|
` .dataset(${stringLiteral(mapName)}, rows)`,
|
|
15745
15865
|
columnStepSource,
|
|
@@ -15870,17 +15990,55 @@ function helperSource() {
|
|
|
15870
15990
|
` return parts;`,
|
|
15871
15991
|
`}`,
|
|
15872
15992
|
``,
|
|
15993
|
+
`function __dlNormalizeHeader(value: string): string {`,
|
|
15994
|
+
` return value.trim().replace(/([a-z0-9])([A-Z])/g, '$1_$2').toLowerCase().replace(/[^a-z0-9]+/g, '_').replace(/^_+|_+$/g, '');`,
|
|
15995
|
+
`}`,
|
|
15996
|
+
``,
|
|
15997
|
+
`function __dlOwnStringKeys(record: Record<string, unknown>): string[] {`,
|
|
15998
|
+
` return Object.keys(record);`,
|
|
15999
|
+
`}`,
|
|
16000
|
+
``,
|
|
16001
|
+
`function __dlReadOwnField(record: Record<string, unknown>, key: string): unknown {`,
|
|
16002
|
+
` return record[key];`,
|
|
16003
|
+
`}`,
|
|
16004
|
+
``,
|
|
16005
|
+
`function __dlGetNormalizedKey(record: Record<string, unknown>, part: string): string | null {`,
|
|
16006
|
+
` const normalized = __dlNormalizeHeader(part);`,
|
|
16007
|
+
` for (const key of __dlOwnStringKeys(record)) {`,
|
|
16008
|
+
` if (__dlNormalizeHeader(key) === normalized) return key;`,
|
|
16009
|
+
` }`,
|
|
16010
|
+
` return null;`,
|
|
16011
|
+
`}`,
|
|
16012
|
+
``,
|
|
16013
|
+
`function __dlGetRecordField(record: Record<string, unknown>, part: string): { found: boolean; value: unknown } {`,
|
|
16014
|
+
` if (part in record) return { found: true, value: record[part] };`,
|
|
16015
|
+
` const normalizedKey = __dlGetNormalizedKey(record, part);`,
|
|
16016
|
+
` if (normalizedKey) return { found: true, value: __dlReadOwnField(record, normalizedKey) };`,
|
|
16017
|
+
` const projectedValues = record.__deeplineCsvProjectedValues;`,
|
|
16018
|
+
` if (projectedValues && typeof projectedValues === 'object' && !Array.isArray(projectedValues)) {`,
|
|
16019
|
+
` const projectedRecord = projectedValues as Record<string, unknown>;`,
|
|
16020
|
+
` if (part in projectedRecord) return { found: true, value: projectedRecord[part] };`,
|
|
16021
|
+
` const projectedKey = __dlGetNormalizedKey(projectedRecord, part);`,
|
|
16022
|
+
` if (projectedKey) return { found: true, value: __dlReadOwnField(projectedRecord, projectedKey) };`,
|
|
16023
|
+
` }`,
|
|
16024
|
+
` const data = record.data;`,
|
|
16025
|
+
` if (data && typeof data === 'object' && !Array.isArray(data)) {`,
|
|
16026
|
+
` const dataRecord = data as Record<string, unknown>;`,
|
|
16027
|
+
` if (part in dataRecord) return { found: true, value: dataRecord[part] };`,
|
|
16028
|
+
` const dataKey = __dlGetNormalizedKey(dataRecord, part);`,
|
|
16029
|
+
` if (dataKey) return { found: true, value: __dlReadOwnField(dataRecord, dataKey) };`,
|
|
16030
|
+
` }`,
|
|
16031
|
+
` return { found: false, value: undefined };`,
|
|
16032
|
+
`}`,
|
|
16033
|
+
``,
|
|
15873
16034
|
`function __dlGetByPath(root: unknown, path: string): unknown {`,
|
|
15874
16035
|
` let cursor = root;`,
|
|
15875
16036
|
` for (const part of __dlPathParts(path)) {`,
|
|
15876
16037
|
` if (!cursor || typeof cursor !== 'object') return undefined;`,
|
|
15877
16038
|
` const record = cursor as Record<string, unknown>;`,
|
|
15878
|
-
`
|
|
15879
|
-
`
|
|
15880
|
-
`
|
|
15881
|
-
` }`,
|
|
15882
|
-
` const data = record.data;`,
|
|
15883
|
-
` cursor = data && typeof data === 'object' ? (data as Record<string, unknown>)[part] : undefined;`,
|
|
16039
|
+
` const field = __dlGetRecordField(record, part);`,
|
|
16040
|
+
` if (!field.found) return undefined;`,
|
|
16041
|
+
` cursor = field.value;`,
|
|
15884
16042
|
` }`,
|
|
15885
16043
|
` return cursor;`,
|
|
15886
16044
|
`}`,
|
|
@@ -15945,6 +16103,30 @@ function helperSource() {
|
|
|
15945
16103
|
` return next ?? row;`,
|
|
15946
16104
|
`}`,
|
|
15947
16105
|
``,
|
|
16106
|
+
`function __dlTemplateContext(row: Record<string, unknown>): Record<string, unknown> {`,
|
|
16107
|
+
` const context: Record<string, unknown> = {};`,
|
|
16108
|
+
` const projectedValues = row.__deeplineCsvProjectedValues;`,
|
|
16109
|
+
` if (__dlRecord(projectedValues)) {`,
|
|
16110
|
+
` for (const [key, value] of Object.entries(projectedValues)) context[key] = value;`,
|
|
16111
|
+
` }`,
|
|
16112
|
+
` for (const [key, value] of Object.entries(row)) {`,
|
|
16113
|
+
` if (key.startsWith('__deepline')) continue;`,
|
|
16114
|
+
` context[key] = value;`,
|
|
16115
|
+
` }`,
|
|
16116
|
+
` return context;`,
|
|
16117
|
+
`}`,
|
|
16118
|
+
``,
|
|
16119
|
+
`function __dlPrepareEnrichRow(row: Record<string, unknown>, aliases: string[]): Record<string, unknown> {`,
|
|
16120
|
+
` const cleaned = __dlStripErroredGeneratedColumns(row, aliases);`,
|
|
16121
|
+
` const templateContext = __dlTemplateContext(cleaned);`,
|
|
16122
|
+
` return {`,
|
|
16123
|
+
` ...templateContext,`,
|
|
16124
|
+
` ...cleaned,`,
|
|
16125
|
+
` __deeplineCsvProjectedFields: Object.keys(templateContext),`,
|
|
16126
|
+
` __deeplineCsvProjectedValues: templateContext,`,
|
|
16127
|
+
` };`,
|
|
16128
|
+
`}`,
|
|
16129
|
+
``,
|
|
15948
16130
|
`function __dlRawToolOutput(result: unknown): unknown {`,
|
|
15949
16131
|
` if (!result || typeof result !== 'object') return result;`,
|
|
15950
16132
|
` const record = result as Record<string, unknown>;`,
|
|
@@ -16982,7 +17164,7 @@ async function resolveWatchedGeneratedPlayStatus(input2) {
|
|
|
16982
17164
|
}
|
|
16983
17165
|
return input2.client.runs.get(runId, { full: true });
|
|
16984
17166
|
}
|
|
16985
|
-
function
|
|
17167
|
+
function isRecord7(value) {
|
|
16986
17168
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
16987
17169
|
}
|
|
16988
17170
|
async function captureStdout(run, options = {}) {
|
|
@@ -17030,12 +17212,12 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
17030
17212
|
if (!rowsInfo) {
|
|
17031
17213
|
throw new Error("The generated play did not return row-shaped output.");
|
|
17032
17214
|
}
|
|
17033
|
-
if (
|
|
17215
|
+
if (options?.client) {
|
|
17034
17216
|
rowsInfo = await fetchBackingRowsForCsvExport({
|
|
17035
17217
|
client: options.client,
|
|
17036
17218
|
status,
|
|
17037
17219
|
rowsInfo
|
|
17038
|
-
}) ?? rowsInfo;
|
|
17220
|
+
}).catch(() => null) ?? rowsInfo;
|
|
17039
17221
|
}
|
|
17040
17222
|
assertCompleteRowsForCsvExport(rowsInfo, status, outputPath);
|
|
17041
17223
|
const merged = mergeRowsForCsvExport(rowsInfo.rows, options);
|
|
@@ -17051,10 +17233,14 @@ async function writeOutputCsv(outputPath, status, options) {
|
|
|
17051
17233
|
csvStringFromRows(merged.rows, columns),
|
|
17052
17234
|
"utf8"
|
|
17053
17235
|
);
|
|
17236
|
+
const sourceCsvRows = options?.sourceCsvPath ? readCsvRows(options.sourceCsvPath).length : null;
|
|
17054
17237
|
return {
|
|
17238
|
+
sourceCsvRows,
|
|
17239
|
+
selectedRows: rowsInfo.totalRows,
|
|
17240
|
+
enrichedRows: rowsInfo.rows.length,
|
|
17055
17241
|
rows: merged.rows.length,
|
|
17056
17242
|
path: (0, import_node_path13.resolve)(outputPath),
|
|
17057
|
-
|
|
17243
|
+
enrichedDataRows: rowsInfo.rows
|
|
17058
17244
|
};
|
|
17059
17245
|
}
|
|
17060
17246
|
function recordField(value, key) {
|
|
@@ -17135,12 +17321,12 @@ function collectHardFailureAliases(config) {
|
|
|
17135
17321
|
}
|
|
17136
17322
|
function cellFailureError(value) {
|
|
17137
17323
|
const parsed = parseMaybeJsonObject(value);
|
|
17138
|
-
if (!
|
|
17324
|
+
if (!isRecord7(parsed)) {
|
|
17139
17325
|
return null;
|
|
17140
17326
|
}
|
|
17141
17327
|
const status = typeof parsed.status === "string" ? parsed.status.trim().toLowerCase() : "";
|
|
17142
17328
|
const directError = typeof parsed.error === "string" ? parsed.error.trim() : typeof parsed.last_error === "string" ? parsed.last_error.trim() : "";
|
|
17143
|
-
const result =
|
|
17329
|
+
const result = isRecord7(parsed.result) ? parsed.result : null;
|
|
17144
17330
|
const resultError = typeof result?.error === "string" ? result.error.trim() : typeof result?.message === "string" ? result.message.trim() : "";
|
|
17145
17331
|
if (!directError && !resultError && status !== "error" && status !== "failed") {
|
|
17146
17332
|
return null;
|
|
@@ -17206,6 +17392,136 @@ function collectEnrichFailureJobs(input2) {
|
|
|
17206
17392
|
});
|
|
17207
17393
|
return jobs;
|
|
17208
17394
|
}
|
|
17395
|
+
function parseExecutionCount(value) {
|
|
17396
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
17397
|
+
return Math.max(0, Math.trunc(value));
|
|
17398
|
+
}
|
|
17399
|
+
if (typeof value !== "string") {
|
|
17400
|
+
return null;
|
|
17401
|
+
}
|
|
17402
|
+
const match = value.trim().match(/^(\d+)\s*\//);
|
|
17403
|
+
return match?.[1] ? Number.parseInt(match[1], 10) : null;
|
|
17404
|
+
}
|
|
17405
|
+
function executionSummaryText(count, total) {
|
|
17406
|
+
const percent = total > 0 ? Math.round(count / total * 100) : 0;
|
|
17407
|
+
return `${count}/${total} (${percent}%)`;
|
|
17408
|
+
}
|
|
17409
|
+
function collectColumnStats(status) {
|
|
17410
|
+
const summaries = [];
|
|
17411
|
+
const visit = (value) => {
|
|
17412
|
+
if (Array.isArray(value)) {
|
|
17413
|
+
value.forEach(visit);
|
|
17414
|
+
return;
|
|
17415
|
+
}
|
|
17416
|
+
if (!isRecord7(value)) {
|
|
17417
|
+
return;
|
|
17418
|
+
}
|
|
17419
|
+
if (isRecord7(value.columnStats)) {
|
|
17420
|
+
summaries.push(value.columnStats);
|
|
17421
|
+
}
|
|
17422
|
+
Object.values(value).forEach(visit);
|
|
17423
|
+
};
|
|
17424
|
+
visit(status);
|
|
17425
|
+
return summaries;
|
|
17426
|
+
}
|
|
17427
|
+
function firstAliasExecutionCounts(input2) {
|
|
17428
|
+
const aliases = collectConfigScalarAliasOrder(input2.config);
|
|
17429
|
+
const summaries = collectColumnStats(input2.status);
|
|
17430
|
+
for (const alias of aliases) {
|
|
17431
|
+
const stat4 = summaries.map((summary) => summary[alias]).find(isRecord7);
|
|
17432
|
+
if (!stat4) continue;
|
|
17433
|
+
if (input2.forceAliases.has(normalizeAlias2(alias))) {
|
|
17434
|
+
return { executed: input2.selectedRows, reused: 0 };
|
|
17435
|
+
}
|
|
17436
|
+
const execution = isRecord7(stat4.execution) ? stat4.execution : null;
|
|
17437
|
+
if (!execution) continue;
|
|
17438
|
+
return {
|
|
17439
|
+
executed: parseExecutionCount(execution["completed:executed"]),
|
|
17440
|
+
reused: parseExecutionCount(execution["completed:reused"])
|
|
17441
|
+
};
|
|
17442
|
+
}
|
|
17443
|
+
return { executed: null, reused: null };
|
|
17444
|
+
}
|
|
17445
|
+
function rewriteEnrichJsonStatus(input2) {
|
|
17446
|
+
const selectedRows = input2.output?.selectedRows ?? extractCanonicalRowsInfo(input2.status)?.totalRows ?? 0;
|
|
17447
|
+
const failedRows = new Set(
|
|
17448
|
+
input2.failureReport?.jobs.map((job) => job.row_id) ?? []
|
|
17449
|
+
).size;
|
|
17450
|
+
const executionCounts = firstAliasExecutionCounts({
|
|
17451
|
+
status: input2.status,
|
|
17452
|
+
config: input2.config,
|
|
17453
|
+
forceAliases: input2.forceAliases,
|
|
17454
|
+
selectedRows
|
|
17455
|
+
});
|
|
17456
|
+
const forcedAliases = new Set(
|
|
17457
|
+
collectConfigScalarAliasOrder(input2.config).filter((alias) => input2.forceAliases.has(normalizeAlias2(alias))).map((alias) => alias)
|
|
17458
|
+
);
|
|
17459
|
+
const rewrite = (value) => {
|
|
17460
|
+
if (Array.isArray(value)) {
|
|
17461
|
+
return value.map(rewrite);
|
|
17462
|
+
}
|
|
17463
|
+
if (!isRecord7(value)) {
|
|
17464
|
+
return value;
|
|
17465
|
+
}
|
|
17466
|
+
const next = {};
|
|
17467
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
17468
|
+
next[key] = rewrite(entry);
|
|
17469
|
+
}
|
|
17470
|
+
if (isRecord7(next.progress)) {
|
|
17471
|
+
next.progress = {
|
|
17472
|
+
...next.progress,
|
|
17473
|
+
...selectedRows > 0 ? { total: selectedRows } : {},
|
|
17474
|
+
...executionCounts.executed !== null ? { executed: executionCounts.executed } : {},
|
|
17475
|
+
...executionCounts.reused !== null ? { reused: executionCounts.reused } : {},
|
|
17476
|
+
...failedRows > 0 ? { failed: failedRows, pending: 0 } : {}
|
|
17477
|
+
};
|
|
17478
|
+
}
|
|
17479
|
+
if (isRecord7(next.summary)) {
|
|
17480
|
+
const rowCounts = isRecord7(next.summary.rowCounts) ? next.summary.rowCounts : null;
|
|
17481
|
+
if (failedRows > 0) {
|
|
17482
|
+
next.summary = {
|
|
17483
|
+
...next.summary,
|
|
17484
|
+
rowCounts: {
|
|
17485
|
+
...rowCounts ?? {},
|
|
17486
|
+
persisted: selectedRows,
|
|
17487
|
+
succeeded: Math.max(0, selectedRows - failedRows),
|
|
17488
|
+
failed: failedRows
|
|
17489
|
+
}
|
|
17490
|
+
};
|
|
17491
|
+
}
|
|
17492
|
+
}
|
|
17493
|
+
if (isRecord7(next.columnStats) && selectedRows > 0) {
|
|
17494
|
+
const columnStats = { ...next.columnStats };
|
|
17495
|
+
for (const alias of forcedAliases) {
|
|
17496
|
+
const stat4 = isRecord7(columnStats[alias]) ? columnStats[alias] : null;
|
|
17497
|
+
const execution = isRecord7(stat4?.execution) ? stat4.execution : null;
|
|
17498
|
+
if (!stat4 || !execution) continue;
|
|
17499
|
+
columnStats[alias] = {
|
|
17500
|
+
...stat4,
|
|
17501
|
+
execution: {
|
|
17502
|
+
...execution,
|
|
17503
|
+
"completed:executed": executionSummaryText(
|
|
17504
|
+
selectedRows,
|
|
17505
|
+
selectedRows
|
|
17506
|
+
),
|
|
17507
|
+
"completed:reused": executionSummaryText(0, selectedRows)
|
|
17508
|
+
}
|
|
17509
|
+
};
|
|
17510
|
+
}
|
|
17511
|
+
next.columnStats = columnStats;
|
|
17512
|
+
}
|
|
17513
|
+
return next;
|
|
17514
|
+
};
|
|
17515
|
+
const rewritten = rewrite(input2.status);
|
|
17516
|
+
if (failedRows === 0 || !isRecord7(rewritten)) {
|
|
17517
|
+
return rewritten;
|
|
17518
|
+
}
|
|
17519
|
+
return {
|
|
17520
|
+
...rewritten,
|
|
17521
|
+
...rewritten.status === "completed" ? { status: "failed" } : {},
|
|
17522
|
+
...isRecord7(rewritten.run) && rewritten.run.status === "completed" ? { run: { ...rewritten.run, status: "failed" } } : {}
|
|
17523
|
+
};
|
|
17524
|
+
}
|
|
17209
17525
|
function summarizeFailedJobError(value) {
|
|
17210
17526
|
const text = String(value ?? "").trim();
|
|
17211
17527
|
return text.length > 500 ? `${text.slice(0, 497)}...` : text;
|
|
@@ -17474,11 +17790,11 @@ function normalizeEnrichRowsForCsvExport(rows) {
|
|
|
17474
17790
|
}
|
|
17475
17791
|
function legacyMetadataFromRow(row) {
|
|
17476
17792
|
const direct = parseLegacyMetadataCell(row._metadata);
|
|
17477
|
-
if (direct &&
|
|
17793
|
+
if (direct && isRecord7(direct.columns)) {
|
|
17478
17794
|
return direct;
|
|
17479
17795
|
}
|
|
17480
17796
|
const relocated = parseLegacyMetadataCell(row.metadata);
|
|
17481
|
-
if (relocated &&
|
|
17797
|
+
if (relocated && isRecord7(relocated.columns)) {
|
|
17482
17798
|
return relocated;
|
|
17483
17799
|
}
|
|
17484
17800
|
const flattenedColumns = parseLegacyMetadataCell(row["metadata.columns"]);
|
|
@@ -17495,7 +17811,7 @@ function legacyMetadataFromRow(row) {
|
|
|
17495
17811
|
}
|
|
17496
17812
|
function parseLegacyMetadataCell(value) {
|
|
17497
17813
|
const parsed = parseMaybeJsonObject(value);
|
|
17498
|
-
if (
|
|
17814
|
+
if (isRecord7(parsed)) {
|
|
17499
17815
|
return parsed;
|
|
17500
17816
|
}
|
|
17501
17817
|
if (typeof value !== "string") {
|
|
@@ -17512,12 +17828,12 @@ function parseLegacyMetadataCell(value) {
|
|
|
17512
17828
|
for (const candidate of candidates) {
|
|
17513
17829
|
try {
|
|
17514
17830
|
const decoded = JSON.parse(candidate);
|
|
17515
|
-
if (
|
|
17831
|
+
if (isRecord7(decoded)) {
|
|
17516
17832
|
return decoded;
|
|
17517
17833
|
}
|
|
17518
17834
|
if (typeof decoded === "string") {
|
|
17519
17835
|
const nested = JSON.parse(decoded);
|
|
17520
|
-
if (
|
|
17836
|
+
if (isRecord7(nested)) {
|
|
17521
17837
|
return nested;
|
|
17522
17838
|
}
|
|
17523
17839
|
}
|
|
@@ -17527,8 +17843,8 @@ function parseLegacyMetadataCell(value) {
|
|
|
17527
17843
|
return null;
|
|
17528
17844
|
}
|
|
17529
17845
|
function mergeLegacyMetadataRecords(base, enriched) {
|
|
17530
|
-
const baseColumns =
|
|
17531
|
-
const enrichedColumns =
|
|
17846
|
+
const baseColumns = isRecord7(base.columns) ? base.columns : null;
|
|
17847
|
+
const enrichedColumns = isRecord7(enriched.columns) ? enriched.columns : null;
|
|
17532
17848
|
const merged = {
|
|
17533
17849
|
...base,
|
|
17534
17850
|
...enriched
|
|
@@ -17730,7 +18046,7 @@ function registerEnrichCommand(program) {
|
|
|
17730
18046
|
sourceCsvPath,
|
|
17731
18047
|
rows
|
|
17732
18048
|
}) : null;
|
|
17733
|
-
const rowsForFailureReport = exportResult?.
|
|
18049
|
+
const rowsForFailureReport = exportResult?.enrichedDataRows ?? extractCanonicalRowsInfo(status)?.rows ?? [];
|
|
17734
18050
|
if (options.json) {
|
|
17735
18051
|
const failureReport2 = await maybeEmitEnrichFailureReport({
|
|
17736
18052
|
config,
|
|
@@ -17739,10 +18055,22 @@ function registerEnrichCommand(program) {
|
|
|
17739
18055
|
client: client2,
|
|
17740
18056
|
outputPath: exportResult?.path ?? outputPath ?? null
|
|
17741
18057
|
});
|
|
18058
|
+
const run = rewriteEnrichJsonStatus({
|
|
18059
|
+
status,
|
|
18060
|
+
config,
|
|
18061
|
+
forceAliases,
|
|
18062
|
+
output: exportResult,
|
|
18063
|
+
failureReport: failureReport2
|
|
18064
|
+
});
|
|
17742
18065
|
printJson({
|
|
17743
18066
|
ok: !failureReport2,
|
|
17744
|
-
run
|
|
17745
|
-
output: exportResult ? {
|
|
18067
|
+
run,
|
|
18068
|
+
output: exportResult ? {
|
|
18069
|
+
sourceCsvRows: exportResult.sourceCsvRows,
|
|
18070
|
+
selectedRows: exportResult.selectedRows,
|
|
18071
|
+
enrichedRows: exportResult.enrichedRows,
|
|
18072
|
+
path: exportResult.path
|
|
18073
|
+
} : null,
|
|
17746
18074
|
...failureReport2 ? {
|
|
17747
18075
|
failure_report: {
|
|
17748
18076
|
path: failureReport2.path,
|
|
@@ -17762,7 +18090,7 @@ function registerEnrichCommand(program) {
|
|
|
17762
18090
|
);
|
|
17763
18091
|
const waterfallSummaryLines = buildEnrichWaterfallSummaryLines(
|
|
17764
18092
|
config,
|
|
17765
|
-
exportResult.
|
|
18093
|
+
exportResult.enrichedDataRows
|
|
17766
18094
|
);
|
|
17767
18095
|
if (waterfallSummaryLines.length > 0) {
|
|
17768
18096
|
process.stdout.write(`${waterfallSummaryLines.join("\n")}
|
|
@@ -17829,6 +18157,129 @@ Examples:
|
|
|
17829
18157
|
).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);
|
|
17830
18158
|
}
|
|
17831
18159
|
|
|
18160
|
+
// src/cli/commands/legacy-noops.ts
|
|
18161
|
+
var SESSION_SUBCOMMANDS = [
|
|
18162
|
+
"start",
|
|
18163
|
+
"status",
|
|
18164
|
+
"output",
|
|
18165
|
+
"alert",
|
|
18166
|
+
"usage",
|
|
18167
|
+
"limit",
|
|
18168
|
+
"render",
|
|
18169
|
+
"send"
|
|
18170
|
+
];
|
|
18171
|
+
var BACKEND_SUBCOMMANDS = [
|
|
18172
|
+
"start",
|
|
18173
|
+
"stop",
|
|
18174
|
+
"status",
|
|
18175
|
+
"refresh-runtime",
|
|
18176
|
+
"sync-runtime"
|
|
18177
|
+
];
|
|
18178
|
+
function legacyNoopEnvelope(input2) {
|
|
18179
|
+
const command = [
|
|
18180
|
+
"deepline",
|
|
18181
|
+
input2.family,
|
|
18182
|
+
input2.subcommand
|
|
18183
|
+
].filter(Boolean).join(" ");
|
|
18184
|
+
const subject = input2.family === "session" ? "Legacy Session UI/playground command" : "Legacy local playground backend command";
|
|
18185
|
+
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.";
|
|
18186
|
+
return {
|
|
18187
|
+
ok: true,
|
|
18188
|
+
noop: true,
|
|
18189
|
+
command,
|
|
18190
|
+
compatibility: {
|
|
18191
|
+
family: "legacy_python_cli",
|
|
18192
|
+
sdk_behavior: "noop"
|
|
18193
|
+
},
|
|
18194
|
+
render: {
|
|
18195
|
+
sections: [
|
|
18196
|
+
{
|
|
18197
|
+
title: subject,
|
|
18198
|
+
lines: [note]
|
|
18199
|
+
}
|
|
18200
|
+
]
|
|
18201
|
+
}
|
|
18202
|
+
};
|
|
18203
|
+
}
|
|
18204
|
+
function printLegacyNoop(input2) {
|
|
18205
|
+
printCommandEnvelope(legacyNoopEnvelope(input2), { json: input2.options.json });
|
|
18206
|
+
}
|
|
18207
|
+
function legacySubcommandFromArgv(family) {
|
|
18208
|
+
const args = process.argv.slice(2);
|
|
18209
|
+
const familyIndex = args.indexOf(family);
|
|
18210
|
+
const nextToken = familyIndex >= 0 ? args[familyIndex + 1] : void 0;
|
|
18211
|
+
return nextToken && !nextToken.startsWith("-") ? nextToken : void 0;
|
|
18212
|
+
}
|
|
18213
|
+
function addLegacyNoopSubcommand(parent, family, subcommand, description) {
|
|
18214
|
+
parent.command(subcommand).description(description).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").action((_args, options) => {
|
|
18215
|
+
printLegacyNoop({ family, subcommand, options });
|
|
18216
|
+
});
|
|
18217
|
+
}
|
|
18218
|
+
function registerLegacyNoopCommands(program) {
|
|
18219
|
+
const session = program.command("session").description(
|
|
18220
|
+
"Compatibility no-ops for legacy Python Session UI commands."
|
|
18221
|
+
).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
|
|
18222
|
+
"after",
|
|
18223
|
+
`
|
|
18224
|
+
Notes:
|
|
18225
|
+
The SDK CLI accepts singular session commands from older agent skills so they
|
|
18226
|
+
do not fail, but it does not manage the legacy Python Session UI.
|
|
18227
|
+
Use "deepline sessions send" or "deepline sessions render" for real SDK
|
|
18228
|
+
transcript workflows.
|
|
18229
|
+
|
|
18230
|
+
Examples:
|
|
18231
|
+
deepline session start --steps '["Inspect CSV","Run pilot"]'
|
|
18232
|
+
deepline session status --message "Running pilot"
|
|
18233
|
+
deepline session output --csv ./results.csv --label "Results"
|
|
18234
|
+
`
|
|
18235
|
+
).action((args, options) => {
|
|
18236
|
+
void args;
|
|
18237
|
+
printLegacyNoop({
|
|
18238
|
+
family: "session",
|
|
18239
|
+
subcommand: legacySubcommandFromArgv("session"),
|
|
18240
|
+
options
|
|
18241
|
+
});
|
|
18242
|
+
});
|
|
18243
|
+
for (const subcommand of SESSION_SUBCOMMANDS) {
|
|
18244
|
+
addLegacyNoopSubcommand(
|
|
18245
|
+
session,
|
|
18246
|
+
"session",
|
|
18247
|
+
subcommand,
|
|
18248
|
+
`Accept legacy "deepline session ${subcommand}" as an SDK no-op.`
|
|
18249
|
+
);
|
|
18250
|
+
}
|
|
18251
|
+
const backend = program.command("backend").description(
|
|
18252
|
+
"Compatibility no-ops for legacy Python local backend commands."
|
|
18253
|
+
).allowUnknownOption(true).allowExcessArguments(true).option("--json", "Emit JSON output").argument("[args...]").addHelpText(
|
|
18254
|
+
"after",
|
|
18255
|
+
`
|
|
18256
|
+
Notes:
|
|
18257
|
+
The SDK CLI uses the configured Deepline host and V2 play runtime. It does not
|
|
18258
|
+
start, stop, or refresh the legacy Python local playground backend.
|
|
18259
|
+
|
|
18260
|
+
Examples:
|
|
18261
|
+
deepline backend start
|
|
18262
|
+
deepline backend stop --just-backend
|
|
18263
|
+
deepline backend status --json
|
|
18264
|
+
`
|
|
18265
|
+
).action((args, options) => {
|
|
18266
|
+
void args;
|
|
18267
|
+
printLegacyNoop({
|
|
18268
|
+
family: "backend",
|
|
18269
|
+
subcommand: legacySubcommandFromArgv("backend"),
|
|
18270
|
+
options
|
|
18271
|
+
});
|
|
18272
|
+
});
|
|
18273
|
+
for (const subcommand of BACKEND_SUBCOMMANDS) {
|
|
18274
|
+
addLegacyNoopSubcommand(
|
|
18275
|
+
backend,
|
|
18276
|
+
"backend",
|
|
18277
|
+
subcommand,
|
|
18278
|
+
`Accept legacy "deepline backend ${subcommand}" as an SDK no-op.`
|
|
18279
|
+
);
|
|
18280
|
+
}
|
|
18281
|
+
}
|
|
18282
|
+
|
|
17832
18283
|
// src/cli/commands/org.ts
|
|
17833
18284
|
async function fetchOrganizations(http, apiKey) {
|
|
17834
18285
|
return http.post("/api/v2/auth/cli/organizations", { api_key: apiKey });
|
|
@@ -19731,11 +20182,13 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
19731
20182
|
"deeplineUsdPerPricingUnit",
|
|
19732
20183
|
"deepline_usd_per_pricing_unit"
|
|
19733
20184
|
);
|
|
19734
|
-
const starterScript =
|
|
19735
|
-
|
|
19736
|
-
|
|
19737
|
-
|
|
19738
|
-
|
|
20185
|
+
const starterScript = extractedLists.length > 0 ? starterScriptJson(
|
|
20186
|
+
seedToolListScript({
|
|
20187
|
+
toolId,
|
|
20188
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
20189
|
+
rows: []
|
|
20190
|
+
})
|
|
20191
|
+
) : null;
|
|
19739
20192
|
return {
|
|
19740
20193
|
schemaVersion: 1,
|
|
19741
20194
|
toolId,
|
|
@@ -19761,20 +20214,12 @@ function toolContractJsonForDescribe(tool, requestedToolId) {
|
|
|
19761
20214
|
extractedValues
|
|
19762
20215
|
},
|
|
19763
20216
|
executeCommand: `deepline tools execute ${toolId} --input '{...}' --json`,
|
|
19764
|
-
starterScript: {
|
|
19765
|
-
path: starterScript.path,
|
|
19766
|
-
sourceCode: starterScript.sourceCode,
|
|
19767
|
-
projectDir: starterScript.projectDir,
|
|
19768
|
-
copyToProject: {
|
|
19769
|
-
macosLinux: starterScript.macCopyCommand,
|
|
19770
|
-
windowsPowerShell: starterScript.windowsCopyCommand
|
|
19771
|
-
}
|
|
19772
|
-
}
|
|
20217
|
+
...starterScript ? { starterScript } : {}
|
|
19773
20218
|
};
|
|
19774
20219
|
}
|
|
19775
20220
|
function extractionContractEntries(entries) {
|
|
19776
20221
|
return entries.flatMap((entry) => {
|
|
19777
|
-
if (!
|
|
20222
|
+
if (!isRecord8(entry)) return [];
|
|
19778
20223
|
const name = stringField(entry, "name");
|
|
19779
20224
|
const expression = stringField(entry, "expression");
|
|
19780
20225
|
return name && expression ? [{ name, expression }] : [];
|
|
@@ -19782,8 +20227,8 @@ function extractionContractEntries(entries) {
|
|
|
19782
20227
|
}
|
|
19783
20228
|
function printCompactToolContract(tool, requestedToolId) {
|
|
19784
20229
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19785
|
-
const cost =
|
|
19786
|
-
const getters =
|
|
20230
|
+
const cost = isRecord8(contract.cost) ? contract.cost : {};
|
|
20231
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19787
20232
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19788
20233
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19789
20234
|
const inputFields = Array.isArray(contract.inputFields) ? contract.inputFields : [];
|
|
@@ -19800,7 +20245,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19800
20245
|
console.log("");
|
|
19801
20246
|
console.log("Inputs:");
|
|
19802
20247
|
for (const field of inputFields) {
|
|
19803
|
-
if (!
|
|
20248
|
+
if (!isRecord8(field)) continue;
|
|
19804
20249
|
const name = stringField(field, "name");
|
|
19805
20250
|
if (!name) continue;
|
|
19806
20251
|
const required = field.required ? "*" : "";
|
|
@@ -19813,7 +20258,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19813
20258
|
}
|
|
19814
20259
|
console.log("");
|
|
19815
20260
|
printToolExamplesOnly(tool, requestedToolId, { includeSamples: false });
|
|
19816
|
-
const starterScript =
|
|
20261
|
+
const starterScript = isRecord8(contract.starterScript) ? contract.starterScript : {};
|
|
19817
20262
|
const starterPath = stringField(starterScript, "path");
|
|
19818
20263
|
if (starterPath) {
|
|
19819
20264
|
console.log("");
|
|
@@ -19827,14 +20272,14 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19827
20272
|
console.log("Getters:");
|
|
19828
20273
|
if (listGetters.length) console.log("Lists:");
|
|
19829
20274
|
for (const entry of listGetters) {
|
|
19830
|
-
if (
|
|
20275
|
+
if (isRecord8(entry))
|
|
19831
20276
|
console.log(
|
|
19832
20277
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19833
20278
|
);
|
|
19834
20279
|
}
|
|
19835
20280
|
if (valueGetters.length) console.log("Values:");
|
|
19836
20281
|
for (const entry of valueGetters) {
|
|
19837
|
-
if (
|
|
20282
|
+
if (isRecord8(entry))
|
|
19838
20283
|
console.log(
|
|
19839
20284
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19840
20285
|
);
|
|
@@ -19847,7 +20292,7 @@ function printCompactToolContract(tool, requestedToolId) {
|
|
|
19847
20292
|
}
|
|
19848
20293
|
function printToolPricingOnly(tool, requestedToolId, options = {}) {
|
|
19849
20294
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19850
|
-
const cost =
|
|
20295
|
+
const cost = isRecord8(contract.cost) ? contract.cost : {};
|
|
19851
20296
|
const pricingModel = stringField(cost, "pricingModel") || "unknown";
|
|
19852
20297
|
const billingMode = stringField(cost, "billingMode") || "unknown";
|
|
19853
20298
|
const unit = pricingModel === "per_page" ? "page" : pricingModel === "per_result" ? "result" : pricingModel === "fixed" ? "call" : pricingModel.replace(/^per_/, "") || "unit";
|
|
@@ -19867,7 +20312,7 @@ function printToolSchemaOnly(tool, requestedToolId) {
|
|
|
19867
20312
|
}
|
|
19868
20313
|
console.log("Inputs:");
|
|
19869
20314
|
for (const field of inputFields) {
|
|
19870
|
-
if (!
|
|
20315
|
+
if (!isRecord8(field)) continue;
|
|
19871
20316
|
const name = stringField(field, "name");
|
|
19872
20317
|
if (!name) continue;
|
|
19873
20318
|
const required = field.required ? "*" : "";
|
|
@@ -19893,10 +20338,10 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
19893
20338
|
` input: ${JSON.stringify(sampleInput || {}, null, 2).replace(/\n/g, "\n ")},`
|
|
19894
20339
|
);
|
|
19895
20340
|
console.log("});");
|
|
19896
|
-
const getters =
|
|
20341
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19897
20342
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19898
20343
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19899
|
-
const firstGetter = [...valueGetters, ...listGetters].find(
|
|
20344
|
+
const firstGetter = [...valueGetters, ...listGetters].find(isRecord8);
|
|
19900
20345
|
if (firstGetter) {
|
|
19901
20346
|
const name = stringField(firstGetter, "name") || "value";
|
|
19902
20347
|
const expression = stringField(firstGetter, "expression");
|
|
@@ -19913,7 +20358,7 @@ function printToolExamplesOnly(tool, requestedToolId, options = {}) {
|
|
|
19913
20358
|
}
|
|
19914
20359
|
function printToolGettersOnly(tool, requestedToolId) {
|
|
19915
20360
|
const contract = toolContractJsonForDescribe(tool, requestedToolId);
|
|
19916
|
-
const getters =
|
|
20361
|
+
const getters = isRecord8(contract.getters) ? contract.getters : {};
|
|
19917
20362
|
const listGetters = Array.isArray(getters.extractedLists) ? getters.extractedLists : [];
|
|
19918
20363
|
const valueGetters = Array.isArray(getters.extractedValues) ? getters.extractedValues : [];
|
|
19919
20364
|
console.log(`Getters: ${contract.toolId}`);
|
|
@@ -19926,7 +20371,7 @@ function printToolGettersOnly(tool, requestedToolId) {
|
|
|
19926
20371
|
if (listGetters.length) {
|
|
19927
20372
|
console.log("Lists:");
|
|
19928
20373
|
for (const entry of listGetters) {
|
|
19929
|
-
if (
|
|
20374
|
+
if (isRecord8(entry))
|
|
19930
20375
|
console.log(
|
|
19931
20376
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19932
20377
|
);
|
|
@@ -19935,7 +20380,7 @@ function printToolGettersOnly(tool, requestedToolId) {
|
|
|
19935
20380
|
if (valueGetters.length) {
|
|
19936
20381
|
console.log("Values:");
|
|
19937
20382
|
for (const entry of valueGetters) {
|
|
19938
|
-
if (
|
|
20383
|
+
if (isRecord8(entry))
|
|
19939
20384
|
console.log(
|
|
19940
20385
|
`- ${stringField(entry, "name")}: ${playResultExpression(entry)}`
|
|
19941
20386
|
);
|
|
@@ -19961,7 +20406,7 @@ function sampleValueForField(field) {
|
|
|
19961
20406
|
function samplePayloadForInputFields(fields) {
|
|
19962
20407
|
return Object.fromEntries(
|
|
19963
20408
|
fields.slice(0, 4).flatMap((field) => {
|
|
19964
|
-
if (!
|
|
20409
|
+
if (!isRecord8(field)) return [];
|
|
19965
20410
|
const name = stringField(field, "name");
|
|
19966
20411
|
if (!name) return [];
|
|
19967
20412
|
return [[name, sampleValueForField(field)]];
|
|
@@ -19986,11 +20431,24 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
19986
20431
|
const inputFields = toolInputFieldsForDisplay(
|
|
19987
20432
|
recordField2(tool, "inputSchema", "input_schema")
|
|
19988
20433
|
);
|
|
19989
|
-
const
|
|
19990
|
-
|
|
19991
|
-
|
|
19992
|
-
|
|
19993
|
-
|
|
20434
|
+
const usageGuidance = usageGuidanceWithAccessDefaults(
|
|
20435
|
+
recordField2(tool, "usageGuidance", "usage_guidance")
|
|
20436
|
+
);
|
|
20437
|
+
const toolExecutionResult = recordField2(
|
|
20438
|
+
usageGuidance,
|
|
20439
|
+
"toolExecutionResult",
|
|
20440
|
+
"tool_execution_result"
|
|
20441
|
+
);
|
|
20442
|
+
const extractedLists = extractionContractEntries(
|
|
20443
|
+
arrayField(toolExecutionResult, "extractedLists", "extracted_lists")
|
|
20444
|
+
);
|
|
20445
|
+
const starterScript = extractedLists.length > 0 ? starterScriptJson(
|
|
20446
|
+
seedToolListScript({
|
|
20447
|
+
toolId,
|
|
20448
|
+
payload: samplePayloadForInputFields(inputFields),
|
|
20449
|
+
rows: []
|
|
20450
|
+
})
|
|
20451
|
+
) : null;
|
|
19994
20452
|
const {
|
|
19995
20453
|
cost: _cost,
|
|
19996
20454
|
deeplineCreditsPerPricingUnit: _deeplineCreditsPerPricingUnit,
|
|
@@ -20010,9 +20468,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
20010
20468
|
toolId,
|
|
20011
20469
|
provider: tool.provider,
|
|
20012
20470
|
displayName: tool.displayName,
|
|
20013
|
-
usageGuidance
|
|
20014
|
-
recordField2(tool, "usageGuidance", "usage_guidance")
|
|
20015
|
-
),
|
|
20471
|
+
usageGuidance,
|
|
20016
20472
|
runtimeOutputHelp: {
|
|
20017
20473
|
contract: "tools describe shows declared schema and Deepline getters; it is not an observed provider response.",
|
|
20018
20474
|
getterScope: "extractedValues/extractedLists .get() only works for declared Deepline getters listed in usageGuidance.toolExecutionResult.",
|
|
@@ -20023,15 +20479,7 @@ function toolMetadataJsonForDescribe(tool, requestedToolId) {
|
|
|
20023
20479
|
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.",
|
|
20024
20480
|
executeOutputFields: "tools execute JSON may include output_preview for this direct probe only; play debugging uses run output and returned dataset handles."
|
|
20025
20481
|
},
|
|
20026
|
-
starterScript: {
|
|
20027
|
-
path: starterScript.path,
|
|
20028
|
-
sourceCode: starterScript.sourceCode,
|
|
20029
|
-
projectDir: starterScript.projectDir,
|
|
20030
|
-
copyToProject: {
|
|
20031
|
-
macosLinux: starterScript.macCopyCommand,
|
|
20032
|
-
windowsPowerShell: starterScript.windowsCopyCommand
|
|
20033
|
-
}
|
|
20034
|
-
}
|
|
20482
|
+
...starterScript ? { starterScript } : {}
|
|
20035
20483
|
};
|
|
20036
20484
|
}
|
|
20037
20485
|
function usageGuidanceWithAccessDefaults(usageGuidance) {
|
|
@@ -20075,12 +20523,12 @@ function formatListedToolCost(tool) {
|
|
|
20075
20523
|
}
|
|
20076
20524
|
function toolInputFieldsForDisplay(inputSchema) {
|
|
20077
20525
|
if (Array.isArray(inputSchema.fields))
|
|
20078
|
-
return inputSchema.fields.filter(
|
|
20079
|
-
const jsonSchema =
|
|
20080
|
-
const properties =
|
|
20526
|
+
return inputSchema.fields.filter(isRecord8);
|
|
20527
|
+
const jsonSchema = isRecord8(inputSchema.jsonSchema) ? inputSchema.jsonSchema : inputSchema;
|
|
20528
|
+
const properties = isRecord8(jsonSchema.properties) ? jsonSchema.properties : {};
|
|
20081
20529
|
const required = Array.isArray(jsonSchema.required) ? new Set(jsonSchema.required.map(String)) : /* @__PURE__ */ new Set();
|
|
20082
20530
|
return Object.entries(properties).map(([name, value]) => {
|
|
20083
|
-
const property =
|
|
20531
|
+
const property = isRecord8(value) ? value : {};
|
|
20084
20532
|
return {
|
|
20085
20533
|
name,
|
|
20086
20534
|
type: typeof property.type === "string" ? property.type : "unknown",
|
|
@@ -20109,15 +20557,15 @@ function printJsonPreview(label, payload) {
|
|
|
20109
20557
|
}
|
|
20110
20558
|
function samplePayload(samples, key) {
|
|
20111
20559
|
const entry = samples[key];
|
|
20112
|
-
if (!
|
|
20560
|
+
if (!isRecord8(entry)) return void 0;
|
|
20113
20561
|
return Object.prototype.hasOwnProperty.call(entry, "payload") ? entry.payload : entry;
|
|
20114
20562
|
}
|
|
20115
20563
|
function commandEnvelopeFromRawResponse(rawResponse) {
|
|
20116
|
-
return
|
|
20564
|
+
return isRecord8(rawResponse) ? { ...rawResponse } : { status: "completed", result: rawResponse };
|
|
20117
20565
|
}
|
|
20118
20566
|
function listExtractorPathsFromUsageGuidance(tool) {
|
|
20119
20567
|
const toolExecutionResult = tool.usageGuidance?.toolExecutionResult;
|
|
20120
|
-
const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists :
|
|
20568
|
+
const extractedLists = Array.isArray(toolExecutionResult?.extractedLists) ? toolExecutionResult.extractedLists : isRecord8(toolExecutionResult?.extractedLists) ? Object.values(toolExecutionResult.extractedLists) : [];
|
|
20121
20569
|
return extractedLists.flatMap((entry) => {
|
|
20122
20570
|
const paths = entry.details?.candidatePaths ?? entry.details?.rawToolOutputPaths;
|
|
20123
20571
|
if (!Array.isArray(paths)) return [];
|
|
@@ -20133,7 +20581,7 @@ function formatDecimal(value) {
|
|
|
20133
20581
|
function formatUsd(value) {
|
|
20134
20582
|
return `$${formatDecimal(value)}`;
|
|
20135
20583
|
}
|
|
20136
|
-
function
|
|
20584
|
+
function isRecord8(value) {
|
|
20137
20585
|
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
20138
20586
|
}
|
|
20139
20587
|
function stringField(source, ...keys) {
|
|
@@ -20160,7 +20608,7 @@ function arrayField(source, ...keys) {
|
|
|
20160
20608
|
function recordField2(source, ...keys) {
|
|
20161
20609
|
for (const key of keys) {
|
|
20162
20610
|
const value = source[key];
|
|
20163
|
-
if (
|
|
20611
|
+
if (isRecord8(value)) return value;
|
|
20164
20612
|
}
|
|
20165
20613
|
return {};
|
|
20166
20614
|
}
|
|
@@ -20226,7 +20674,7 @@ function parseJsonObjectArgument(raw, flagName) {
|
|
|
20226
20674
|
}
|
|
20227
20675
|
throw invalidJsonError(flagName, message);
|
|
20228
20676
|
}
|
|
20229
|
-
if (!
|
|
20677
|
+
if (!isRecord8(parsed)) {
|
|
20230
20678
|
throw invalidJsonError(flagName, "expected an object.");
|
|
20231
20679
|
}
|
|
20232
20680
|
return parsed;
|
|
@@ -20285,6 +20733,17 @@ function shellQuote2(value) {
|
|
|
20285
20733
|
function powerShellQuote(value) {
|
|
20286
20734
|
return `'${value.replace(/'/g, "''")}'`;
|
|
20287
20735
|
}
|
|
20736
|
+
function starterScriptJson(script) {
|
|
20737
|
+
return {
|
|
20738
|
+
path: script.path,
|
|
20739
|
+
sourceCode: script.sourceCode,
|
|
20740
|
+
projectDir: script.projectDir,
|
|
20741
|
+
copyToProject: {
|
|
20742
|
+
macosLinux: script.macCopyCommand,
|
|
20743
|
+
windowsPowerShell: script.windowsCopyCommand
|
|
20744
|
+
}
|
|
20745
|
+
};
|
|
20746
|
+
}
|
|
20288
20747
|
function seedToolListScript(input2) {
|
|
20289
20748
|
const stem = safeFileStem(input2.toolId);
|
|
20290
20749
|
const fileName = `${stem}-workflow-seed-${Date.now()}.play.ts`;
|
|
@@ -20349,7 +20808,7 @@ function buildToolExecuteBaseEnvelope(input2) {
|
|
|
20349
20808
|
kind: summaryEntries.length > 0 ? "object" : "raw",
|
|
20350
20809
|
summary: input2.summary
|
|
20351
20810
|
};
|
|
20352
|
-
const envelopeHasCanonicalOutput =
|
|
20811
|
+
const envelopeHasCanonicalOutput = isRecord8(envelope.toolResponse) && Object.prototype.hasOwnProperty.call(envelope.toolResponse, "raw");
|
|
20353
20812
|
const inspectCommand = `deepline tools execute ${input2.toolId} --input ${shellQuote2(JSON.stringify(input2.params))} --json`;
|
|
20354
20813
|
const actions = input2.listConversion ? [
|
|
20355
20814
|
{
|
|
@@ -20458,7 +20917,7 @@ async function executeTool(args) {
|
|
|
20458
20917
|
{
|
|
20459
20918
|
...baseEnvelope,
|
|
20460
20919
|
local: {
|
|
20461
|
-
...
|
|
20920
|
+
...isRecord8(baseEnvelope.local) ? baseEnvelope.local : {},
|
|
20462
20921
|
payload_file: jsonPath
|
|
20463
20922
|
}
|
|
20464
20923
|
},
|
|
@@ -21218,10 +21677,6 @@ var command_compatibility_default = {
|
|
|
21218
21677
|
label: "a legacy Python CLI workflow command",
|
|
21219
21678
|
sdk_alternative: "Use `deepline plays ...` in the SDK CLI."
|
|
21220
21679
|
},
|
|
21221
|
-
backend: {
|
|
21222
|
-
family: "python",
|
|
21223
|
-
label: "a legacy Python CLI playground backend command"
|
|
21224
|
-
},
|
|
21225
21680
|
events: {
|
|
21226
21681
|
family: "python",
|
|
21227
21682
|
label: "a legacy Python CLI event command"
|
|
@@ -21450,7 +21905,11 @@ var import_node_os11 = require("os");
|
|
|
21450
21905
|
var import_node_path19 = require("path");
|
|
21451
21906
|
var CHECK_TIMEOUT_MS2 = 3e3;
|
|
21452
21907
|
var SDK_SKILL_NAME = "deepline-plays";
|
|
21453
|
-
var SDK_SKILL_NAMES = [
|
|
21908
|
+
var SDK_SKILL_NAMES = [
|
|
21909
|
+
SDK_SKILL_NAME,
|
|
21910
|
+
"deepline-plays-feedback",
|
|
21911
|
+
"deepline-plays-quickstart"
|
|
21912
|
+
];
|
|
21454
21913
|
var attemptedSync = false;
|
|
21455
21914
|
function shouldSkipSkillsSync() {
|
|
21456
21915
|
const value = process.env.DEEPLINE_SKIP_SKILLS_SYNC?.trim().toLowerCase();
|
|
@@ -21672,7 +22131,9 @@ async function syncSdkSkillsIfNeeded(baseUrl) {
|
|
|
21672
22131
|
if (!update?.needsUpdate && !hasStaleInstalledSkill || !update?.remoteVersion) {
|
|
21673
22132
|
return;
|
|
21674
22133
|
}
|
|
21675
|
-
writeSdkSkillsStatusLine(
|
|
22134
|
+
writeSdkSkillsStatusLine(
|
|
22135
|
+
"SDK skills changed; syncing Deepline SDK skills..."
|
|
22136
|
+
);
|
|
21676
22137
|
const installed = await runSkillsInstall(baseUrl);
|
|
21677
22138
|
if (!installed) return;
|
|
21678
22139
|
if (installedSdkSkillHasStalePositionalExecuteExamples()) {
|
|
@@ -21712,6 +22173,19 @@ function shouldDeferSkillsSyncForCommand() {
|
|
|
21712
22173
|
const subcommand = args[1];
|
|
21713
22174
|
return (command === "play" || command === "plays") && subcommand === "run" && args.includes("--json");
|
|
21714
22175
|
}
|
|
22176
|
+
function isLegacyNoopInvocation() {
|
|
22177
|
+
const command = process.argv.slice(2)[0];
|
|
22178
|
+
return command === "session" || command === "backend";
|
|
22179
|
+
}
|
|
22180
|
+
function topLevelCommandKnown(program, commandName) {
|
|
22181
|
+
const normalized = commandName.trim();
|
|
22182
|
+
if (!normalized || normalized.startsWith("-")) {
|
|
22183
|
+
return true;
|
|
22184
|
+
}
|
|
22185
|
+
return program.commands.some(
|
|
22186
|
+
(command) => command.name() === normalized || command.aliases().includes(normalized)
|
|
22187
|
+
);
|
|
22188
|
+
}
|
|
21715
22189
|
async function runPlayRunnerHealthCheck() {
|
|
21716
22190
|
const dir = await (0, import_promises7.mkdtemp)((0, import_node_path20.join)((0, import_node_os12.tmpdir)(), "deepline-health-play-"));
|
|
21717
22191
|
const file = (0, import_node_path20.join)(dir, "health-check.play.ts");
|
|
@@ -21931,7 +22405,7 @@ Exit codes:
|
|
|
21931
22405
|
`
|
|
21932
22406
|
);
|
|
21933
22407
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
21934
|
-
if (actionCommand.name() === "version" || actionCommand.name() === "update") {
|
|
22408
|
+
if (actionCommand.name() === "version" || actionCommand.name() === "update" || isLegacyNoopInvocation()) {
|
|
21935
22409
|
return;
|
|
21936
22410
|
}
|
|
21937
22411
|
if (printStartupPhase) {
|
|
@@ -21948,9 +22422,7 @@ Exit codes:
|
|
|
21948
22422
|
if (compatibility.error) {
|
|
21949
22423
|
return;
|
|
21950
22424
|
}
|
|
21951
|
-
const relaunched = await maybeAutoUpdateAndRelaunch(
|
|
21952
|
-
compatibility.response
|
|
21953
|
-
);
|
|
22425
|
+
const relaunched = await maybeAutoUpdateAndRelaunch(compatibility.response);
|
|
21954
22426
|
if (relaunched) {
|
|
21955
22427
|
return;
|
|
21956
22428
|
}
|
|
@@ -21978,6 +22450,7 @@ Exit codes:
|
|
|
21978
22450
|
registerCsvCommands(program);
|
|
21979
22451
|
registerDbCommands(program);
|
|
21980
22452
|
registerFeedbackCommands(program);
|
|
22453
|
+
registerLegacyNoopCommands(program);
|
|
21981
22454
|
registerUpdateCommand(program);
|
|
21982
22455
|
registerQuickstartCommands(program);
|
|
21983
22456
|
program.command("preflight").description("Run compact health, auth, and Deepline billing checks.").option("--json", "Force JSON output.").addHelpText(
|
|
@@ -22078,6 +22551,20 @@ Examples:
|
|
|
22078
22551
|
process.exitCode = 2;
|
|
22079
22552
|
return;
|
|
22080
22553
|
}
|
|
22554
|
+
const requestedTopLevelCommand = process.argv.slice(2)[0] ?? "";
|
|
22555
|
+
if (!topLevelCommandKnown(program, requestedTopLevelCommand)) {
|
|
22556
|
+
console.error(`error: unknown command '${requestedTopLevelCommand}'`);
|
|
22557
|
+
const hint = commandCompatibilityHint(
|
|
22558
|
+
"sdk",
|
|
22559
|
+
requestedTopLevelCommand,
|
|
22560
|
+
autoDetectBaseUrl()
|
|
22561
|
+
);
|
|
22562
|
+
if (hint && !process.argv.includes("--json")) {
|
|
22563
|
+
console.error(hint);
|
|
22564
|
+
}
|
|
22565
|
+
process.exitCode = 2;
|
|
22566
|
+
return;
|
|
22567
|
+
}
|
|
22081
22568
|
try {
|
|
22082
22569
|
await program.parseAsync(process.argv);
|
|
22083
22570
|
recordCliTrace({
|