mirror of
https://github.com/ThearchyHelios/AgentLab.git
synced 2026-11-15 14:21:58 +00:00
Excel 导入改造期 2:配方引擎与确认向导——表从哪一行哪一列开始、哪些是合计、日期怎么补年份,都写进一份可校验的配方;首次导入经人确认,之后每期按配方重放并核对
配方语言(agentlab-recipe/2,新 recipe_types、recipe) - 封闭、不含正则、保存时静态校验:常量只能从表里的候选文字里选,占位符只能映射成空值,单位从固定词表里取 - 交叉表和列表两种版式;分段各自定位、不依赖先后顺序;合计按标签语义区间核对,关系恒等式、口径不同的声明都写在配方里 - 固定的解析器集合(parsers/2):全角、各类横线、千分位、月日写法宽容归一,规范写法存库、原文另记 执行器(新 xlsx_cells、recipe_engine) - 两遍读取逐行对账,每个非空格都要有去向(格子账);交叉表逆透视成长表,按统计期补年份并断言覆盖整期 - 合计行改作核对并另存一张表,不和明细混在一列;区域外文字、隐藏行列、合并单元格、空行之后的文字都单独报出 - STRICT 加主键写临时库;按锚点段记溯源,供后续证据下钻用;大表流式读取,扫描在 sheetData 处停止 校验与说明(新 recipe_checks、recipe_notes) - SQL 核对分通过、不一致、无法核对三种结果,失败分结构、数据质量、需确认三类;结构类直接拒收 - 数据质量类可以写理由接受,接受不改库、只改状态和说明 - 表的说明按核对结果生成、不含数字,经过数字检查;没核对过的不写「已核对」 起草(新 recipe_suggest、recipe_ai) - 先用规则起草:建议卡片加待确认问题(关系要不要登记、占位符表示什么) - 规则起草不完整时才提示 AI 兜底:界面先展示要发出的全部文字,用户同意才发;只发结构,数字、隐藏行列、遮罩列不发,公式先脱敏;同意绑定模型和服务方;AI 只写配方,有限次修订,记 token 和费用;截断单独识别 - 无论规则还是 AI 起草,都必须人工确认才能启用 导入流程(新 recipe_imports、recipe_confirm、recipe_diff、api/table_imports) - 暂存 → 起草 → 回答问题或改配方 → 试运行 → 勾确认项、写接受理由 → 确认并启用;接入期 1 的构建、导入记录、快照和运行固定版本 - 上传新一期按已确认的配方重放,不调用模型,出回执和差异卡,手动启用 - 改配方报破坏性变更(breaking:*)、单位变化、工作表改名的兜底,都要逐项勾选确认 前端导入向导(新 pages/import) - 原始网格(行列号、去向着色)、建议卡片、配方面板(表单,不露正则)、试运行回执、确认清单、差异卡、AI 起草的同意对话框
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
import type {
|
||||
AiPreview, CommitOut, CurrentRecipe, QuestionAnswer, Recipe, Staging,
|
||||
} from '../types'
|
||||
import type {
|
||||
Approval, AutofixResult, Conversation, ConversationDetail, ConversationTurn, CustomTool, DataSource, EvidenceGraph,
|
||||
EvidenceAudit, EvidenceJudgeResult, EvidenceSegmentDetail, GraphSpec, KbDocument, MemoryItem, Provider, PublishCheck, PublishLevel, ReviewResult, Run,
|
||||
@@ -552,6 +555,48 @@ export const api = {
|
||||
get<TableSchema>(`/datasources/${id}/schema?table=${encodeURIComponent(table)}`),
|
||||
},
|
||||
|
||||
/**
|
||||
* 按配方导入(期 2)。暂存区(staging)是一次还没提交的导入:起草、回答问题、改配方、试运行都在它上面做,
|
||||
* 提交(commit)成功之前不动数据源的当前版本。错误按 ApiError.code 分支(staging_closed、trial_required……)
|
||||
*/
|
||||
tableImports: {
|
||||
/** 选文件开始一次导入(首次,或同名的简单导入切换为按配方导入)。带字节进度 */
|
||||
stage: (file: File, body: { name: string; description?: string }, opts?: UploadOptions) => {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
form.append('name', body.name)
|
||||
form.append('description', body.description ?? '')
|
||||
return upload<Staging>('/datasources/imports/stage', form, opts)
|
||||
},
|
||||
get: (id: string) => get<Staging>(`/datasources/imports/${encodeURIComponent(id)}`),
|
||||
/** 已选的全部回答(服务端从起点配方按问题顺序重放)。needs_reason 的选项要带 reason */
|
||||
answers: (id: string, answers: Record<string, QuestionAnswer>) =>
|
||||
post<Staging>(`/datasources/imports/${encodeURIComponent(id)}/answers`, { answers }),
|
||||
/** 整份配方替换工作配方:有静态校验问题也照存,只是不能试运行;已选的回答清空 */
|
||||
putRecipe: (id: string, recipe: Recipe) =>
|
||||
put<Staging>(`/datasources/imports/${encodeURIComponent(id)}/recipe`, { recipe }),
|
||||
/** 将要发给模型的全文(同意框里给人看的就是这一份) */
|
||||
draftAiPreview: (id: string) => get<AiPreview>(`/datasources/imports/${encodeURIComponent(id)}/draft-ai/preview`),
|
||||
/** 用户同意后才调:preview_sha256 与服务端重算的不一致时回 409 ai_preview_stale */
|
||||
draftAi: (id: string, previewSha256: string) =>
|
||||
post<Staging>(`/datasources/imports/${encodeURIComponent(id)}/draft-ai`, { consent: true, preview_sha256: previewSha256 }),
|
||||
trial: (id: string, body: { context_inputs?: Record<string, { start: string; end: string }>; signed_by?: string | null } = {}) =>
|
||||
post<Staging>(`/datasources/imports/${encodeURIComponent(id)}/trial`, body),
|
||||
commit: (id: string, body: {
|
||||
trial_id: string; confirmations: string[]; acceptances: { check_id: string; reason: string }[]; signed_by?: string | null
|
||||
}) => post<CommitOut>(`/datasources/imports/${encodeURIComponent(id)}/commit`, body),
|
||||
discard: (id: string) => del(`/datasources/imports/${encodeURIComponent(id)}`),
|
||||
/** 上传新一期:按当前配方自动试运行,回来时已带回执和差异卡。带字节进度 */
|
||||
reupload: (sourceId: string, file: File, opts?: UploadOptions) => {
|
||||
const form = new FormData()
|
||||
form.append('file', file)
|
||||
return upload<Staging>(`/datasources/${encodeURIComponent(sourceId)}/reupload`, form, opts)
|
||||
},
|
||||
/** 修改配方(不换文件):用当前导入的原件、以当前配方为工作配方 */
|
||||
redraft: (sourceId: string) => post<Staging>(`/datasources/${encodeURIComponent(sourceId)}/redraft`, {}),
|
||||
recipe: (sourceId: string) => get<CurrentRecipe>(`/datasources/${encodeURIComponent(sourceId)}/recipe`),
|
||||
},
|
||||
|
||||
runs: {
|
||||
/**
|
||||
* status 可以给多个(逗号连接);q 按工作流名模糊匹配;before 是翻页游标
|
||||
|
||||
Reference in New Issue
Block a user