Commit Graph

12 Commits

Author SHA1 Message Date
Blizzard 760ca06667 feat(desktop/studio): Tier1 编排画布主题化 + 节点精修(产品灵魂打磨)
react-flow 此前 colorMode 写死 dark、背景/连线/控件全用库默认,换肤下不协调。改为:
- colorMode 绑定当前主题 → 控件/连线/手柄/选区自动随亮暗切换。
- Background 点阵色、MiniMap 遮罩随主题;隐藏库水印(proOptions.hideAttribution,更干净)。
- index.css 精修 react-flow:控件(细边/圆角/themed hover)、连线(中性描边+选中紫)、迷你图边框,对齐设计系统。
- TypedNode:卡面落到表面色(ink-850)、选中环用 brand 令牌(替硬编码紫)、加 hover 描边、手柄themed。
- 工具栏/调色板/检查器已用新 Button + 令牌类,自动一致。

tsc + 生产构建通过;桌面端已 HMR。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-25 12:47:48 +08:00
Blizzard d7c6fab933 fix(hitl): 审批弹窗可靠化(状态轮询兜底)+ 审批节点入调色板并改橙色
两个实测发现的问题:
1. 审批条偶发不弹、任务卡「运行中」:exec 的 await 事件走实时 core NATS(无回放),
   UI 的 EventSource 晚连一拍就漏掉 → 永远不弹审批。改为轮询持久化的任务状态
   (GET /tasks/:id,每 1.5s),status==waiting 即弹审批条,不再依赖易抢跑的 exec 事件;
   exec 事件仅用于丰富摘要。新增 api.taskStatus + RunState.lifecycle/detail +
   App.tsx 轮询 + 终态停轮询;BottomDrawer 审批条触发改以 lifecycle==waiting 为准。
2. Studio 左侧调色板没有「人工审批」节点(只加了 NODE_KINDS,漏了 NODE_ORDER),
   且其配色与「输入」同为 amber 难以区分:补进 NODE_ORDER(分支与并行之间),
   配色改 orange(橙)与输入的 amber(琥珀金)区分。

验证:桌面端 live 重启确认审批条可靠弹出 + 批准/拒绝两条路径正常;左侧节点列表与
画布配色区分清晰。tsc 干净 + vitest 36 过。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 14:51:37 +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 95f4752d9e feat(desktop): Agent 节点加「自主工具 (ReAct)」开关
前端补上 Phase B 的 UI 接缝:agent 节点 nodeCatalog 增 autonomous checkbox
(默认 false)。勾选 → exportDsl 带 config.autonomous=true → dispatcher
走 ReAct 自主调工具。此前能力在后端但画布点不到。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 14:29:37 +08:00
Blizzard 1bd187874d feat(orchestration): Phase2 —— map 真并行 fan-out + branch 真/假边标签精确选路
Phase1 让引擎按图执行后,本轮补上两块:

1) map 并行 fan-out(dispatcher)
   - map 节点:planItems 把主题拆成 3–6 子项 → 复用 report 的 writeSections
     有界并发(4)逐项撰写 → 结构化 sections 存黑板 + 拼进 answer + 流式呈现。
   - 检索节点记下 owner 作用域库名(b.kb),供 map 各项并行检索复用。
   - render 节点优先用 map 产出的多章 sections 渲染,否则整段成稿当单章。

2) branch 真/假边标签(前端 + DSL + dispatcher)
   - TypedNode:分支节点渲染两个出口手柄 真(绿)/假(红),连线各带 sourceHandle。
   - exportDsl / TaskDsl:边导出携带 sourceHandle。
   - dispatcher dsl.Edge 增 SourceHandle;branchNode 优先按 true/false 标签精确
     选路,无标签的旧图退回"出边顺序"约定,向后兼容。

实测(gateway+dispatcher+DeepSeek 真跑):
- map:input→map→render,DeepSeek 拆出 5 章并行撰写(347–512字),trace 见
  section:0..4 并发 + 有界并发(section3 等槽);render 因 mcp-go 不在优雅降级 ✓
- branch 标签:把 true 边故意列第二位,条件真仍走 true 标签的分支A、假走分支B,
  证明按标签而非边序选路 ✓
- 桌面端:分支节点正确渲染 真/假 两手柄,无 console 报错 ✓

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 14:01:51 +08:00
Blizzard e1cac0eb69 fix(studio): 载入编排防御兜底,避免损坏图导致黑屏
点击「我的编排」里某条若其 graph 缺 position/type/data(旧数据/外部写入),
React Flow 缺 position 会直接崩成黑屏。loadGraph 改为对每个节点兜底:
补 type=typed、缺失或非法 position 给网格默认坐标、data.kind 不识别则回退 output、
补 label/config/status;边过滤掉两端不存在或缺 source/target 的,自动补 id。

验证(Preview):故意存一条节点全缺字段的「损坏测试」→ 载入渲染为 2 节点·1 连线、
渲染器正常(不再黑屏);正常「尽调问答 Agent」4 节点·3 连线照常载入。tsc+vite 通过;重建 .app。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:28:21 +08:00
Blizzard 4bf614a07c feat(studio): Agent 编排服务端保存 + 我的编排列表(owner 隔离)
编排好的 Agent 现在可命名保存到服务端、跨会话可见;左侧「我的编排」列出本人全部。

- store: sundynix_agent 表(owner+name 唯一,Graph=React Flow {nodes,edges} JSON 含布局,
  UpdatedAt);ListAgents(最近在前)/SaveAgent(OnConflict 覆盖图+时间)/DeleteAgent。AutoMigrate +Agent。
- gateway: GET/POST/DELETE /api/v1/agents(owner 隔离,身份取自 X-User-ID)。
- 前端:api listAgents/saveAgent/deleteAgent;StudioView 左面板下半区「我的编排(N)」列出本人编排,
  点击载入(含布局)、悬停删除;工具栏 编排名+保存(服务端),去掉 localStorage 模板。

验证:curl 保存「合同审查流程」→ wt 列表含之,alice 列表为空(隔离)。Preview:示例图填名「尽调问答
Agent」保存 → 左「我的编排(2)」即时出现两条、可点载入。tsc+vite+gateway build 通过;重建 .app。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:23:03 +08:00
Blizzard 337d4d7619 feat(studio): 完善编排 —— 检索接本人知识库 + 真实模型下拉 + 模板/示例
把编排从"演示桩"接到真实平台:检索节点查本人 owner 隔离的知识库,节点下拉用真实数据。

- dispatcher:makeToolNode 用 task user_id 给检索类工具的 kb 加 owner 前缀("uid/kb"),
  编排里的「检索(RAG)」节点真正命中本人知识库(与隔离对齐)。
- 前端 StudioView:加 identity,载入 /kb/list 与 chat 模型作为「检索.kb」「Agent.model」下拉真值;
  Inspector 支持 dynamicOptions(无真值时提示去创建)。
- 编辑体验:示例(一键加载 输入→检索→Agent→输出 可运行图)/ 清空 / 模板名+保存(localStorage,
  含布局)/ 载入下拉;ReactFlow deleteKeyCode 支持 Del/Backspace 删节点。

验证:示例图运行 → gateway 发布任务 → dispatcher 编译 → mcp-go 日志 `tool=wiki_search
args=[kb:wt/default ...]`(kb 已按 owner 作用域)→ 命中本人库 → DeepSeek 流式作答;
底部抽屉 完成 ✓ · 工具调用 1。tsc+vite+dispatcher build 通过;重建 .app。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 16:14: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 2291f60380 feat(desktop): 深色 AI 控制台视觉改造 + 工作台仪表盘
桌面端从扁平 dev 工具风改为深色高端 AI 控制台:分层表面 + 紫青强调 + 微光 +
首页仪表盘,提升第一印象与吸引力。

- 设计 tokens: tailwind ink 分层调色板 + glow/card 阴影; index.css 深色基底 +
  品牌渐变 + 深色滚动条
- shell: TopBar(品牌渐变+毛玻璃+发光健康灯) / LeftNav(激活态紫色高亮+左光条) /
  BottomDrawer(深色+状态色)
- 新 views/Home 工作台仪表盘: 渐变 hero + 4 状态卡 + 3 能力卡 + 快速开始(默认首页)
- 画布: TypedNode 深色节点卡; StudioView ReactFlow colorMode=dark + 深色工具栏/面板/
  MiniMap; Inspector 深色表单
- KbView/MemoryView/MemoryPanel/Placeholder 全深色化; 进度条改紫青渐变
- 纯前端改造, npm build✓; 浏览器验证: 仪表盘 + 编排画布深色呈现

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-11 16:56:04 +08:00
Blizzard aa574a8cb2 feat: DSL→对话编译 — Eino 图用节点字段而非整段 JSON 喂模型
dispatcher 真正解析 DSL 图:input 节点文本=用户消息,agent 节点 system=系统提示词,
不再把整段 DSL JSON 当 prompt 丢给模型。

- dispatcher/internal/dsl: Compile(graph)→Plan{System,Query,Tools}
  (input.text/agent.prompt→query, agent.system→system, tool.tool→tools, 兜底默认)
- eino/graph: recall 调 dsl.Compile,模板加 {system}(Agent 系统提示词+画像注入)
- eino/orchestrator: 写回历史落真实 query 而非 DSL 原文
- frontend nodeCatalog: input 节点改 text 字段(用户输入,必填),检查器可编辑
- 验证: 全模块+前端 build✓; 真实 DeepSeek——curl DSL(input '中国首都?')→'北京';
  真实浏览器——加 input 节点输入'NATS是什么'→运行→DeepSeek 简洁正确作答

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 16:34:38 +08:00
Blizzard 61c1177eba feat(desktop): MVP 驾驶舱外壳 + 类型化节点 Studio + 运行抽屉
按 desktop-ui-plan.md 落 MVP:五区外壳 + 编排 Studio + 底部抽屉 + 健康灯。

- shell: TopBar(垂直切换/健康灯[Gateway/DB 实时,余规划]/身份会话) +
  LeftNav(BUILD/RUN/MANAGE 分组,未就绪模块灰显) + BottomDrawer(输出/轨迹/工具调用/引用/评测)
- studio: 类型化节点目录(输入/检索RAG/Agent/工具/记忆/分支/并行/汇聚/渲染/输出,
  按类配色) + 自定义 TypedNode(状态徽标) + Inspector(按类型渲染配置表单) +
  校验(孤立节点/必填项) + 运行
- views: MemoryView(复用偏好面板) + Placeholder(规划中模块,露出 IA 与依赖)
- lib: run(运行状态机) + health(轮询 billing) + dsl(导出类型化 DSL + validate)
- 删旧 AgentCanvas(被 StudioView 取代)

验证: npm run build(tsc+vite)✓; 真实浏览器跑通——加类型化节点→校验(标出孤立)→运行
→SSE 注入画像(老王)+历史 流入抽屉, 健康灯 Gateway/DB 实时绿

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-10 15:00:32 +08:00