Conversation
新增 RunManifest / RunManifestContext / RunManifestDiff 等类型,覆盖 provider/model、model params、prompt hash、strategy、enabled tools、search/retrieval、feature flags、app/build/git 版本与 eval 上下文;并在 Run 与 ResearchRunSummary 上挂载可选的 manifest 字段。
captureRunManifest 在 run 创建时快照运行配置,写入后不再被当前全局设置覆盖;redactManifestSecrets 递归替换 secret 形状的键;diffRunManifests 按 model/prompt/tools/config/versions 分组产出结构化差异;exportRunManifest 输出脱敏 JSON。RunManager 在 prepareRun 写入 manifest,Deep Research 服务同样在启动时记录,AgentKernel 传入 runtimeMode。附 run-manifest 单测与 RunManager 不可变持久化单测。
kernelHost 在 startRun 前装配 manifest 上下文(runtime mode、provider/model/params、prompt hash、enabled tools、search routing、feature flags、app/build/git 版本),并新增 getRunManifest / exportRunManifest / compareRunManifests / getResearchManifest / compareResearchManifests。main 注册 runs:getManifest|exportManifest|compareManifests 与 research:getManifest|compareManifests,preload 与 renderer client 同步暴露(diff 在主进程计算,渲染进程不引入 @finagent/shared)。
RunInfoPanel 以人可读形式展示 manifest(运行时模式、模型/参数、prompt hash、策略、工具、检索、版本、feature flags),提供脱敏 JSON 复制导出,并渲染结构化 diff;ResearchPanel 运行历史新增“运行信息”入口与勾选两次运行的对比入口。client 暴露 kernel/research 的 getManifest/compareManifests,diff 由主进程计算。附 RunInfoPanel 渲染单测。
kernelHost 新增从 @finagent/shared 导入 diffRunManifests/exportRunManifest 后,该单测的部分 mock 需要同步提供这两个导出,否则 bun 的 ESM 链接会报 "Export named ... not found" 而整文件失败。
- RunManifestBudget 增加 effective/clamped:记录 run 实际遵守的预算上限, 以及被系统天花板下调的键,避免事后重算当时的解析规则(与 helsome#17 对接)。 - 新增 RunManifestContextPatch:每次调用可只补充自己负责的字段(如评测的 gold case),其余由宿主提供的基础上下文填充。 - 新增 AGENT_WORKFLOW_ID:Copilot agent 路径的工作流标识,与 Deep Research 的 StrategyId 一起落到 RunManifestStrategy.id。
- RunManager 新增 getRunManifestContext:由宿主提供基础上下文,使所有运行 入口(含评测直接调用 kernel 的路径)都落一份真实清单,而不是空 fallback。 单次调用的 manifestContext 作为 patch 叠加其上。 - 预算在 run 落盘前解析(defaults → overrides → ceiling),并把 defaults/ceiling/overrides/effective/clamped 一并写入清单(与 helsome#17 对接); 非法预算在写入前 fail loud,不再留下半创建的 run。 - 评测运行把 gold case / dataset version 写进清单(与 helsome#15 对接)。 - Deep Research 清单记录 research strategy id(优先于宿主的默认 agent 工作流) 与解析后的 research 预算。 - 新增 manifestToLangfuseMetadata:由清单派生 Langfuse trace metadata, 使 trace 与本地清单共用同一 folioRunId 与同一份 model/provider/strategy/ prompt 版本记录(与 helsome#14 对齐);回读确认值优先,requested 值单独保留。
- AgentKernel 注入 getRunManifestContext,Copilot run 与评测 run 共用同一份 上下文装配,不再需要调用点各自传 manifestContext。 - 清单记录 agent 工作流身份(AGENT_WORKFLOW_ID + 随包版本)。 - agent / Deep Research 的 Langfuse trace metadata 改由 manifestToLangfuseMetadata 派生,trace id 与清单 runId 同源,trace 也带上 model/provider/strategy/ prompt version,便于与历史清单互相定位。
研究策略没有自带的 version 字段,此前的清单会退而继承宿主的应用版本 (与 appVersion/buildVersion 重复)。改为记录「策略解析出的能力计划」 的 SHA-256:同一策略稳定、计划一变即变,因此两次行为不同的运行绝不会 共用同一个策略版本,清单 diff 也就不会把不同策略误判为相同。
新增一个独立的现场验收脚本,只用真实组件、不含 fixture: - 真实 AgentKernel + ResearchService(生产研究路径); - 真实 DeepSeek HTTP 流式调用,配置的模型就是实际请求的模型; - 通过仓库自带的 capability fetcher 注入点(createFullRegistry)走公网 取数,能力体(校验、脱敏、摘要、溯源)原样执行; - 另起一个全新进程做「重启后读回」,其当前全局配置与历史清单故意不同, 证明历史运行仍报告它诞生时的配置。 另附一个 SSR 渲染脚本,用真正发布的 ManifestView/DiffView 组件与设计 令牌产出 Run Info 的 HTML/文本证据(本机无法拉起 Electron 截图)。
按仓库既有验收约定(docs/acceptance/<主题>/ + docs/<主题>-test-report.md) 提交现场验收的证据与报告。 验收覆盖 issue helsome#21 中 fixture 无法满足的两项: 1. 两次真实生产 Deep Research 运行,刻意改动 model 与 budget,diff 精确反映; 2. 全新进程(当前全局模型与历史不同)重启后读回历史 Run Info,配置未被覆盖。 取数经仓库自带的 fetcher 注入点改用公开源(Yahoo Finance chart API + NYT Business RSS)替代未安装的 Longbridge CLI,报告与 verification.json 均显式记录 该替换,不声称使用过 Longbridge。
durable research recovery 的 settled() 用固定 400 × 5ms 迭代数作轮询 预算;在饱和的 CI runner 上,每轮都要经磁盘读 run 记录,会在健康运行 settle 之前耗尽迭代数,表现为 'Run did not settle'。service.test.ts 里 waitForTerminal 已为同类问题改用墙钟预算(5s)并附注释,此处对齐同一 做法。
5 tasks done
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
改动说明
为每次 Agent / Deep Research run 持久化一份 immutable、machine-readable 的 manifest,记录当时实际生效的运行配置,使任何历史报告都能回答「当时到底是用什么配置跑出来的」。
按包拆分:
RunManifest/RunManifestContext/RunManifestContextPatch/RunManifestDiff等类型,覆盖 provider/model identity、实际生效的 model params、prompt version/hash 与来源、agent/workflow strategy、enabled tools(含 capability)、search/retrieval provider 与 routing、feature flags/runtime mode、app/build/git 版本、budget(含effective/clamped)与 eval 上下文(与 [Eval] Add Gold Case dataset and real end-to-end evaluation harness #15/[Runtime] Add run budgets and runaway-agent safeguards #17 对接);Run与ResearchRunSummary增加可选manifest字段;新增AGENT_WORKFLOW_ID。captureRunManifest在 run 创建时快照配置;redactManifestSecrets递归替换 secret 形状的键(apiKey/secret/token/credential 等);diffRunManifests按model / prompt / tools / config / versions分组产出结构化差异;exportRunManifest输出缩进、已脱敏 JSON;manifestToLangfuseMetadata由清单派生 Langfuse trace metadata(与 [Eval] Integrate Langfuse tracing and evaluation for Agent / Deep Research runs #14 对齐)。getRunManifest/exportRunManifest/compareRunManifests/getResearchManifest/compareResearchManifests;main / preload / renderer client 全链路暴露。diff 在主进程计算(渲染进程不引入@finagent/shared)。不可变性:manifest 只在 run 创建时写入一次,
execute阶段从不改写。因此应用重启或全局配置变更后,历史 run 仍展示其诞生时的配置,而非当前设置。secret 在采集阶段就不会进入 manifest(另有一层递归脱敏兜底)。把「已声明但未填充」的字段补齐
首版里
budget/strategy/evaluation三个字段在 schema 中存在,但实际没有采集路径。已补齐,使 issue 要求的每一项都真正落到 manifest:relevant budget/config(与 #17 对接)defaults/ceiling/overrides/effective/clamped一并写入清单,记录 run 实际遵守的上限而不只是请求值。非法预算在写入前 fail loud,不再留下半创建的 run。Deep Research 同样记录其 research 预算。eval dataset / case id / dataset version(与 #15 对接){ datasetId, caseId, datasetVersion }写进清单。agent/workflow strategy versionAGENT_WORKFLOW_ID+ 随包版本)。Deep Research 用StrategyId覆盖id,version记录「策略解析出的能力计划」的 SHA-256(内容寻址):同一策略稳定、计划一变即变,两次行为不同的运行绝不会共用同一个策略版本。与 #14 Langfuse metadata 保持同一 run identitymanifestToLangfuseMetadata(manifest, extras)成为唯一映射点:清单runId即 Langfuse 的folioRunId(也是 trace id),trace 同时带上 model/provider/strategy/prompt version/gold case,trace 与本地清单可互相定位。回读确认值优先,requestedModel/requestedProvider单独保留,不会被读成「实际跑的模型」。同时把「清单上下文」从调用点收回到 kernel:
RunManager新增getRunManifestContext,宿主注入一次,所有运行入口(Copilot run、评测直接调用 kernel 的 run)都落一份真实清单,而不是空 fallback。单次调用只补充自己负责的字段(评测补 gold case)。关联 Issue
Closes #21
验收:两条真实运行项(本 PR 已提供真实证据)
issue #21 里 fixture 无法满足的两条验收项,已用
apps/electron/e2e/run-manifest-acceptance.ts跑通。脚本只用真实组件、不含 fixture:真实AgentKernel+ResearchService(生产研究路径)、真实 DeepSeek HTTP 流式调用、经仓库自带的 capability fetcher 注入点(createFullRegistry)走公网取数(能力体——校验/脱敏/摘要/溯源——原样执行)。完整报告见docs/run-manifest-test-report.md。1) 两次真实 Deep Research run + 刻意改动配置 → diff 精确反映
两次运行刻意改动 model(
deepseek-flash→deepseek-v4-pro)与 budget(modelCalls3 → 6),其余维度保持不变:prompt/tools/versions保持false,说明 diff 是有选择性的,不是「有差异就全标红」。两次运行都真实完成取数(market.quote、market.kline、company.profile、research.news),状态partial(无真实等价数据源的 12 个能力显式unavailable)。provider 回显的apiModel与请求模型一致,证明清单记录的就是实际跑的模型。2) 重启后读回历史 Run Info → 仍报告诞生时的配置
第三个子进程是全新进程,其当前全局模型为
deepseek-v4-pro,却读回历史 run A(诞生于deepseek-flash):deepseek-v4-prodeepseek-flashpreserved: true(未覆盖)证据产物
docs/acceptance/run-manifest/:verification.json、两次运行的 manifest、JSON export、manifest-diff.json、重启读回载荷、provider 用量,以及 Run Info 的 HTML/文本视图。两个 HTML 由apps/electron/e2e/render-run-info.ts用真正发布的ManifestView/DiffView组件渲染(颜色取自渲染进程自身的index.css设计令牌),即应用实际展示的视图。测试报告(正式审核前必填)
环境
upstream/main@ba5dcdf402bd92(验收产物记录的就是这个 revision)实际执行命令与结果
与改动对应的验证(核心行为)
packages/shared/src/kernel/run-manifest.test.ts(13 项):captureRunManifest快照与不修改入参、默认 tools、secret 不入 manifest;redactManifestSecrets递归脱敏且保持结构;diffRunManifests忽略身份锚点、按工具名比对、分组标记;exportRunManifest输出脱敏 JSON;hashManifestInput稳定。packages/shared/src/kernel/run-manager.test.ts新增 8 项:manifest 采集并持久化;同一 session 内两次 run 的 manifest 互不覆盖(不可变性);无上下文时默认tools: []与runtimeMode: 'pi';预算解析结果(含 ceiling clamp 与clamped)写入清单;未配置预算时不写 budget;宿主基础上下文与单次调用 override 合并;基础上下文抛错时降级到 fallback 而不阻塞 run。packages/shared/src/evaluation/langfuse/metadata.test.ts(4 项):manifestToLangfuseMetadata使folioRunId === manifest.runId并携带 model/provider/strategy/promptVersion;评测清单派生出run_kind:evaluation与gold_case:/dataset:tag;回读值优先且 requested 值不会被误读为实际模型。packages/shared/src/research/service.test.ts新增 2 项:Deep Research 清单记录 research strategy id(优先于宿主默认 agent 工作流)与解析后的预算(含clamped);策略版本内容寻址——不同策略的计划产出不同版本,避免清单 diff 把行为不同的策略误判为相同。packages/shared/src/evaluation/experiment-service.test.ts新增 1 项:评测运行把 gold case / dataset version 传给 kernel 的清单上下文。packages/ui/src/components/kernel/RunInfoPanel.test.tsx(3 项):manifest 人可读渲染 + 脱敏 JSON 导出内容;结构化 diff 的 before → after 与分组标记;无差异时渲染为「一致」。已知失败 / Baseline(如有)
本 PR 相关的 focused tests、typecheck 与现场验收 全绿。
首轮 CI 的 Focused tests 曾失败一次:
kernelHost单测用mock.module('@finagent/shared', ...)提供了部分导出,本 PR 让 kernelHost 新增了diffRunManifests/exportRunManifest导入后,mock 需要同步补齐,否则 bun 的 ESM 链接会整文件报Export named ... not found。已修复并复跑通过;本次新增的manifestToLangfuseMetadata导入也已同步补进该 mock。langfuse.test.ts的 1 项失败为本机既有失败:已 stash 本 PR 改动在干净基线上复现同一失败;CI 中该文件通过。属本地环境差异,非代码问题。apps/electron/e2e/下 2 个既有脚本的类型错误(quote-provenance-live-acceptance.ts:192的 unionpayload、research-recovery-kernel.ts:139的ReadableStream异步迭代)在main上即存在,且仓库根tsconfig.json只 includepackages/*/src、apps/*/src,e2e 目录不参与 CI typecheck。本 PR 新增的两个 e2e 脚本在同等设置下类型干净。修复一个既有 flake:CI 的 Focused tests 曾在
durable research recovery > fails safely and preserves a version checkpoint报Run did not settle。该用例用迭代数(400 × 5ms)作轮询预算,在饱和的 CI runner 上会在健康运行 settle 之前耗尽迭代数。本仓库在service.test.ts里已为同类问题做过「迭代预算 → 墙钟预算」的修复并附注释,此处把同一修复应用到recovery.test.ts(2s → 5s 墙钟)。同一 commit 的 advisory 全量跑与本地复跑均通过,指向时序 flake 而非确定性失败。环境基线说明(与本 PR 无关):Windows 上 bun 的符号链接创建受限(无开发者模式),
bun install会静默不建工作区链接,导致signal-exit、zod(被解析成 4.4.3,而 lockfile 是 3.25.76)等包解析到错误版本。本机用 directory junction 复刻 hoistednode_modules后即恢复;这是环境问题,不是代码问题,origin/main上同样存在。已提供实际测试命令与 pass/fail 结果
已说明测试环境
如果存在已知 baseline / 环境失败,已提供 main 对照或说明
核心改动已有对应 focused test / smoke / integration 验证
UI 截图(仅可见 UI 变化时必填)
本 PR 含可见 UI 变化(Deep Research 运行历史新增「运行信息」入口、Run Info 弹窗、勾选两次运行的对比视图)。
贡献者环境无法启动浏览器 / Electron(Mojo IPC channel 创建与管道子进程创建均 access denied / EPERM),无法提供真实窗口截图。作为替代,已用
renderToStaticMarkup把真正发布的ManifestView/DiffView组件渲染为静态 HTML,颜色取自应用自身的index.css设计令牌——它证明了视图的内容与布局,但不等于真实窗口的像素渲染:docs/acceptance/run-manifest/run-info-after-restart.html— Run Info 视图(重启后读回历史 run)docs/acceptance/run-manifest/run-info-compare.html— 两次运行对比视图本 PR 无可见 UI 变化(无需截图)
本 PR 有可见 UI 变化,已提供替代渲染证据(静态 HTML,非真实窗口截图)
本 PR 有可见 UI 变化,已提供修改后的 UI 截图
Scope / 后续
本 PR 交付 issue #21 的完整实现,两条真实运行验收项均已跑通并提供可复现证据(见上)。
需要诚实说明的范围限制:
verification.json里以substitutedFor显式记录了该替换。其余 12 个能力无公开等价源,用notWired()显式抛错,因此两次运行均为partial。kernelHost单测覆盖。这不是打包测试。