数据目录 F3 / B4 界面:目录页顶部说明「这个数据源共有 N 张表,只探查了前 200 张」,写明为什么只取了这些、其余的助手也看不到,下一步回到数据源卡片换 schema 或缩小范围后重新探查;助手「参考了哪些表」那一行截断了的库写「共 N 张,只探查了 200 张」;补检查脚本的断言

This commit is contained in:
ThearchyHelios
2026-10-04 01:25:19 +08:00
parent 3ece89872b
commit 9c02833544
6 changed files with 111 additions and 9 deletions
+37 -1
View File
@@ -347,7 +347,11 @@ function listOf(state, src) {
const all = state.tables[src]
const rows = all.filter((t) => !t.missing).sort((a, b) => b.usage - a.usage).map(rowOf)
rows.push(...all.filter((t) => t.missing).map(rowOf))
return { tables: rows, system_notes: isUpload(src), schema_note: all.length ? null : '尚未探查结构' }
// 探查结构截断了的源(state.schemaTotal 里给了数据库里的总数):清单只有探查到的那部分
const explored = all.filter((t) => !t.missing).length
const total = state.schemaTotal?.[src] ?? explored
return { tables: rows, system_notes: isUpload(src), schema_note: all.length ? null : '尚未探查结构',
schema_truncated: total > explored, schema_total: total }
}
const detailOf = (src, t) => ({
table_name: t.name, in_schema: !t.missing, notes: t.notes ?? {}, version: t.version, updated_at: t.updated_at, updated_by: t.updated_by,
@@ -1186,6 +1190,38 @@ const profilePhase = (page) => profileBox(page).getAttribute('data-profile-dialo
/** 报告里不该露的机读码:停止原因、跳过原因、状态、基数的英文值 */
const PROFILE_CODE_RE = /\b(?:budget|deadline|failed|masked|too_large|high_cardinality|no_data|unsupported|verified|proposed|many_to_one|row_estimate)\b/
await section('数据目录 · 只探查了一部分表', async () => {
// 探查结构每个数据源最多取 200 张表:多出来的不在清单里,助手也看不到。顶部要说出来,并给出下一步
const state = freshState()
const explored = state.tables[S1].filter((t) => !t.missing).length
const total = explored + 57
state.schemaTotal = { [S1]: total }
const { page, sent, errors, natives, close } = await open(`/data/catalog/${S1}`, { handlers: catalogHandlers(state) })
const bar = page.locator('[data-catalog-schema-partial]')
check('顶部有一条说明', await bar.waitFor({ timeout: 3000 }).then(() => true, () => false))
check('……数字:一共几张、探查了几张', (await bar.getAttribute('data-catalog-schema-partial')) === `${total},${explored}`,
await bar.getAttribute('data-catalog-schema-partial'))
const text = await bar.innerText().catch(() => '')
check('……写成「共有 N 张表,只探查了前 M 张」', text.includes(`这个数据源共有 ${total} 张表,只探查了前 ${explored} 张`), text)
check('……说明为什么只取了这些、其余的助手也看不到', text.includes('最多取 200 张表') && text.includes('其余 57 张不在数据目录中')
&& text.includes('助手也看不到'), text.replace(/\s+/g, ' '))
check('……给出下一步:换 schema 或缩小范围后重新探查', text.includes('换一个 schema') && text.includes('缩小范围')
&& text.includes('探查结构'), text.replace(/\s+/g, ' '))
await shot(page, 'catalog-schema-partial')
await cleanCopy(page, '只探查了一部分表')
await bar.locator('[data-catalog-schema-partial-go]').click()
await page.waitForURL('**/data/databases', { timeout: 5000 }).catch(() => {})
check('……按钮回到数据源卡片', new URL(page.url()).pathname === '/data/databases', page.url())
// 没截断的库不出这一条
await goto(page, `/data/catalog/${S4}`)
await page.locator('[data-catalog-overview]').waitFor()
check('没截断的库不出这一条', await page.locator('[data-catalog-schema-partial]').count() === 0)
check('只读、不发写请求', writes(sent, /./).length === 0)
check('没有原生对话框', natives.length === 0, natives.join(' | '))
check('没有运行时报错', errors.length === 0, errors.join(' | '))
await close()
})
await section('数据目录 · 数据剖析设置', async () => {
const state = freshState()
const replies = { patch: [] }
+10
View File
@@ -685,6 +685,16 @@ await section('Copilot:这一轮参考了哪些表(context 操作)', async
{ source: 'b', tables: [], selected_by: 'model', total: 70 }] })
check('挑表成功但某个库一张没挑中:说清只给了表名', !!none?.detail.includes('「b」共 70 张表,未挑中与需求相关的表,已提供全部表名'),
none?.detail)
// 探查结构截断了(每个数据源最多取 200 张表):total 是数据库里的总数,explored 是探查到的
const partial = mod.copilotContext({ op: 'context', sources: [
{ source: 'wide', tables: ['t001', 't002'], selected_by: 'model', total: 205, explored: 200 },
{ source: 'wide2', tables: [], selected_by: 'fallback', total: 260, explored: 200, reason: 'r' }] })
check('截断了的库写「共 N 张,只探查了 200 张」', !!partial?.detail.includes('「wide」共 205 张,只探查了 200 张,按需求挑出 2 张:t001、t002')
&& partial.detail.includes('「wide2」共 260 张,只探查了 200 张,未能按需求挑选'), partial?.detail)
const whole = mod.copilotContext({ op: 'context', sources: [
{ source: 'a', tables: ['x'], selected_by: 'model', total: 60, explored: 60 }] })
check('探查到的和总数一样:照旧写「从 N 张表中挑出」', !!whole?.detail.includes('「a」按需求从 60 张表中挑出 1 张') && !whole.detail.includes('只探查了'),
whole?.detail)
check('形状不对不出行、不报错', mod.decodeCopilot([
{ op: 'context' }, { op: 'context', sources: 'x' }, { op: 'context', sources: [null, 3, { tables: ['t'] }] },
]).length === 0)