deepline 0.1.176 → 0.1.177
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/bundling-sources/sdk/src/release.ts +5 -4
- package/dist/cli/index.js +454 -55
- package/dist/cli/index.mjs +462 -63
- package/dist/index.js +5 -4
- package/dist/index.mjs +5 -4
- package/package.json +1 -1
package/dist/cli/index.mjs
CHANGED
|
@@ -607,17 +607,18 @@ var SDK_RELEASE = {
|
|
|
607
607
|
// 0.1.111 ships dataset-native tool list getters and result row datasets.
|
|
608
608
|
// 0.1.154 removes the short-lived generated enrich StepOptions recompute
|
|
609
609
|
// fields shipped in 0.1.153.
|
|
610
|
-
|
|
610
|
+
// 0.1.175 ships loud `deepline enrich` empty-waterfall reporting.
|
|
611
|
+
version: "0.1.177",
|
|
611
612
|
apiContract: "2026-06-dataset-handle-results-hard-cutover",
|
|
612
613
|
supportPolicy: {
|
|
613
|
-
latest: "0.1.
|
|
614
|
+
latest: "0.1.177",
|
|
614
615
|
minimumSupported: "0.1.53",
|
|
615
616
|
deprecatedBelow: "0.1.53",
|
|
616
617
|
commandMinimumSupported: [
|
|
617
618
|
{
|
|
618
619
|
command: "enrich",
|
|
619
|
-
minimumSupported: "0.1.
|
|
620
|
-
reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source."
|
|
620
|
+
minimumSupported: "0.1.175",
|
|
621
|
+
reason: "Older SDK CLI enrich generated stale play source; SDK CLI enrich 0.1.153 generated removed StepOptions fields in play source; SDK CLI enrich before 0.1.175 could silently succeed on the empty-waterfall bug when a requested waterfall returned no values for selected rows."
|
|
621
622
|
},
|
|
622
623
|
{
|
|
623
624
|
command: "plays",
|
|
@@ -7743,7 +7744,7 @@ import {
|
|
|
7743
7744
|
writeFile as writeFile3
|
|
7744
7745
|
} from "fs/promises";
|
|
7745
7746
|
import { homedir as homedir7, tmpdir as tmpdir2 } from "os";
|
|
7746
|
-
import { dirname as dirname7, join as join7, resolve as resolve9 } from "path";
|
|
7747
|
+
import { basename as basename2, dirname as dirname7, extname, join as join7, resolve as resolve9 } from "path";
|
|
7747
7748
|
|
|
7748
7749
|
// src/cli/commands/play.ts
|
|
7749
7750
|
import { createHash as createHash2 } from "crypto";
|
|
@@ -17866,14 +17867,39 @@ function enrichOutputJson(exportResult) {
|
|
|
17866
17867
|
...exportResult.partial ? { rows: exportResult.rows, partial: true } : {}
|
|
17867
17868
|
};
|
|
17868
17869
|
}
|
|
17870
|
+
function enrichReportJson(report) {
|
|
17871
|
+
if (!report) {
|
|
17872
|
+
return {};
|
|
17873
|
+
}
|
|
17874
|
+
return {
|
|
17875
|
+
...report.jobs.length > 0 ? {
|
|
17876
|
+
failure_report: {
|
|
17877
|
+
path: report.path,
|
|
17878
|
+
jobs: report.jobs.length
|
|
17879
|
+
}
|
|
17880
|
+
} : {},
|
|
17881
|
+
...report.issues.length > 0 ? {
|
|
17882
|
+
enrich_issues: {
|
|
17883
|
+
path: report.path,
|
|
17884
|
+
issues: report.issues.length,
|
|
17885
|
+
items: report.issues
|
|
17886
|
+
}
|
|
17887
|
+
} : {}
|
|
17888
|
+
};
|
|
17889
|
+
}
|
|
17869
17890
|
async function buildEnrichFailureReport(input2) {
|
|
17891
|
+
const fallbackRowsInfo = input2.exportResult ? null : extractCanonicalRowsInfo(input2.status);
|
|
17870
17892
|
return maybeEmitEnrichFailureReport({
|
|
17871
17893
|
config: input2.config,
|
|
17872
17894
|
rows: input2.rows,
|
|
17873
17895
|
rowRange: input2.rowRange,
|
|
17874
17896
|
client: input2.client,
|
|
17875
17897
|
outputPath: input2.reportOutputPath ?? input2.exportResult?.path ?? input2.outputPath ?? null,
|
|
17876
|
-
|
|
17898
|
+
followUpOutputPath: input2.followUpOutputPath,
|
|
17899
|
+
status: input2.status,
|
|
17900
|
+
rowSetComplete: input2.exportResult ? !input2.exportResult.partial : Boolean(
|
|
17901
|
+
fallbackRowsInfo?.complete && input2.rows.length >= fallbackRowsInfo.totalRows
|
|
17902
|
+
)
|
|
17877
17903
|
});
|
|
17878
17904
|
}
|
|
17879
17905
|
function recordField(value, key) {
|
|
@@ -18150,7 +18176,7 @@ function emitPlainBatchRunFailure(input2) {
|
|
|
18150
18176
|
`Batch ${input2.chunkIndex + 1}/${input2.chunkCount} failed for rows ${input2.rows.rowStart}:${input2.rows.rowEnd}.
|
|
18151
18177
|
`
|
|
18152
18178
|
);
|
|
18153
|
-
const runId = extractRunId(input2.status);
|
|
18179
|
+
const runId = extractRunId(input2.status) ?? firstCollectedStringField(input2.status, "runId");
|
|
18154
18180
|
const error = firstCollectedStringField(input2.status, "error") ?? firstCollectedStringField(input2.status, "message");
|
|
18155
18181
|
if (runId) {
|
|
18156
18182
|
process.stderr.write(`Run id: ${runId}
|
|
@@ -18366,6 +18392,38 @@ function collectHardFailureAliasSpecs(config) {
|
|
|
18366
18392
|
}
|
|
18367
18393
|
return aliases;
|
|
18368
18394
|
}
|
|
18395
|
+
function collectWaterfallAliasSpecs(config) {
|
|
18396
|
+
const aliases = [];
|
|
18397
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18398
|
+
for (const command of config.commands) {
|
|
18399
|
+
if (!("with_waterfall" in command)) {
|
|
18400
|
+
continue;
|
|
18401
|
+
}
|
|
18402
|
+
const alias = command.with_waterfall.trim();
|
|
18403
|
+
if (!alias || seen.has(alias)) {
|
|
18404
|
+
continue;
|
|
18405
|
+
}
|
|
18406
|
+
const activeChildren = command.commands.filter(
|
|
18407
|
+
(child) => !("with_waterfall" in child) && !child.disabled
|
|
18408
|
+
);
|
|
18409
|
+
if (activeChildren.length === 0) {
|
|
18410
|
+
continue;
|
|
18411
|
+
}
|
|
18412
|
+
seen.add(alias);
|
|
18413
|
+
const childOperations = activeChildren.map((child) => child.operation?.trim() || child.tool.trim()).filter(Boolean);
|
|
18414
|
+
aliases.push({
|
|
18415
|
+
alias,
|
|
18416
|
+
childAliases: activeChildren.map((child) => child.alias).filter(Boolean),
|
|
18417
|
+
childToolsByAlias: new Map(
|
|
18418
|
+
activeChildren.map(
|
|
18419
|
+
(child) => [child.alias, child.tool.trim()]
|
|
18420
|
+
)
|
|
18421
|
+
),
|
|
18422
|
+
operation: childOperations.length > 0 ? childOperations.join(", ") : void 0
|
|
18423
|
+
});
|
|
18424
|
+
}
|
|
18425
|
+
return aliases;
|
|
18426
|
+
}
|
|
18369
18427
|
function hardFailureOperationByAlias(config) {
|
|
18370
18428
|
const operations = /* @__PURE__ */ new Map();
|
|
18371
18429
|
if (!config) {
|
|
@@ -18378,6 +18436,60 @@ function hardFailureOperationByAlias(config) {
|
|
|
18378
18436
|
}
|
|
18379
18437
|
return operations;
|
|
18380
18438
|
}
|
|
18439
|
+
function isWaterfallResultMeaningful(value) {
|
|
18440
|
+
if (Array.isArray(value)) {
|
|
18441
|
+
return value.some(isWaterfallResultMeaningful);
|
|
18442
|
+
}
|
|
18443
|
+
if (value && typeof value === "object") {
|
|
18444
|
+
const record = value;
|
|
18445
|
+
const status = typeof record.status === "string" ? record.status.trim().toLowerCase() : "";
|
|
18446
|
+
if (status === "error" || status === "failed") {
|
|
18447
|
+
return false;
|
|
18448
|
+
}
|
|
18449
|
+
if (typeof record.error === "string" && record.error.trim()) {
|
|
18450
|
+
return false;
|
|
18451
|
+
}
|
|
18452
|
+
if (Object.prototype.hasOwnProperty.call(record, "matched_result")) {
|
|
18453
|
+
return isWaterfallResultMeaningful(record.matched_result);
|
|
18454
|
+
}
|
|
18455
|
+
for (const key of [
|
|
18456
|
+
"value",
|
|
18457
|
+
"email",
|
|
18458
|
+
"phone",
|
|
18459
|
+
"phone_number",
|
|
18460
|
+
"mobile_phone",
|
|
18461
|
+
"mobile_phone_number",
|
|
18462
|
+
"url",
|
|
18463
|
+
"domain",
|
|
18464
|
+
"name",
|
|
18465
|
+
"result",
|
|
18466
|
+
"data"
|
|
18467
|
+
]) {
|
|
18468
|
+
if (isWaterfallResultMeaningful(record[key])) {
|
|
18469
|
+
return true;
|
|
18470
|
+
}
|
|
18471
|
+
}
|
|
18472
|
+
return Object.entries(record).some(
|
|
18473
|
+
([key, entry]) => !ENRICH_FLATTENED_CONTROL_FIELDS.has(key) && isWaterfallResultMeaningful(entry)
|
|
18474
|
+
);
|
|
18475
|
+
}
|
|
18476
|
+
return isNonEmptyCsvCell(value);
|
|
18477
|
+
}
|
|
18478
|
+
function aliasHasMeaningfulResult(row, alias) {
|
|
18479
|
+
return aliasFailureCellCandidates(row, alias).some(
|
|
18480
|
+
isWaterfallResultMeaningful
|
|
18481
|
+
);
|
|
18482
|
+
}
|
|
18483
|
+
function stableRowSnapshot(value) {
|
|
18484
|
+
if (Array.isArray(value)) {
|
|
18485
|
+
return `[${value.map(stableRowSnapshot).join(",")}]`;
|
|
18486
|
+
}
|
|
18487
|
+
if (value && typeof value === "object") {
|
|
18488
|
+
const record = value;
|
|
18489
|
+
return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableRowSnapshot(record[key])}`).join(",")}}`;
|
|
18490
|
+
}
|
|
18491
|
+
return JSON.stringify(value);
|
|
18492
|
+
}
|
|
18381
18493
|
function cellFailureError(value) {
|
|
18382
18494
|
const parsed = parseMaybeJsonObject(value);
|
|
18383
18495
|
if (!isRecord7(parsed)) {
|
|
@@ -18523,6 +18635,112 @@ function collectEnrichFailureJobs(input2) {
|
|
|
18523
18635
|
});
|
|
18524
18636
|
return jobs;
|
|
18525
18637
|
}
|
|
18638
|
+
function collectEmptyWaterfallIssues(input2) {
|
|
18639
|
+
const aliases = collectWaterfallAliasSpecs(input2.config);
|
|
18640
|
+
if (aliases.length === 0 || input2.rows.length === 0 || !input2.rowSetComplete) {
|
|
18641
|
+
return [];
|
|
18642
|
+
}
|
|
18643
|
+
const runId = extractRunId(input2.status) ?? firstCollectedStringField(input2.status, "runId");
|
|
18644
|
+
const followUpCommands = collectEnrichFollowUpCommands({
|
|
18645
|
+
status: input2.status,
|
|
18646
|
+
runId,
|
|
18647
|
+
outputPath: input2.followUpOutputPath ?? input2.outputPath
|
|
18648
|
+
});
|
|
18649
|
+
const issues = [];
|
|
18650
|
+
aliases.forEach((spec) => {
|
|
18651
|
+
if (waterfallExecutionSignal(input2.status, spec) === "all_condition_skipped") {
|
|
18652
|
+
return;
|
|
18653
|
+
}
|
|
18654
|
+
const logicalRows = /* @__PURE__ */ new Map();
|
|
18655
|
+
input2.rows.forEach((row, rowIndex) => {
|
|
18656
|
+
const sourceRowId = sourceRowIndexFromEnrichRow(
|
|
18657
|
+
row,
|
|
18658
|
+
0,
|
|
18659
|
+
Number.MAX_SAFE_INTEGER
|
|
18660
|
+
);
|
|
18661
|
+
const rowKey = sourceRowId !== null ? `source:${sourceRowId}` : `snapshot:${stableRowSnapshot(row)}`;
|
|
18662
|
+
const existing = logicalRows.get(rowKey);
|
|
18663
|
+
const hasMeaningfulResult = aliasHasMeaningfulResult(row, spec.alias);
|
|
18664
|
+
logicalRows.set(rowKey, {
|
|
18665
|
+
hasMeaningfulResult: (existing?.hasMeaningfulResult ?? false) || hasMeaningfulResult
|
|
18666
|
+
});
|
|
18667
|
+
});
|
|
18668
|
+
const emptyRows = Array.from(logicalRows.values()).filter(
|
|
18669
|
+
(row) => !row.hasMeaningfulResult
|
|
18670
|
+
);
|
|
18671
|
+
if (emptyRows.length !== logicalRows.size) {
|
|
18672
|
+
return;
|
|
18673
|
+
}
|
|
18674
|
+
const selectedRows = logicalRows.size;
|
|
18675
|
+
const message = `Waterfall ${spec.alias} produced 0 values for ${selectedRows} selected row(s).`;
|
|
18676
|
+
issues.push({
|
|
18677
|
+
issue_id: `${spec.alias}-empty-waterfall`,
|
|
18678
|
+
kind: "empty_waterfall",
|
|
18679
|
+
severity: "needs_attention",
|
|
18680
|
+
column: spec.alias,
|
|
18681
|
+
selected_rows: selectedRows,
|
|
18682
|
+
rows_with_value: 0,
|
|
18683
|
+
rows_without_value: selectedRows,
|
|
18684
|
+
message,
|
|
18685
|
+
next_steps: enrichIssueNextSteps({ runId }),
|
|
18686
|
+
follow_up_commands: followUpCommands,
|
|
18687
|
+
...spec.operation ? { operation: spec.operation } : {},
|
|
18688
|
+
...runId ? { run_id: runId } : {}
|
|
18689
|
+
});
|
|
18690
|
+
});
|
|
18691
|
+
return issues;
|
|
18692
|
+
}
|
|
18693
|
+
function waterfallExecutionSignal(status, spec) {
|
|
18694
|
+
const childAliases = spec.childAliases ?? [];
|
|
18695
|
+
if (childAliases.length === 0) {
|
|
18696
|
+
return "unknown";
|
|
18697
|
+
}
|
|
18698
|
+
const summaries = collectColumnStats(status);
|
|
18699
|
+
let sawChildStats = false;
|
|
18700
|
+
let everyChildStatOnlyConditionSkipped = true;
|
|
18701
|
+
const childAliasesWithStats = /* @__PURE__ */ new Set();
|
|
18702
|
+
for (const childAlias of childAliases) {
|
|
18703
|
+
for (const stat2 of summaries.map((summary) => summary[childAlias]).filter(isRecord7)) {
|
|
18704
|
+
sawChildStats = true;
|
|
18705
|
+
childAliasesWithStats.add(childAlias);
|
|
18706
|
+
const execution = isRecord7(stat2.execution) ? stat2.execution : null;
|
|
18707
|
+
const executedSummary = parseExecutionSummary(
|
|
18708
|
+
execution?.["completed:executed"]
|
|
18709
|
+
);
|
|
18710
|
+
const skippedConditionSummary = parseExecutionSummary(
|
|
18711
|
+
execution?.["skipped:condition"]
|
|
18712
|
+
);
|
|
18713
|
+
const executedCount = executedSummary?.count ?? 0;
|
|
18714
|
+
const skippedConditionCount = skippedConditionSummary?.count ?? 0;
|
|
18715
|
+
const totalCount = executedSummary?.total ?? skippedConditionSummary?.total;
|
|
18716
|
+
const onlyConditionSkips = totalCount !== void 0 && skippedConditionCount >= totalCount && executedCount <= skippedConditionCount;
|
|
18717
|
+
if (executedCount > 0 && !onlyConditionSkips || numericFailedRowSignal(execution?.failed) > 0 || numericFailedRowSignal(stat2.failed) > 0 || numericFailedRowSignal(stat2.failedRows) > 0) {
|
|
18718
|
+
return "executed";
|
|
18719
|
+
}
|
|
18720
|
+
if (!onlyConditionSkips) {
|
|
18721
|
+
everyChildStatOnlyConditionSkipped = false;
|
|
18722
|
+
}
|
|
18723
|
+
}
|
|
18724
|
+
}
|
|
18725
|
+
if (sawChildStats && childAliasesWithStats.size === childAliases.length && everyChildStatOnlyConditionSkipped) {
|
|
18726
|
+
return "all_condition_skipped";
|
|
18727
|
+
}
|
|
18728
|
+
return "unknown";
|
|
18729
|
+
}
|
|
18730
|
+
function mergeEnrichFailureJobs(...jobGroups) {
|
|
18731
|
+
const merged = [];
|
|
18732
|
+
const seen = /* @__PURE__ */ new Set();
|
|
18733
|
+
for (const jobs of jobGroups) {
|
|
18734
|
+
for (const job of jobs) {
|
|
18735
|
+
if (seen.has(job.job_id)) {
|
|
18736
|
+
continue;
|
|
18737
|
+
}
|
|
18738
|
+
seen.add(job.job_id);
|
|
18739
|
+
merged.push(job);
|
|
18740
|
+
}
|
|
18741
|
+
}
|
|
18742
|
+
return merged;
|
|
18743
|
+
}
|
|
18526
18744
|
function collectStatusFailureJobs(input2) {
|
|
18527
18745
|
const aliases = collectHardFailureAliasSpecs(input2.config);
|
|
18528
18746
|
if (aliases.length === 0) {
|
|
@@ -18616,14 +18834,23 @@ function collectCompleteStatusFailureMessages(input2) {
|
|
|
18616
18834
|
return complete;
|
|
18617
18835
|
}
|
|
18618
18836
|
function parseExecutionCount(value) {
|
|
18837
|
+
return parseExecutionSummary(value)?.count ?? null;
|
|
18838
|
+
}
|
|
18839
|
+
function parseExecutionSummary(value) {
|
|
18619
18840
|
if (typeof value === "number" && Number.isFinite(value)) {
|
|
18620
|
-
return Math.max(0, Math.trunc(value));
|
|
18841
|
+
return { count: Math.max(0, Math.trunc(value)) };
|
|
18621
18842
|
}
|
|
18622
18843
|
if (typeof value !== "string") {
|
|
18623
18844
|
return null;
|
|
18624
18845
|
}
|
|
18625
|
-
const match = value.trim().match(/^(\d+)\
|
|
18626
|
-
|
|
18846
|
+
const match = value.trim().match(/^(\d+)(?:\s*\/\s*(\d+))?/);
|
|
18847
|
+
if (!match?.[1]) {
|
|
18848
|
+
return null;
|
|
18849
|
+
}
|
|
18850
|
+
return {
|
|
18851
|
+
count: Number.parseInt(match[1], 10),
|
|
18852
|
+
...match[2] ? { total: Number.parseInt(match[2], 10) } : {}
|
|
18853
|
+
};
|
|
18627
18854
|
}
|
|
18628
18855
|
function executionSummaryText(count, total) {
|
|
18629
18856
|
const percent = total > 0 ? Math.round(count / total * 100) : 0;
|
|
@@ -18749,19 +18976,145 @@ function summarizeFailedJobError(value) {
|
|
|
18749
18976
|
const text = String(value ?? "").trim();
|
|
18750
18977
|
return text.length > 500 ? `${text.slice(0, 497)}...` : text;
|
|
18751
18978
|
}
|
|
18979
|
+
function shellSingleQuote2(value) {
|
|
18980
|
+
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
18981
|
+
}
|
|
18982
|
+
function addEnrichFollowUpCommand(commands, seen, command) {
|
|
18983
|
+
const normalized = command.command.trim();
|
|
18984
|
+
if (!normalized || seen.has(normalized)) {
|
|
18985
|
+
return;
|
|
18986
|
+
}
|
|
18987
|
+
seen.add(normalized);
|
|
18988
|
+
commands.push({ ...command, command: normalized });
|
|
18989
|
+
}
|
|
18990
|
+
function datasetSelectorForEnrichCommand(record, fallbackPath) {
|
|
18991
|
+
const candidates = [record.path, record.tableNamespace, fallbackPath];
|
|
18992
|
+
for (const candidate of candidates) {
|
|
18993
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
18994
|
+
return candidate.trim();
|
|
18995
|
+
}
|
|
18996
|
+
}
|
|
18997
|
+
return null;
|
|
18998
|
+
}
|
|
18999
|
+
function collectEnrichFollowUpCommands(input2) {
|
|
19000
|
+
const commands = [];
|
|
19001
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19002
|
+
if (input2.runId) {
|
|
19003
|
+
addEnrichFollowUpCommand(commands, seen, {
|
|
19004
|
+
label: "inspect run",
|
|
19005
|
+
command: `deepline runs get ${input2.runId} --full --json`
|
|
19006
|
+
});
|
|
19007
|
+
}
|
|
19008
|
+
collectDatasetFollowUpCommands(input2.status, {
|
|
19009
|
+
runId: input2.runId,
|
|
19010
|
+
outputPath: input2.outputPath,
|
|
19011
|
+
commands,
|
|
19012
|
+
seen,
|
|
19013
|
+
path: "result",
|
|
19014
|
+
depth: 0
|
|
19015
|
+
});
|
|
19016
|
+
if (input2.runId && input2.outputPath && !commands.some((command) => command.label === "export enrich rows")) {
|
|
19017
|
+
addEnrichFollowUpCommand(commands, seen, {
|
|
19018
|
+
label: "export enrich rows",
|
|
19019
|
+
path: GENERATED_ENRICH_ROWS_TABLE_NAMESPACE,
|
|
19020
|
+
command: `deepline runs export ${input2.runId} --dataset ${GENERATED_ENRICH_ROWS_TABLE_NAMESPACE} --out ${shellSingleQuote2(
|
|
19021
|
+
resolve9(input2.outputPath)
|
|
19022
|
+
)}`
|
|
19023
|
+
});
|
|
19024
|
+
}
|
|
19025
|
+
return commands.slice(0, 8);
|
|
19026
|
+
}
|
|
19027
|
+
function sidecarEnrichRowsExportPath(outputPath) {
|
|
19028
|
+
const resolved = resolve9(outputPath);
|
|
19029
|
+
const ext = extname(resolved) || ".csv";
|
|
19030
|
+
const stem = basename2(resolved, ext);
|
|
19031
|
+
return join7(dirname7(resolved), `${stem}.deepline-enrich-rows${ext}`);
|
|
19032
|
+
}
|
|
19033
|
+
function collectDatasetFollowUpCommands(value, state) {
|
|
19034
|
+
if (state.depth > 12 || !value || typeof value !== "object" || state.commands.length >= 8) {
|
|
19035
|
+
return;
|
|
19036
|
+
}
|
|
19037
|
+
if (Array.isArray(value)) {
|
|
19038
|
+
value.slice(0, 50).forEach(
|
|
19039
|
+
(entry, index) => collectDatasetFollowUpCommands(entry, {
|
|
19040
|
+
...state,
|
|
19041
|
+
path: `${state.path}.${index}`,
|
|
19042
|
+
depth: state.depth + 1
|
|
19043
|
+
})
|
|
19044
|
+
);
|
|
19045
|
+
return;
|
|
19046
|
+
}
|
|
19047
|
+
const record = value;
|
|
19048
|
+
const isDataset = record.kind === "dataset";
|
|
19049
|
+
if (isDataset) {
|
|
19050
|
+
const selector = datasetSelectorForEnrichCommand(record, state.path);
|
|
19051
|
+
const labelPath = typeof record.path === "string" && record.path.trim() ? record.path.trim() : selector ?? state.path;
|
|
19052
|
+
if (typeof record.queryDatasetCommand === "string") {
|
|
19053
|
+
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
19054
|
+
label: `query ${labelPath}`,
|
|
19055
|
+
path: labelPath,
|
|
19056
|
+
command: record.queryDatasetCommand
|
|
19057
|
+
});
|
|
19058
|
+
}
|
|
19059
|
+
const exportCommand = typeof record.slowExportAsCsvCommand === "string" ? record.slowExportAsCsvCommand : typeof record.fullExportCommand === "string" ? record.fullExportCommand : null;
|
|
19060
|
+
if (exportCommand) {
|
|
19061
|
+
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
19062
|
+
label: `export ${labelPath}`,
|
|
19063
|
+
path: labelPath,
|
|
19064
|
+
command: exportCommand
|
|
19065
|
+
});
|
|
19066
|
+
} else if (state.runId && state.outputPath && selector) {
|
|
19067
|
+
addEnrichFollowUpCommand(state.commands, state.seen, {
|
|
19068
|
+
label: selector === GENERATED_ENRICH_ROWS_TABLE_NAMESPACE ? "export enrich rows" : `export ${labelPath}`,
|
|
19069
|
+
path: selector,
|
|
19070
|
+
command: `deepline runs export ${state.runId} --dataset ${shellSingleQuote2(
|
|
19071
|
+
selector
|
|
19072
|
+
)} --out ${shellSingleQuote2(resolve9(state.outputPath))}`
|
|
19073
|
+
});
|
|
19074
|
+
}
|
|
19075
|
+
}
|
|
19076
|
+
for (const [key, child] of Object.entries(record)) {
|
|
19077
|
+
if (key === "preview" || key === "access") {
|
|
19078
|
+
continue;
|
|
19079
|
+
}
|
|
19080
|
+
collectDatasetFollowUpCommands(child, {
|
|
19081
|
+
...state,
|
|
19082
|
+
path: `${state.path}.${key}`,
|
|
19083
|
+
depth: state.depth + 1
|
|
19084
|
+
});
|
|
19085
|
+
if (state.commands.length >= 8) {
|
|
19086
|
+
return;
|
|
19087
|
+
}
|
|
19088
|
+
}
|
|
19089
|
+
}
|
|
19090
|
+
function enrichIssueNextSteps(input2) {
|
|
19091
|
+
const steps = [
|
|
19092
|
+
"Inspect the run output and returned dataset handles.",
|
|
19093
|
+
"If runs get returns queryDatasetCommand or slowExportAsCsvCommand, run that command to fetch durable rows from the customer DB.",
|
|
19094
|
+
"For provider-backed waterfalls, execute the child provider tool on a sample row to confirm the provider returns the expected field."
|
|
19095
|
+
];
|
|
19096
|
+
if (!input2.runId) {
|
|
19097
|
+
return steps;
|
|
19098
|
+
}
|
|
19099
|
+
return [
|
|
19100
|
+
`Inspect run output: deepline runs get ${input2.runId} --full --json`,
|
|
19101
|
+
...steps.slice(1)
|
|
19102
|
+
];
|
|
19103
|
+
}
|
|
18752
19104
|
function formatFailureReportCommand(reportPath) {
|
|
18753
19105
|
const quoted = reportPath.replace(/'/g, `'\\''`);
|
|
18754
19106
|
return `Inspect failed jobs: jq -r '.jobs[] | [.job_id,.row_id,.col_index,.column,.status,.last_error] | @tsv' '${quoted}'`;
|
|
18755
19107
|
}
|
|
18756
19108
|
async function persistEnrichFailureReport(input2) {
|
|
18757
|
-
if (input2.jobs.length === 0) {
|
|
19109
|
+
if (input2.jobs.length === 0 && input2.issues.length === 0) {
|
|
18758
19110
|
return null;
|
|
18759
19111
|
}
|
|
18760
19112
|
const stateDir = join7(homedir7(), ".local", "deepline", "runtime", "state");
|
|
19113
|
+
const reportPrefix = input2.jobs.length > 0 ? "run-block-failures" : "enrich-issues";
|
|
18761
19114
|
await mkdir3(stateDir, { recursive: true });
|
|
18762
19115
|
const reportPath = join7(
|
|
18763
19116
|
stateDir,
|
|
18764
|
-
|
|
19117
|
+
`${reportPrefix}-${Math.floor(Date.now() / 1e3)}-${process.pid}.json`
|
|
18765
19118
|
);
|
|
18766
19119
|
const report = {
|
|
18767
19120
|
generated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -18776,6 +19129,7 @@ async function persistEnrichFailureReport(input2) {
|
|
|
18776
19129
|
},
|
|
18777
19130
|
jobs: input2.jobs,
|
|
18778
19131
|
failed_jobs: input2.jobs,
|
|
19132
|
+
enrich_issues: input2.issues,
|
|
18779
19133
|
canceled_jobs: [],
|
|
18780
19134
|
pending_jobs: [],
|
|
18781
19135
|
missing_job_ids: []
|
|
@@ -18788,48 +19142,100 @@ async function persistEnrichFailureReport(input2) {
|
|
|
18788
19142
|
return reportPath;
|
|
18789
19143
|
}
|
|
18790
19144
|
async function maybeEmitEnrichFailureReport(input2) {
|
|
19145
|
+
const fallbackRowsInfo = extractCanonicalRowsInfo(input2.status);
|
|
19146
|
+
const rowSetComplete = input2.rowSetComplete ?? Boolean(
|
|
19147
|
+
fallbackRowsInfo?.complete && input2.rows.length >= fallbackRowsInfo.totalRows
|
|
19148
|
+
);
|
|
18791
19149
|
const rowJobs = collectEnrichFailureJobs({
|
|
18792
19150
|
config: input2.config,
|
|
18793
19151
|
rows: input2.rows,
|
|
18794
19152
|
rowStart: input2.rowRange.rowStart
|
|
18795
19153
|
});
|
|
18796
|
-
const
|
|
19154
|
+
const enrichIssues = collectEmptyWaterfallIssues({
|
|
19155
|
+
config: input2.config,
|
|
19156
|
+
rows: input2.rows,
|
|
19157
|
+
status: input2.waterfallStatus ?? input2.status,
|
|
19158
|
+
outputPath: input2.outputPath,
|
|
19159
|
+
followUpOutputPath: input2.followUpOutputPath,
|
|
19160
|
+
rowSetComplete
|
|
19161
|
+
});
|
|
19162
|
+
const statusJobs = input2.status === void 0 || rowJobs.length > 0 ? [] : collectStatusFailureJobs({
|
|
18797
19163
|
config: input2.config,
|
|
18798
19164
|
status: input2.status,
|
|
18799
19165
|
rowRange: input2.statusRowRange ?? input2.rowRange
|
|
18800
19166
|
});
|
|
18801
|
-
|
|
19167
|
+
const jobs = rowJobs.length > 0 || statusJobs.length > 0 || input2.status === void 0 ? mergeEnrichFailureJobs(rowJobs, statusJobs) : [];
|
|
19168
|
+
if (jobs.length === 0 && enrichIssues.length === 0) {
|
|
18802
19169
|
return null;
|
|
18803
19170
|
}
|
|
18804
19171
|
const reportPath = await persistEnrichFailureReport({
|
|
18805
19172
|
jobs,
|
|
19173
|
+
issues: enrichIssues,
|
|
18806
19174
|
apiUrl: input2.client.baseUrl,
|
|
18807
19175
|
outputPath: input2.outputPath,
|
|
18808
19176
|
rows: input2.rowRange
|
|
18809
19177
|
});
|
|
18810
|
-
|
|
18811
|
-
|
|
18812
|
-
|
|
18813
|
-
|
|
18814
|
-
|
|
18815
|
-
|
|
19178
|
+
if (jobs.length > 0) {
|
|
19179
|
+
process.stderr.write("Execution failed.\n");
|
|
19180
|
+
process.stderr.write("Failure preview (up to 5 failed jobs):\n");
|
|
19181
|
+
process.stderr.write("job_id row_id col_index column status error\n");
|
|
19182
|
+
for (const job of jobs.slice(0, 5)) {
|
|
19183
|
+
process.stderr.write(
|
|
19184
|
+
`${job.job_id} ${job.row_id} ${job.col_index} ${job.column} ${job.status} ${summarizeFailedJobError(job.last_error)}
|
|
18816
19185
|
`
|
|
18817
|
-
|
|
19186
|
+
);
|
|
19187
|
+
}
|
|
19188
|
+
if (jobs.length > 5) {
|
|
19189
|
+
process.stderr.write(`Showing 5 of ${jobs.length} failed jobs.
|
|
19190
|
+
`);
|
|
19191
|
+
}
|
|
18818
19192
|
}
|
|
18819
|
-
if (
|
|
18820
|
-
process.stderr.write(
|
|
19193
|
+
if (enrichIssues.length > 0) {
|
|
19194
|
+
process.stderr.write("Enrichment needs attention.\n");
|
|
19195
|
+
process.stderr.write("Issue preview (up to 5 enrichment issues):\n");
|
|
19196
|
+
process.stderr.write(
|
|
19197
|
+
"issue_id column severity selected_rows rows_with_value message\n"
|
|
19198
|
+
);
|
|
19199
|
+
for (const issue of enrichIssues.slice(0, 5)) {
|
|
19200
|
+
process.stderr.write(
|
|
19201
|
+
`${issue.issue_id} ${issue.column} ${issue.severity} ${issue.selected_rows} ${issue.rows_with_value} ${issue.message}
|
|
19202
|
+
`
|
|
19203
|
+
);
|
|
19204
|
+
for (const step of issue.next_steps.slice(0, 2)) {
|
|
19205
|
+
process.stderr.write(`Next: ${step}
|
|
19206
|
+
`);
|
|
19207
|
+
}
|
|
19208
|
+
for (const command of issue.follow_up_commands.slice(0, 4)) {
|
|
19209
|
+
process.stderr.write(`Command: ${command.label}: ${command.command}
|
|
18821
19210
|
`);
|
|
19211
|
+
}
|
|
19212
|
+
}
|
|
19213
|
+
if (enrichIssues.length > 5) {
|
|
19214
|
+
process.stderr.write(
|
|
19215
|
+
`Showing 5 of ${enrichIssues.length} enrichment issues.
|
|
19216
|
+
`
|
|
19217
|
+
);
|
|
19218
|
+
}
|
|
18822
19219
|
}
|
|
18823
19220
|
if (reportPath) {
|
|
18824
|
-
|
|
19221
|
+
if (jobs.length > 0) {
|
|
19222
|
+
process.stderr.write(`Full failure report: ${reportPath}
|
|
18825
19223
|
`);
|
|
18826
|
-
|
|
19224
|
+
process.stderr.write(`${formatFailureReportCommand(reportPath)}
|
|
18827
19225
|
`);
|
|
18828
|
-
|
|
18829
|
-
|
|
19226
|
+
} else {
|
|
19227
|
+
process.stderr.write(`Full enrich report: ${reportPath}
|
|
19228
|
+
`);
|
|
19229
|
+
}
|
|
19230
|
+
process.stderr.write(
|
|
19231
|
+
jobs.length > 0 ? "Enrichment failed. See report above.\n" : "Enrichment produced no values for at least one requested waterfall. See issue preview above.\n"
|
|
19232
|
+
);
|
|
19233
|
+
return { path: reportPath, jobs, issues: enrichIssues };
|
|
18830
19234
|
}
|
|
18831
|
-
process.stderr.write(
|
|
18832
|
-
|
|
19235
|
+
process.stderr.write(
|
|
19236
|
+
jobs.length > 0 ? "Enrichment failed.\n" : "Enrichment needs attention.\n"
|
|
19237
|
+
);
|
|
19238
|
+
return { path: "", jobs, issues: enrichIssues };
|
|
18833
19239
|
}
|
|
18834
19240
|
function mergePreferredColumns(preferredColumns, rows) {
|
|
18835
19241
|
const columns = [];
|
|
@@ -19495,6 +19901,7 @@ function registerEnrichCommand(program) {
|
|
|
19495
19901
|
const inPlaceFinalOutputPath = options.inPlace ? resolve9(inputCsv) : null;
|
|
19496
19902
|
const inPlaceCommitOutputPath = options.inPlace ? (await lstat(inputCsv)).isSymbolicLink() ? await realpath(inputCsv) : inPlaceFinalOutputPath : null;
|
|
19497
19903
|
const failureReportOutputPath = options.inPlace ? inPlaceFinalOutputPath : null;
|
|
19904
|
+
const enrichIssueFollowUpOutputPath = options.inPlace && inPlaceFinalOutputPath ? sidecarEnrichRowsExportPath(inPlaceFinalOutputPath) : null;
|
|
19498
19905
|
let inPlaceCommitted = false;
|
|
19499
19906
|
const commitInPlaceOutput = async (exportResult) => {
|
|
19500
19907
|
if (!inPlaceTempOutputPath || !inPlaceCommitOutputPath || !inPlaceFinalOutputPath) {
|
|
@@ -19583,6 +19990,7 @@ function registerEnrichCommand(program) {
|
|
|
19583
19990
|
}
|
|
19584
19991
|
let workingMergeSourceCsvPath = sourceCsvPath;
|
|
19585
19992
|
let lastStatus = null;
|
|
19993
|
+
const batchStatuses = [];
|
|
19586
19994
|
let finalExportResult = null;
|
|
19587
19995
|
let totalEnrichedRows = 0;
|
|
19588
19996
|
const batchFailureRows = [];
|
|
@@ -19620,6 +20028,7 @@ function registerEnrichCommand(program) {
|
|
|
19620
20028
|
suppressOpen: true
|
|
19621
20029
|
});
|
|
19622
20030
|
lastStatus = chunk.status;
|
|
20031
|
+
batchStatuses.push(chunk.status);
|
|
19623
20032
|
if (chunk.captured.result !== 0) {
|
|
19624
20033
|
if (chunk.exportResult) {
|
|
19625
20034
|
finalExportResult = chunk.exportResult;
|
|
@@ -19639,7 +20048,10 @@ function registerEnrichCommand(program) {
|
|
|
19639
20048
|
statusRowRange: chunkRows,
|
|
19640
20049
|
client: client2,
|
|
19641
20050
|
outputPath: failureReportOutputPath ?? finalExportResult?.path ?? outputPath,
|
|
19642
|
-
|
|
20051
|
+
followUpOutputPath: enrichIssueFollowUpOutputPath,
|
|
20052
|
+
status: chunk.status,
|
|
20053
|
+
waterfallStatus: batchStatuses,
|
|
20054
|
+
...finalExportResult ? { rowSetComplete: !finalExportResult.partial } : {}
|
|
19643
20055
|
});
|
|
19644
20056
|
const committedExportResult2 = finalExportResult ? await commitInPlaceOutput(finalExportResult) : null;
|
|
19645
20057
|
if (options.json) {
|
|
@@ -19661,12 +20073,7 @@ function registerEnrichCommand(program) {
|
|
|
19661
20073
|
partial: true
|
|
19662
20074
|
} : {}
|
|
19663
20075
|
} : null,
|
|
19664
|
-
...failureReport3
|
|
19665
|
-
failure_report: {
|
|
19666
|
-
path: failureReport3.path,
|
|
19667
|
-
jobs: failureReport3.jobs.length
|
|
19668
|
-
}
|
|
19669
|
-
} : {}
|
|
20076
|
+
...enrichReportJson(failureReport3)
|
|
19670
20077
|
});
|
|
19671
20078
|
} else {
|
|
19672
20079
|
if (committedExportResult2) {
|
|
@@ -19705,7 +20112,10 @@ function registerEnrichCommand(program) {
|
|
|
19705
20112
|
},
|
|
19706
20113
|
client: client2,
|
|
19707
20114
|
outputPath: failureReportOutputPath ?? finalExportResult?.path ?? outputPath,
|
|
19708
|
-
|
|
20115
|
+
followUpOutputPath: enrichIssueFollowUpOutputPath,
|
|
20116
|
+
status: lastStatus,
|
|
20117
|
+
waterfallStatus: batchStatuses,
|
|
20118
|
+
...finalExportResult ? { rowSetComplete: !finalExportResult.partial } : {}
|
|
19709
20119
|
});
|
|
19710
20120
|
finalExportResult = await commitInPlaceOutput(finalExportResult);
|
|
19711
20121
|
if (options.json) {
|
|
@@ -19737,12 +20147,7 @@ function registerEnrichCommand(program) {
|
|
|
19737
20147
|
enrichedRows: totalEnrichedRows,
|
|
19738
20148
|
path: finalExportResult.path
|
|
19739
20149
|
} : null,
|
|
19740
|
-
...failureReport2
|
|
19741
|
-
failure_report: {
|
|
19742
|
-
path: failureReport2.path,
|
|
19743
|
-
jobs: failureReport2.jobs.length
|
|
19744
|
-
}
|
|
19745
|
-
} : {}
|
|
20150
|
+
...enrichReportJson(failureReport2)
|
|
19746
20151
|
});
|
|
19747
20152
|
}
|
|
19748
20153
|
if (failureReport2) {
|
|
@@ -19773,6 +20178,7 @@ function registerEnrichCommand(program) {
|
|
|
19773
20178
|
exportResult: committedExportResult2,
|
|
19774
20179
|
outputPath,
|
|
19775
20180
|
reportOutputPath: failureReportOutputPath,
|
|
20181
|
+
followUpOutputPath: enrichIssueFollowUpOutputPath,
|
|
19776
20182
|
status
|
|
19777
20183
|
});
|
|
19778
20184
|
if (options.json) {
|
|
@@ -19780,12 +20186,7 @@ function registerEnrichCommand(program) {
|
|
|
19780
20186
|
ok: false,
|
|
19781
20187
|
run: status,
|
|
19782
20188
|
output: enrichOutputJson(committedExportResult2),
|
|
19783
|
-
...failureReport2
|
|
19784
|
-
failure_report: {
|
|
19785
|
-
path: failureReport2.path,
|
|
19786
|
-
jobs: failureReport2.jobs.length
|
|
19787
|
-
}
|
|
19788
|
-
} : {}
|
|
20189
|
+
...enrichReportJson(failureReport2)
|
|
19789
20190
|
});
|
|
19790
20191
|
}
|
|
19791
20192
|
process.exitCode = failureReport2 ? EXIT_SERVER2 : captured.result;
|
|
@@ -19800,6 +20201,7 @@ function registerEnrichCommand(program) {
|
|
|
19800
20201
|
exportResult,
|
|
19801
20202
|
outputPath,
|
|
19802
20203
|
reportOutputPath: failureReportOutputPath,
|
|
20204
|
+
followUpOutputPath: enrichIssueFollowUpOutputPath,
|
|
19803
20205
|
status
|
|
19804
20206
|
});
|
|
19805
20207
|
const committedExportResult2 = await commitInPlaceOutput(exportResult);
|
|
@@ -19814,12 +20216,7 @@ function registerEnrichCommand(program) {
|
|
|
19814
20216
|
ok: !failureReport2,
|
|
19815
20217
|
run,
|
|
19816
20218
|
output: enrichOutputJson(committedExportResult2),
|
|
19817
|
-
...failureReport2
|
|
19818
|
-
failure_report: {
|
|
19819
|
-
path: failureReport2.path,
|
|
19820
|
-
jobs: failureReport2.jobs.length
|
|
19821
|
-
}
|
|
19822
|
-
} : {}
|
|
20219
|
+
...enrichReportJson(failureReport2)
|
|
19823
20220
|
});
|
|
19824
20221
|
if (failureReport2) {
|
|
19825
20222
|
process.exitCode = EXIT_SERVER2;
|
|
@@ -19832,7 +20229,9 @@ function registerEnrichCommand(program) {
|
|
|
19832
20229
|
rowRange: rows,
|
|
19833
20230
|
client: client2,
|
|
19834
20231
|
outputPath: failureReportOutputPath ?? exportResult?.path ?? null,
|
|
19835
|
-
|
|
20232
|
+
followUpOutputPath: enrichIssueFollowUpOutputPath,
|
|
20233
|
+
status,
|
|
20234
|
+
...exportResult ? { rowSetComplete: !exportResult.partial } : {}
|
|
19836
20235
|
});
|
|
19837
20236
|
const committedExportResult = await commitInPlaceOutput(exportResult);
|
|
19838
20237
|
if (committedExportResult) {
|
|
@@ -19917,7 +20316,7 @@ import {
|
|
|
19917
20316
|
writeFileSync as writeFileSync10
|
|
19918
20317
|
} from "fs";
|
|
19919
20318
|
import { homedir as homedir8, platform } from "os";
|
|
19920
|
-
import { basename as
|
|
20319
|
+
import { basename as basename3, dirname as dirname8, join as join8, resolve as resolve10 } from "path";
|
|
19921
20320
|
import { gzipSync } from "zlib";
|
|
19922
20321
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
19923
20322
|
var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
@@ -19936,7 +20335,7 @@ function homeDir() {
|
|
|
19936
20335
|
function detectShellContext() {
|
|
19937
20336
|
const shellPath = process.env.SHELL?.trim() || process.env.ComSpec?.trim() || process.env.COMSPEC?.trim() || "";
|
|
19938
20337
|
return {
|
|
19939
|
-
shell: shellPath ?
|
|
20338
|
+
shell: shellPath ? basename3(shellPath).replace(/\.exe$/i, "") : "unknown",
|
|
19940
20339
|
shell_path: shellPath || null,
|
|
19941
20340
|
os: platform(),
|
|
19942
20341
|
cwd: process.cwd()
|
|
@@ -20042,10 +20441,10 @@ function newestSessionFile(agent) {
|
|
|
20042
20441
|
return newest;
|
|
20043
20442
|
}
|
|
20044
20443
|
function sessionIdFromClaudeFilePath(filePath) {
|
|
20045
|
-
return
|
|
20444
|
+
return basename3(filePath, ".jsonl");
|
|
20046
20445
|
}
|
|
20047
20446
|
function sessionIdFromCodexFilePath(filePath) {
|
|
20048
|
-
const match =
|
|
20447
|
+
const match = basename3(filePath, ".jsonl").match(UUID_IN_TEXT_RE);
|
|
20049
20448
|
return match?.[0] ?? null;
|
|
20050
20449
|
}
|
|
20051
20450
|
function readCodexSessionId(filePath) {
|
|
@@ -20333,19 +20732,19 @@ async function handleSessionsSend(options) {
|
|
|
20333
20732
|
}
|
|
20334
20733
|
const response2 = await uploadPayload("/api/v2/cli/send-session", {
|
|
20335
20734
|
file: readFileSync8(filePath).toString("base64"),
|
|
20336
|
-
filename:
|
|
20735
|
+
filename: basename3(filePath)
|
|
20337
20736
|
});
|
|
20338
20737
|
printCommandEnvelope(
|
|
20339
20738
|
{
|
|
20340
20739
|
...response2,
|
|
20341
20740
|
ok: true,
|
|
20342
|
-
filename:
|
|
20741
|
+
filename: basename3(filePath),
|
|
20343
20742
|
render: {
|
|
20344
20743
|
sections: [
|
|
20345
20744
|
{
|
|
20346
20745
|
title: "sessions send",
|
|
20347
20746
|
lines: [
|
|
20348
|
-
`File '${
|
|
20747
|
+
`File '${basename3(filePath)}' uploaded to #internal-reports.`
|
|
20349
20748
|
]
|
|
20350
20749
|
}
|
|
20351
20750
|
]
|