Files
AgentLab/scripts/ledger-fixtures.mjs
T
ThearchyHelios 1195c4abcb 账本前端补两样:答案身上的召回标记写到问数据的轮次和证据面板「口径」一步;对账结果卡上问「说明有用 / 看不懂」
复核 W4R-03(a×c):召回在原答案的运行上追加 ledger.recalled、ledger.basis_changed,以前只在运行时间线(decode)里,问数据的
轮次底部、证据面板「口径」一步、账本接口都不带——使用者被标了「依据有变」、或者口径升版后「已按 v2 核对,不影响」,重开对话
什么也看不到,得点开「过程」才翻得出来,而使用者进不了记录页。W4-a 已在账本接口加上 recall(ledger/recall.answer_marks:
checked / basis / tasks,几种 state 都带),这边照它画:

- typesLedger:RunLedger.recall(LedgerRecallMarks)
- run/LedgerStep 新增 RecallMarks(问数据的轮次和「口径」一步共用):「已按口径「X」vN 核对,不影响」(同一份口径核对过
  几次只写最近那一版,数变了的不在这里写);依据有变按两类各一行——数据目录(catalog / values / catalog_edit)和表结构
  (structure),认不出的种类只说「答案的依据有变」不猜,项数相加,按新目录新出现错误级问题的写几条;看的人手上有说的是
  这个答案的召回待办时写一句(口径升到 vN、数变了 / 依据有变检查出新问题)并链到 /apps/inbox/{待办}
- LedgerTurn:比对过的卡里写在摘要下面;没比对、不比对的答案(state 不是 matched)只要带着标记就单独写一张小卡
- LedgerPart(证据面板「口径」一步):有标签的写在脚注前;没标签但答案带着标记的,这一步只写标记

复核 W4R-10(多包):细案 02 做法 10 的 E2「说明有用 / 看不懂」以前没有入口。W4-a 已加 POST /ledger/answers/{run}/reconcile/
{对账运行}/feedback({verdict: useful | unclear},记成对账运行上的封存后事件、统计 E2 数它),账本接口的 reconciled 每一项
带 feedback {mine, useful, unclear}。这边:

- api.caliberLedger.feedback;typesLedger 加 LedgerFeedback、LedgerFeedbackOut
- run/LedgerReconcile 的对账卡:做完的卡问一句「「差在哪」的说明有帮助吗?」,两个按钮,看的人选过的按下(aria-pressed),
  写各几个人(服务端给的数),可以改主意;交回来的反馈先画上,账本再取一次让别处挂着的同一张卡跟着变;回收站里只看不反馈;
  没做完的卡不问
- 问数据的轮次里卡片上方没有「差在哪」,卡里补写一份(showWhere),反馈问的就是它;证据面板里它本来就在卡片上方,不重复

检查(写请求都在浏览器层拦下):
- check-evidence 新一段 ledger-recall:比对过的答案「口径」一步写核对过(只写最近那一版)、依据有变(项数相加、新问题条数)、
  链到待办;不比对的答案这一步只写依据有变
- check-chat 新一段 recall:轮次底部同上,另核对做完的对账卡写「差在哪」和反馈人数;不比对的答案单独一张小卡写表结构有变
- check-ledger 对账一段:没做完不问;点「看不懂」请求体只有 verdict、按下、写各几个人;改点「说明有用」再记一条、按下的换过来
- 共用夹具 ledger-fixtures 加 RECALL
把这几个文件的改动拿掉回跑:check-chat recall 6 项、check-evidence ledger-recall 4 项、check-ledger 对账反馈 2 项都不过;
放回去全过
2026-10-16 22:21:11 +08:00

134 lines
9.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 口径账本的检查夹具(check-ledger、check-evidence、check-chat 共用):GET /api/runs/{id}/ledger 的答复形状照服务端
// app/ledger/view.py 的 run_view(labels.view_label、issue.Plan.action、reconcile.actions_of / reconciled_view),
// 挂在可点击证据的夹具(frontend/src/run/__tests__/evidence-doc.json,compose_doc 真跑出来的周报,只用通用名)上:
// s6「45,678.5元」来自受管口径「周报口径」v2,等价已证明;s10「1,234单」来自已发布口径「订单口径」v1,助手选用;
// s8「8.7%」相关口径「订单口径」v1(差在哪:少了一个筛选条件),可以对账;s12「37.0元」这次的推理;
// s23「2.35%」没有比对(比对超时)。
// 口径名、表名、数都是虚构的通用名。
/** 口径的几份(calibers) */
export const WEEKLY = { caliber: 'wf-weekly@2', workflow_id: 'wf-weekly', version: 2, level: 'governed', level_text: '受管',
workflow_name: '周报口径', graph_hash: 'aa11' }
export const ORDERS = { caliber: 'wf-orders@1', workflow_id: 'wf-orders', version: 1, level: 'published', level_text: '已发布',
workflow_name: '订单口径', graph_hash: 'bb22' }
const caliberLabel = (c, how, extra = {}) => ({
kind: 'caliber', how, caliber: c.caliber, workflow_id: c.workflow_id, version: c.version, level: c.level,
level_text: c.level_text, workflow_name: c.workflow_name, ...extra,
})
export const DIFF = { items: [{ aspect: 'filter', a: null, b: "status = '[已遮罩]'", text: '口径只保留状态为已支付的行,这次没有这个条件' }],
fallback: false, text_diff: [] }
/** 一份比对过的账本。whole:整题判断(缺省不等价);actions、issued、reconciled 可以换 */
export function ledgerOf(runId, { whole, actions, issued = [], reconciled = [], retro = false, labels } = {}) {
return {
run_id: runId, state: 'matched', note: '封存后比对,不在封存范围内', post_seal: true, artifact: 'cm-1', algo: 'v1',
trigger: retro ? 'on_demand' : 'sealed', retro, matched_at: '2026-10-15T01:00:00+00:00',
...(retro ? { retro_note: '按现在的口径回看' } : {}),
calibers: [WEEKLY, ORDERS],
queries: [
{ artifact: 'q-gmv', node_id: 'ag', source: 'shop', tables: ['orders'], status: 'proven',
candidates: [{ ...WEEKLY, node_id: 'fetch', status: 'proven', how: 'independent' }] },
{ artifact: 'q-orders', node_id: 'ag', source: 'shop', tables: ['orders'], status: 'related',
candidates: [{ ...ORDERS, node_id: 'fetch', status: 'related', comparable: true, via: 'heuristic', diff: DIFF,
binding: [{ field: 'start', value: '2026-09-01' }] }] },
],
reports: { write: { labels: labels ?? {
s6: caliberLabel(WEEKLY, 'independent', { binding: [{ field: 'week', value: '2026-W37' }], card: 'caliber', metric: 'gmv',
queries: ['q-gmv'] }),
s10: caliberLabel(ORDERS, 'composed', { binding: [{ field: 'store', masked: true, value: '已遮罩' }], card: 'caliber',
metric: 'orders', queries: ['q-gmv'] }),
s8: { kind: 'related', related: [{ caliber: ORDERS.caliber, workflow_id: ORDERS.workflow_id, version: 1, level: 'published',
level_text: '已发布', workflow_name: '订单口径', node_id: 'fetch' }], queries: ['q-orders'] },
s12: { kind: 'reasoning', query: 'q-gmv' },
s23: { kind: 'unknown', reason: '比对超过时限,没有做完', query: 'q-gmv' },
} } },
primary: 'write',
whole: whole ?? { equivalent: false, reason: '有的数是这次的推理', counts: { caliber: 2, related: 1, reasoning: 1, unknown: 1 } },
actions: actions ?? [RECONCILE],
issued, reconciled,
}
}
/**
* 答案身上的召回标记(服务端 ledger/recall.answer_marks):周报口径升到 v3 重算过、数没变(同一份口径核对过两次,只写最近
* 那一版);目录里影响数字的两项被驳回、按新目录检查新出现 1 条错误级问题,另有一次出现了新码值(同归「数据目录」那一类,
* 项数相加);看的这个人手上有一条说的是这个答案的 recall 待办(订单口径升到 v2,数变了)
*/
export const RECALL = {
checked: [
{ workflow_id: 'wf-weekly', workflow_name: '周报口径', from_version: 1, to_version: 2, recall_run: 'run-rc0', changed: false,
at: '2026-10-14T01:00:00+00:00' },
{ workflow_id: 'wf-weekly', workflow_name: '周报口径', from_version: 2, to_version: 3, recall_run: 'run-rc1', changed: false,
at: '2026-10-15T01:00:00+00:00' },
],
basis: [
{ kind: 'catalog', items: 2, new_errors: 1, at: '2026-10-15T02:00:00+00:00' },
{ kind: 'values', items: 1, new_errors: 0, at: '2026-10-15T03:00:00+00:00' },
],
tasks: [{ id: 'tk-recall-1', reason: 'caliber', to_version: 2 }],
}
/** 看差多少(s8 那条查询、订单口径):参数是推断的,要先核对 */
export const RECONCILE = {
kind: 'reconcile', query: 'q-orders', caliber: ORDERS.caliber, workflow_id: ORDERS.workflow_id, version: 1, node_id: 'fetch',
workflow_name: '订单口径', level_text: '已发布', needs_check: true, check_reason: '参数按这次的 SQL 推断,请核对',
binding: [{ field: 'start', value: '2026-09-01' }], fallback: false,
fields: [{ name: 'start', required: true, has_default: false }, { name: 'store', required: false, has_default: true }],
}
/** 按口径正式出具(整题等价于周报口径):搭建者能一键,不自动的原因写在 auto_reason */
export const ISSUE = {
kind: 'issue', workflow_id: WEEKLY.workflow_id, version: 2, caliber: WEEKLY.caliber, workflow_name: '周报口径', how: 'independent',
level: 'governed', level_text: '受管', available: true, auto: false, auto_reason: '设置里关了自动按口径出具',
}
/** 整题等价时的标签(三个数都来自周报口径) */
export const WHOLE_LABELS = {
s6: caliberLabel(WEEKLY, 'independent', { binding: [{ field: 'week', value: '2026-W37' }], queries: ['q-gmv'] }),
s10: caliberLabel(WEEKLY, 'independent', { binding: [{ field: 'week', value: '2026-W37' }], queries: ['q-gmv'] }),
s12: caliberLabel(WEEKLY, 'independent', { binding: [{ field: 'week', value: '2026-W37' }], queries: ['q-gmv'] }),
}
export const WHOLE = { equivalent: true, caliber: WEEKLY.caliber, workflow_id: WEEKLY.workflow_id, version: 2, level: 'governed',
level_text: '受管', workflow_name: '周报口径', how: 'independent', binding: [{ field: 'week', value: '2026-W37' }],
missing: [], missing_required: [], counts: { caliber: 3, related: 0, reasoning: 0, unknown: 0 } }
/** 对过的一次账(单行:一组对照)。status 可以换 */
export const reconciledOf = (status = 'succeeded') => ({
run_id: 'run-rec-1', status, query: 'q-orders', caliber: ORDERS.caliber, workflow_id: ORDERS.workflow_id, version: 1,
inputs_from: 'checked', rows: null, card: 'reconcile',
groups: [{ label: '订单数', ours: 'ours_0', caliber: 'cal_0', diff: 'diff_0', rel: 'rel_0' }], created_at: '2026-10-15T02:00:00Z',
})
/** 对账卡上四个指标的展示值(/evidence/metrics/reconcile/{id} 的 rendered) */
export const RECONCILE_VALUES = { ours_0: '1,234单', cal_0: '1,180单', diff_0: '54单', rel_0: '4.58%' }
/** 对账运行的指标出处(形状同片段接口:chain、seal),给 EvidenceDrawer 画 */
export const metricDetail = (runId, metric) => ({
run_id: runId, node: 'reconcile', metric, rendered: RECONCILE_VALUES[metric] ?? '—', eid: `ev:metric:${metric}`,
chain: [{ step: 'metric', alias: 'm', metric, name: metric, value: 1, rendered: RECONCILE_VALUES[metric], node_id: 'reconcile',
caliber: '口径对账', version: 'v1', expression: 'cell(nodes.ours_q1, 0, \'orders\')', sealed: true, inputs: [] }],
seal: { sealed: true, ok: true, covered: true }, redacted: { columns: [] },
})
/** 认证队列:三类来源各一项 */
export const QUEUE = {
items: [
{ id: 'shape:aa11', kind: 'shape', source: 'shop', shape: 'SELECT SUM(amount) FROM orders WHERE paid_at >= ? AND status = ?',
runs: 4, conversations: 3, question: '上周销售额是多少',
turns: [{ run_id: 'run-s1', conversation_id: 'c-1', turn_id: 't-1', question: '上周销售额是多少' },
{ run_id: 'run-s2', conversation_id: 'c-2', turn_id: 't-2', question: '这周销售额是多少' }],
params: [{ index: 0, distinct: 3 }], constants: 1, related: [{ caliber: ORDERS.caliber, workflow_id: ORDERS.workflow_id, version: 1, level: 'published' }],
representative: { run_id: 'run-s1', query: 'q-1' }, peers: ['run-s2', 'run-s3'], frozen_into: [] },
{ id: 'cluster:bb22', kind: 'cluster', question: '各门店的退款率', count: 3,
turns: [{ run_id: 'run-c1', turn_id: 't-c1', question: '各门店的退款率' }, { run_id: 'run-c2', turn_id: 't-c2', question: '门店退款率怎么样' }],
frozen_into: [] },
{ id: 'reused:cc33', kind: 'reused', question: '本月新客数', uses: { exports: 2, app: false, extracted: false, canvas: true },
turns: [{ run_id: 'run-r1', conversation_id: 'c-3', turn_id: 't-r1', question: '本月新客数' }],
representative: { run_id: 'run-r1' }, frozen_into: [{ workflow_id: 'wf-new-old', name: '本月新客数(固化的口径草稿)', status: 'draft' }] },
],
considered: { runs: 120, matched: 100, questions: 90 },
threshold: { runs: 3, conversations: 2, exports: 2 },
}