fix(copilot): mount input tables with display-name CSV headers, not column IDs#5121
Conversation
|
@greptile review |
PR SummaryMedium Risk Overview The mount builder now matches the table export path: header row uses display names only (with formula neutralization), cell values are read via
Reviewed by Cursor Bugbot for commit 2cadfc2. Bugbot is set up for automated code reviews on this repo. Configure here. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR fixes a silent data-loss bug in the copilot
Confidence Score: 5/5Safe to merge — the change is tightly scoped to the CSV builder inside the table mount path and does not touch any other execution logic. The fix is straightforward and well-validated: QueryResult.rows is typed as a required TableRow[] (never optional) and TableRow.data is a required RowData (non-nullable), so removing the old defensive ?? [] and || {} guards is correct. The real shared serializers are exercised directly in the new tests rather than mocked, giving genuine coverage. Both the happy path (modern id-keyed rows) and the legacy name-keyed fallback are tested, and the comma-quoting assertion validates the RFC-4180 escaping end-to-end. No unrelated code was modified. No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[inputTables ref] --> B[resolveTableRef]
B --> C[queryRows]
C --> D[rows.rows loop]
D --> E[Header: column.name via neutralizeCsvFormula + toCsvRow]
D --> F[Data row: getColumnId looks up col_id or name fallback]
F --> G[row.data keyed by stable column id]
G --> H[formatCsvValue applies formula-neutralize and type serialization]
H --> I[toCsvRow applies RFC-4180 quoting and escaping]
E --> J[csvLines joined with newline]
I --> J
J --> K[SandboxFile mounted at /home/user/tables/tbl_id.csv]
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
A[inputTables ref] --> B[resolveTableRef]
B --> C[queryRows]
C --> D[rows.rows loop]
D --> E[Header: column.name via neutralizeCsvFormula + toCsvRow]
D --> F[Data row: getColumnId looks up col_id or name fallback]
F --> G[row.data keyed by stable column id]
G --> H[formatCsvValue applies formula-neutralize and type serialization]
H --> I[toCsvRow applies RFC-4180 quoting and escaping]
E --> J[csvLines joined with newline]
I --> J
J --> K[SandboxFile mounted at /home/user/tables/tbl_id.csv]
Reviews (2): Last reviewed commit: "fix(copilot): mount input tables with di..." | Re-trigger Greptile |
…le-column-names # Conflicts: # apps/sim/lib/copilot/tools/handlers/function-execute.test.ts
Summary
function_executetool mounted input tables as CSV with both display-name headers AND stable column IDs (col_…), with values only under the ID headers — display-name columns came out empty, silently breaking any code reading by header name (e.g. a chart that bucketed everything into one empty group)getColumnId, reusing the sharedtoCsvRow/formatCsvValue/neutralizeCsvFormulaserializers (also adds CSV-formula-injection safety)Type of Change
Testing
Tested manually + new unit tests (2 passing).
bun run lintandbun run check:api-validation:strictpass.Checklist