fix(scan): keep batched description failure bounded

This commit is contained in:
Andrey Avtomonov 2026-05-22 17:17:25 +02:00
parent 3e295ba0d4
commit d9423d8773
2 changed files with 13 additions and 3 deletions

View file

@ -461,7 +461,7 @@ describe('KtxDescriptionGenerator', () => {
expect(llmRuntime.generateText).toHaveBeenCalledTimes(1);
});
it('tolerates structured object failures and falls back to prepared column values', async () => {
it('does not run per-column fallback when structured object generation throws', async () => {
const llmRuntime = createLlmProvider('Fallback description');
llmRuntime.generateObject = vi.fn(async () => {
throw new Error('object output unavailable');
@ -488,9 +488,10 @@ describe('KtxDescriptionGenerator', () => {
});
expect(result.tableDescription).toBeNull();
expect(Object.fromEntries(result.columnDescriptions)).toEqual({ status: 'Fallback description' });
expect(Object.fromEntries(result.columnDescriptions)).toEqual({ status: null });
expect(warnings).toContain('enrichment_failed');
expect(llmRuntime.generateText).toHaveBeenCalledTimes(1);
expect(llmRuntime.generateObject).toHaveBeenCalledTimes(1);
expect(llmRuntime.generateText).not.toHaveBeenCalled();
});
});

View file

@ -755,6 +755,7 @@ export class KtxDescriptionGenerator {
const sampleValues = sampleValuesByColumn(input.table.columns, sampleData);
const descriptions = new Map<string, string | null>();
let tableDescription: string | null = null;
let structuredGenerationSucceeded = false;
try {
const prompt = batchedPrompt({
@ -774,6 +775,7 @@ export class KtxDescriptionGenerator {
schema: batchedTableDescriptionSchema,
temperature: this.settings.temperature,
});
structuredGenerationSucceeded = true;
tableDescription = generated.tableDescription.trim() || null;
const generatedColumns = new Map(
generated.columns.map((column) => [column.name.toLowerCase(), column.description.trim() || null]),
@ -805,6 +807,13 @@ export class KtxDescriptionGenerator {
});
}
if (!structuredGenerationSucceeded) {
for (const column of input.table.columns) {
descriptions.set(column.name, null);
}
return { tableDescription, columnDescriptions: descriptions };
}
const tableContext = `Table: ${input.table.name} | Columns: ${input.table.columns.map((column) => column.name).join(', ')} | Data source: ${input.dataSourceType}`;
for (const column of input.table.columns) {
if (descriptions.get(column.name)) {