Skip to content

Commit c635d89

Browse files
Ahmedsekoclaudegiswqs
authored
fix(processing): honor a tool's recommended output extension over the… (#1901)
* fix(processing): honor a tool's recommended output extension over the table default excel_to_table's output param is data_kind "table", so leaving the output path blank made the WASM runner default it to .csv. Its writer is the generic vector-format dispatch (same as GeoParquet/GPKG tools), which has no CSV driver, so the tool failed its own default with "unsupported output path" -- readable input (21542 rows x 10 columns from a legacy .xls), unusable default output. Same failure shape as #1074. The param's own description already names the extension that works ("GeoParquet .parquet recommended"); outputTextFormatHint now honors an explicit "<ext> recommended" in the description before falling back to the generic csv/html/json/table heuristics. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Address Claude review feedback - Require the recommended-extension capture in `outputTextFormatHint` to start with a letter (`/\.([a-z][a-z0-9]*)\s+recommended/i`), so a decimal in a parameter's prose ("a tolerance of 0.5 recommended") can no longer be read as an extension and short-circuit the csv/html/json/table heuristics. - Add a regression test covering that case. --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com> Co-authored-by: giswqs <giswqs@gmail.com>
1 parent 8d6c2ac commit c635d89

2 files changed

Lines changed: 43 additions & 4 deletions

File tree

packages/processing/src/wasm-client.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -417,14 +417,25 @@ export function fileOutputTargetExtension(
417417
/**
418418
* The text/tabular output format a `file_out` parameter declares through its
419419
* name, description, or `table` data kind, as a bare extension (`csv`/`html`/
420-
* `json`), or `null` when nothing recognizable is found. Shared by the WASM
421-
* runner's {@link fileOutputTargetExtension} and the dialog's default-name and
422-
* download-naming code so the two hint lists cannot drift apart.
420+
* `json`/...), or `null` when nothing recognizable is found. Shared by the
421+
* WASM runner's {@link fileOutputTargetExtension} and the dialog's
422+
* default-name and download-naming code so the two hint lists cannot drift
423+
* apart.
423424
*
424425
* @param param - The output parameter.
425-
* @returns `"csv" | "html" | "json"`, or `null` if no text format is implied.
426+
* @returns A bare extension, or `null` if no text format is implied.
426427
*/
427428
export function outputTextFormatHint(param: WhiteboxToolParameter): string | null {
429+
// An explicit "<ext> recommended" in the description is the tool author's
430+
// own guidance and wins over every heuristic below. `excel_to_table`'s
431+
// output is `data_kind: "table"` but its writer is the generic vector
432+
// format dispatch (same as GeoParquet/GPKG tools), which has no CSV driver
433+
// -- defaulting a blank path to ".csv" made the tool reject its own default,
434+
// the same failure mode as #1074.
435+
// The capture must start with a letter so a decimal in the prose ("a
436+
// tolerance of 0.5 recommended") cannot be mistaken for an extension.
437+
const recommended = (param.description ?? "").match(/\.([a-z][a-z0-9]*)\s+recommended/i);
438+
if (recommended) return recommended[1].toLowerCase();
428439
const hint = `${param.name ?? ""} ${param.description ?? ""} ${param.type ?? ""}`;
429440
if (/\bcsv\b/i.test(hint)) return "csv";
430441
if (/\bhtml\b/i.test(hint)) return "html";

tests/wasm-tool-manifests.test.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,4 +441,32 @@ describe("fileOutputTargetExtension", () => {
441441
const opaque = { name: "output", data_kind: "file", io_role: "output" };
442442
assert.equal(fileOutputTargetExtension(opaque, undefined), "dat");
443443
});
444+
445+
it("honors a recommended extension in the description over the table default", () => {
446+
// excel_to_table's output param, as the WASM manifest reports it: data_kind
447+
// "table" would otherwise default to .csv, but the writer is the generic
448+
// vector format dispatch (no CSV driver) and the description already names
449+
// the extension that does work.
450+
const excelToTable = {
451+
name: "file_out",
452+
description:
453+
"Optional output table path (driver from its extension; GeoParquet .parquet recommended). If omitted, stored in memory.",
454+
data_kind: "table",
455+
io_role: "output",
456+
};
457+
assert.equal(fileOutputTargetExtension(excelToTable, undefined), "parquet");
458+
assert.equal(fileOutputTargetExtension(excelToTable, ""), "parquet");
459+
// An explicit user-chosen path still wins.
460+
assert.equal(fileOutputTargetExtension(excelToTable, "report.gpkg"), "gpkg");
461+
});
462+
463+
it("ignores a decimal in the prose rather than reading it as an extension", () => {
464+
const decimalProse = {
465+
name: "file_out",
466+
description: "Optional CSV output path; a tolerance of 0.5 recommended for noisy inputs.",
467+
data_kind: "table",
468+
io_role: "output",
469+
};
470+
assert.equal(fileOutputTargetExtension(decimalProse, undefined), "csv");
471+
});
444472
});

0 commit comments

Comments
 (0)