Commit Graph

16 Commits

Author SHA1 Message Date
Blizzard 158fe094ab fix(hitl): 审批复盘轨迹补全 —— 中断不关 exec 流,resume 事件续录
现象:已完成的审批任务,复盘轨迹停在「已中断等待审批」、审批节点永远转圈,看着
像卡住(实际任务已 done、有输出)。

根因:任务中断时 Handle 的 defer tr.done() 给 exec 流发了 CompleteExec → 网关 exec
录制器关闭。resume 是另一次独立调用,其 exec 事件(审批通过/拒绝、续跑节点)发到
同一主题时录制器已关 → 没录进去。(token 流中断时特意没关,所以输出录到了;exec
流却被关了,不对称。)

- exec.go: execTracer 加 suspended 标志,done() 挂起时不关流。
- orchestrator.go: 中断分支置 tr.suspended=true(与 token 流一致)。
- ExecTrace.tsx: 前端兜底——运行已完成(phase done)时把悬挂的 waiting/running 节点
  收敛为 done,修旧任务(已 done、轨迹缺 resume 事件)的转圈假象。

live 验证:审批任务批准后复盘轨迹完整呈现 approval await→end「批准:放行」→
agent start→推理→end,审批节点不再转圈。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 16:57:11 +08:00
Blizzard 594be6a317 fix(desktop): 模型输出渲染图表 + Markdown 支持表格/代码围栏;ReAct 步数提至可配 12
针对运行页输出的两个渲染缺口 + 一个节点报错:
- 图表:模型输出走 chart 块分段渲染(文本 Markdown,```chart 块用 ChartView 出图),
  不再把图表 spec 显示成原始代码。
- 表格:轻量 Markdown 组件原本不支持 GFM 表格(| … | 显示成原始竖线)与 ``` 围栏代码,
  现补上:表格解析成 <table>、围栏渲染成 <pre>。
- ReAct 步数:reactMaxStep 由常量 8 改 env 可配(REACT_MAX_STEP,默认 12)。研究型任务
  (搜索→抓取→推理多轮)8 步偏紧易触顶报 exceeds max steps;提到 12 覆盖多数。

tsc+vite 通过,dispatcher build/vet 绿;wails 重启加载。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 17:33:58 +08:00
Blizzard ca7ce4c26f feat(desktop): 亮/暗主题切换 —— 默认亮色,一处令牌驱动全 app 换肤
把高频硬编码色(ink 表面 / line 边框 / slate 文字)重定义为 CSS 变量(RGB 三元组,
保留 /透明度 修饰符),:root(亮) 与 .dark(暗) 两套值切换——改 tailwind.config + index.css
两处即让全 app 换肤,无需逐文件迁移。

- 亮色走 shadcn 中性灰(zinc:zinc-50 底/白卡/zinc-200 边/zinc-900 字);
  暗色精炼为中性 zinc 暗(替代原偏蓝 ink),顺带提质感。
- lib/theme.ts:useTheme + applyInitialTheme(main 启动前设类,避免首屏闪烁)+ localStorage 持久化,默认亮色。
- TopBar 加 Sun/Moon 切换钮;滚动条/输入控件 color-scheme 随主题。
- 修亮色下会失效的 bg-white/5 → bg-ink-800(Tabs/Badge/ExecTrace 的中性微底);
  模态遮罩 bg-black/55 两模式皆宜,保留。

验证:tsc + vitest 48 过 + 生产构建通过(var 色全解析)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 10:39:36 +08:00
Blizzard 592b2a3d97 feat(tools): chart 图表工具 —— 工具产出 JSON spec,前端 SVG 渲染(职责分离)
按「工具只产数据、渲染交前端」设计:
- 后端 chart 工具(mcp-go):校验并返回规范化图表 JSON(type=bar/line/pie + labels + series,
  校验类型/长度一致/pie 取首系列)。工具说明指示 agent 用 ```chart 围栏原样包裹返回的 JSON。
- 前端:lib/chartspec.ts 从输出抽取 ```chart 块(解析失败回退为文本不丢内容);
  components/ChartView.tsx 自绘 SVG 柱/线/饼图(无第三方图表依赖);
  BottomDrawer 输出区含图表块时分段渲染(文本 + SVG),否则纯文本。

测试:前端 chartspec 单测 12 例(isChartSpec 校验、分段抽取、非法块回退、多块、hasChart);
tsc 干净,vitest 48 过。live 自主 agent:chart 工具产出 {"type":"bar",...},
agent 正确用 ```chart 围栏嵌入答复,前端据此渲染。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 17:24:41 +08:00
Blizzard 16a6c4b1aa feat(hitl): 人工审批中断(Eino Phase D)—— 审批节点暂停→批准续跑/拒绝中止
专用「审批」节点方案,全栈打通。

后端:
- contract:TaskWaiting/TaskRejected 状态 + ApprovalSubject/ApprovalDecision。
- bus:PublishApproval + WaitApproval(订阅决定主题,带超时);消费者 AckWait
  30s→15min(阻塞等人审期间消息未 ack,否则重投成重复任务)。
- dispatcher:ApprovalWaiter 接口 + approvalNode——执行到审批节点发 await 事件 +
  置 waiting,阻塞等决定。批准→回 running 放行下游;拒绝/超时→errRejected 哨兵→
  剪下游→rejected,优雅收尾不计熔断。超时安全默认拒绝。
  taskExecTimeout 3→10min(审批5 < 执行10 < AckWait15)。
- 网关:POST /tasks/:id/approve(仅 waiting 态受理,幂等)。

桌面端:
- Studio 新增「人工审批」节点(nodeCatalog,可填标题/说明)。
- run.ts pendingApproval() 从 exec 流派生待审中断 + waiting 节点状态。
- BottomDrawer ApprovalBar:琥珀审批条(摘要 + 批准/拒绝 + 备注,调 api.approveTask)。
- ExecTrace waiting 状态灯。

验证:后端 curl 实测 waiting→批准→running→done;waiting→拒绝→rejected(下游未跑)。
前端 tsc + vitest 36 过(pendingApproval 4 例 + waiting 状态)。全模块 build+vet+test 全绿。
EINO_ADOPTION Phase D 标记 HITL 完成。

未覆盖:compose 路径(EINO_COMPOSE,默认关)的 approval 节点;桌面端审批条未在 GUI 实点。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 13:18:47 +08:00
Blizzard f37d046f2c test(desktop): 前端单元 + 关键组件测试(Vitest + RTL,31 例)
测试基建:vite.config.ts 加 test 配置(jsdom + setup),package.json 加
test/test:watch 脚本,src/test/setup.ts 引 jest-dom;tsconfig 把测试文件 exclude,
使 CI 现有 tsc --noEmit 不检查测试文件(仍绿),测试由 Vitest 自跑(先不接 CI)。

覆盖(31 例 / 4 文件):
- dsl:exportDsl 节点/边映射 + config 兜底 + branch 真假边 sourceHandle 条件;
  validate 空画布/孤立节点/必填项缺失。
- version:isNewer 版本比较矩阵;checkUpdate 有更新/同版/旧版/404限流/离线异常;
  openExternal Wails / 浏览器双路径。
- run:deriveNodes start→running、end→done+耗时、error、error 不被 start 覆盖、
  info 累计 notes、首现顺序、label 更新。
- UpdateBanner(RTL):无更新不渲染、有更新显版本+点下载调 openExternal、点忽略消失。

小改:version.ts 导出 isNewer(原私有)以便直接测版本判定矩阵。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 11:53:54 +08:00
Blizzard 8c980d2b37 feat(desktop,ci): GitHub Releases 分发 + 桌面端检查更新
让桌面端像开源项目一样用 GitHub Releases 分发,旧版用户自动获知更新:
- CD:.github/workflows/release.yml —— 打 vX.Y.Z 标签触发,macOS(universal)/
  Windows(amd64) 用 wails build 出安装包,softprops/action-gh-release 发布到
  GitHub Release(GOWORK=off,因 desktop 不在工作区)。
- 桌面端检查更新:lib/version.ts(APP_VERSION + 查 GitHub /releases/latest +
  语义版本比较 + openExternal 走 Wails BrowserOpenURL);UpdateBanner 启动时
  检查,有新版顶部横幅「前往下载」。404/限流/离线均静默不打扰。

注:未签名/公证(macOS Gatekeeper / Win SmartScreen 需后续证书);release
workflow 需真实 tag push 才能验证(GitHub 侧运行)。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:26:02 +08:00
Blizzard a222ca5f9e feat(kb): 知识图谱换 react-force-graph-2d(活物理 + 拖拽 + 缩放)
把自建静态 SVG 力导向换成 react-force-graph-2d(canvas + d3-force)——真实物理、
可拖拽节点、滚轮缩放、悬停高亮邻域。实体图谱与笔记关系图同一组件,全部升级。

- GraphView 重写:ForceGraph2D,nodeCanvasObject 自绘节点(按度着色/缩放)+标签,
  linkCanvasObject 放大后显示关系文字,onNodeHover 高亮邻域、onNodeClick→onNode(笔记图跳转)。
- 调力:charge=-180 / link distance=52 拉开布局;onEngineStop zoomToFit 自动取景。
- 保持原 props(triples/height/onNode),三处调用零改动。

验证(Preview):笔记关系图渲染 笔记B/项目A概述/模块X 大节点 + 链接边、自动取景、可拖拽缩放。
(实体图谱在 default 库因累积了几十个测试实体显得密,新建干净库则清爽。)tsc+vite 通过;重建 .app。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:55:34 +08:00
Blizzard 10ac5a5277 feat(kb): 笔记可编辑(按 doc 替换重索引)+ 笔记关系图([[双链]])
Obsidian 化继续:笔记能编辑/新建,文档间 [[双链]] 连成可点关系图。

按 doc 重索引(编辑不重复累积):
- Milvus 加 doc 字段(旧 schema 自动重建);insert 带 doc;deleteDoc(kb,doc) 重入库前清旧块。
- Bleve 索引 id 含 doc + deleteDoc 按 kb+doc 清旧块。
- rag.Ingest(kb, doc, text):写入前按 doc 删旧块再写(Neo4j MERGE 仍幂等,附加式)。
- kb_ingest 工具加 doc 参数;gateway runIngest 把 doc 透传,forceDoc 支持编辑保持笔记名稳定。

编辑/新建:
- gateway POST /kb/note {kb,name,content}:落库 + 以 name 为 doc 重入库(替换旧块,搜索/图谱同步)。
- 前端 VaultPanel:阅读/编辑切换(textarea 预填原文,保存调 saveNote)、新建笔记、乐观更新。

笔记关系图:
- GraphView 加 onNode(节点可点);VaultPanel 阅读/关系图切换,关系图 = 文档间 [[双链]] 三元组
  力导向(点节点跳转该笔记)。

验证:curl 编辑 笔记B → 检索只返编辑后内容(旧块已清,不重复)。Preview:关系图渲染
笔记B—链接→项目A概述/模块X 且节点可点;编辑器预填原文可改可存。tsc+vite+后端 build 通过;重建 .app。

注:Milvus 加 doc 字段会触发集合重建(旧向量丢,文库原文在 PG 可重灌);Neo4j 图谱按附加式合并,
编辑删除的实体不会自动消失(图谱倾向增长)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:22:03 +08:00
Blizzard 55c85302b6 feat(kb): Obsidian 式文库 —— 笔记浏览 + [[双链]] + 反向链接(Tab 化)
把知识库做出 Obsidian 感:入库的每份文件/笔记留原文,可浏览、可读、可互链。

- store: sundynix_doc(owner+kb+name 唯一,存原文),SaveDoc(OnConflict 覆盖)/ListVault。
- gateway: runIngest 留存原文(文件用文件名、文本用首行作笔记名);GET /kb/vault?kb= 取文库(owner 隔离)。
- Markdown 组件:解析 [[名称]] / [[名称|别名]] → onLink 可点(Obsidian 双链)。
- KbView 改 Tab(入库 / 文库 / 检索 / 图谱):
  - 文库 = 左文档列表 + 右 Markdown 笔记([[双链]]点击跳转)+ 反向链接面板(扫全库 [[本笔记]])。
  - 检索、图谱各占整页;图谱放大到 460。

验证(Preview):入两条带 [[双链]] 的笔记 → 文库列出 2 篇 → 打开「项目A概述」渲染出可点的
[[模块X]][[模块Y]] + 反向链接显示「模块X」→ 点 [[模块X]] 跳转到该笔记、其 [[项目A概述]] 亦可点。
curl 证隔离:alice 取 wt 的 vault → 空。tsc+vite+gateway build 通过;重建 .app 重启窗口。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 15:06:31 +08:00
Blizzard 84efa0a11c feat(desktop): 命令面板 ⌘K —— 键盘优先工作站入口
Pillar ① 交互骨架升级第一步:全局命令面板。

- components/CommandPalette.tsx:⌘K/Ctrl+K 唤起,搜索 + 多词子串过滤 + 分组(页面/动作)
  + 键盘上下选择 + Enter 执行 + Esc 关闭 + 选中项滚动入视野,纯前端两模式通用。
- App:全局 keydown 监听切换面板;命令清单(8 个页面跳转 + 生成报告/入库知识/新建编排动作)。
- TopBar:加「搜索与命令 ⌘K」触发 pill。

验证(Preview):⌘K/点 pill 唤起 → 输入“报告”过滤出 2 条 → 点「前往·报告生成」自动跳转
报告页并关闭面板。tsc + vite build 通过;重建 .app 重启原生窗口。

注:OS 级全局唤起(⌥Space 后台常驻 + 系统托盘)受 Wails v2 主线程模型限制(与
golang.design/x/hotkey 抢主线程冲突),留作 Wails v3 / cgo 助手的后续,不在本次。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:32:36 +08:00
Blizzard 72e008bfe8 feat(kb): 入库可视化做厚 —— 文件解析/知识抽取过程 + 力导向知识图谱
把"进度条"升级成可观测的入库工作台,回应三点诉求:解析过程、知识抽取过程、丰富图谱。

- contract: IngestEvent 加 Preview(解析文本预览)+ Triples[]TripleView(抽出的三元组)。
- 后端回流:rag.Ingest 抽实体阶段把 LLM 抽出的三元组实时回流(边出现边渲染);
  gateway 解析完成回流文件类型 + 文本预览片段。
- 前端 GraphView.tsx:零依赖自建力导向布局(斥力+边弹簧+居中静态收敛),实体=节点
  按度着色(枢纽紫/关联青/叶子)、关系=带标签边、hover 高亮邻域、节点过多按度裁剪。
- 前端 KbView 重做:入库从"阶段徽标+进度条"→竖向时间线(解析预览/切块块/向量化进度/
  抽取知识三元组 chips + 实时小图谱逐步浮现);右侧知识图谱从扁平列表→GraphView,
  入库完成自动刷新整库图谱。

验证(Preview):入库一段多事实文本 → 时间线逐阶段点亮、抽出 17 条三元组实时浮现、
右侧力导向图渲染 sundynix-agentix/知识库 为枢纽 + 带标签关系边。tsc+vite+后端 build 通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 14:22:50 +08:00
Blizzard d5ae2f71d4 feat(desktop): 工业化升级 D —— 内容可信(Markdown 渲染 + 健康五灯全真)
- components/Markdown.tsx:零依赖、行级 Markdown 渲染(# 标题 / **粗** *斜* `码` /
  - 与 1. 列表 / > 引用 / --- 分隔 / 段落),流式安全(每 token 重渲染容忍残缺)。
  报告正文与运行输出从裸 <pre> 换成真排版,瞬间像份报告。
- 健康聚合:mcp-go 加 rag.Status() + health 工具(milvus/neo4j/embedding 就绪);
  gateway GET /api/v1/health 聚合 gateway/nats/db/redis(本地) + milvus/neo4j(经 mcp-go);
  health.ts 轮询 /health,TopBar 五盏灯(Gateway/DB/NATS/Milvus/Neo4j)从"灰=未知"变真实绿/红。

验证:浏览器(Preview)跑报告——正文以标题/有序列表/引用/分隔线/二级标题排版呈现;
五盏灯全绿(/health 返回 db/gateway/milvus/nats/neo4j/redis 全 true)。tsc + vite build + 后端 build 通过。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 17:34:54 +08:00
Blizzard 72bd43965f feat(desktop): 工业化升级 A —— 设计系统地基(primitives + lucide + 语义令牌)
把"手搓内联 class + Unicode 字符图标"换成统一组件与真实图标,为后续工业化打底。

- 依赖:装 lucide-react(描线图标,按需 tree-shake)
- 令牌:tailwind.config 加语义色 brand/accent/success/warn/danger + 圆角档位;
  强调色字面量(violet/cyan/emerald…)收敛到令牌,便于整体换肤
- primitives(src/ui,零重依赖自建):Button/Input/Textarea/Select/Field/Card/Panel/
  Badge/Dot/Tabs/Skeleton/EmptyState/Dialog/Toast(+useToast)/cn,桶文件统一引入
- 迁移:TopBar/LeftNav/BottomDrawer + Home/Report/Runs/Kb/Placeholder/ExecTrace/
  MemoryPanel/StudioView 全部换 primitives + lucide 图标;导航/能力卡/按钮告别
  ▤◆▣▦ 等 Unicode 字符;错误改用全局 Toast;空状态用 EmptyState
- App 包 ToastProvider

验证:tsc + vite build 通过;浏览器(Preview)走查工作台/报告页——真实图标、统一卡片/
按钮/输入;跑报告端到端正常(执行轨迹 lucide 状态图标点亮、章节耗时/字数/检索片段、
完成弹 Toast + 下载 Word)。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 16:39:42 +08:00
Blizzard cdc5b3a847 feat(observability): 执行可视化 — 节点级实时轨迹(运行·观测)
把任务执行做成可观测:Dispatcher 在每个节点/阶段发结构化 ExecEvent,
经独立 NATS 通道回流,前端逐节点点亮(状态/耗时/工具入参产出)。

- shared: contract.ExecEvent + ExecSubject(sundynix.exec.<id>,与 Token 流分流);
  bus.PublishExec/CompleteExec/SubscribeExec(core NATS,复用结束头)
- dispatcher: execTracer(自增 Seq 保序 + span 自动计耗时);
  Orchestrator 加 ExecSink;通用图(init 召回 / 各 tool 入参→产出 / prompt / model
  首token+token数)与报告编排(规划大纲 / 各章并行 start-end / 渲染)全程埋点
- gateway: SubscribeExec + GET /tasks/:id/exec SSE(与 token 流并行)
- desktop: streamExec + deriveNodes(按 node 归并 start/end/error/info);
  复用组件 ExecTrace(竖向轨道,按 kind 着色,运行中脉冲灯);
  新 RunsView(运行·观测:轨迹+输出双栏);BottomDrawer 轨迹/工具调用 tab 接真实数据;
  ReportView 加执行轨迹栏;左导航「运行」置就绪

实测:
- 报告任务 /exec:规划(2680ms,4章) → 4 章并行(seq 交错,各~7-8s 重叠=真并行,
  每章带 docs 知识库检索预览+成稿字数) → 渲染(docx 落盘)
- 通用图 /exec:tool:kb_search(678ms,入参→Milvus 产出) → prompt(2消息) →
  model(首token 860ms / 4 tokens)
- 浏览器(Preview):报告页执行轨迹逐节点点亮、章节带耗时/字数/检索片段,完成后下载 Word

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:29:28 +08:00
Blizzard c7a02c3905 feat: 初始化 sundynix-agentix 分层式 AI Agent 平台脚手架
5 层 + 1 条 NATS 零拷贝消息总线的 monorepo(Monolith First → Microservices Morph B)。
纵向主干(任务流 + Token 流回流)已真实跑通,横向各层能力为带注释的桩。

已贯通(real code):
- sundynix-shared: 共享契约 + JetStream/core NATS 真实收发(bus) + 内嵌 NATS(devnats) + e2e 测试
- sundynix-gateway: Gin 接入 + DSL 解析组装 + NATS Publish + SSE 流式输出
- sundynix-dispatcher: NATS 消费 + Eino Orchestrator 流式回流 + 熔断器 + LLM Pool 占位流式
- 链路: HTTP POST → DSL → sundynix.tasks.* → Dispatcher → Token 经 sundynix.streams.<id> 回流 → SSE
- 基础设施: docker-compose(nats/postgres/redis/neo4j/milvus) + Makefile(make demo/e2e)

待填(桩):
- Eino 图编排 compose.NewGraph、LLM Pool 接 vLLM/Ollama
- Gateway store 换真实 pgx/redis
- sundynix-mcp-go: Bleve+Milvus+Neo4j 混合检索 / UniOffice / 外部 API
- sundynix-mcp-py: gVisor 沙箱 / MinerU(PaddleOCR) / Docker 解释器
- sundynix-desktop: React Flow 画布 → DSL 导出 → SSE 展示
2026-06-10 11:00:29 +08:00