feat(web): 角色关系图谱(灵感⑥缩减版/D4)

设定库人物 tab 新增 React Flow 关系图谱,仅用现有角色读端点数据
(CharacterRelationView={name,kind,note}):边按 name-join、kind 作中文
标签、节点按 role 上色,无 closeness/阵营(数据不存在,不硬造)。

- lib/characters/graphLayout.ts:纯逻辑(role→分组配色关键词映射 / 节点
  去空重名 / kind→标签+DEFAULT_RELATION_LABEL / 悬空边跳过并计数 / 自指
  跳过 / 互指无向去重 / @dagrejs/dagre 一次性确定性初始坐标、中心→左上、
  不可变更新)+22 单测。
- components/characters/RelationshipGraph.tsx:'use client',经 CodexPage
  dynamic(ssr:false) 挂载;显式容器高度 + import RF CSS + prefers-reduced-
  motion 关 fitView 动画 + 纸感 CSS 变量配色 + 悬空计数提示。
- 依赖:@xyflow/react@^12.11.2 + @dagrejs/dagre@^3.0.0。

无后端契约变更/迁移/gen:api。门禁:lint/typecheck 干净、vitest 565、
coverage lib 95.4%(graphLayout 97.6%)、build OK。
This commit is contained in:
Yaojia Wang
2026-07-06 17:38:58 +02:00
parent 7babb4854b
commit 3d2a8b8cee
9 changed files with 896 additions and 1 deletions

View File

@@ -365,3 +365,5 @@
- [2026-06-20] @backend 再扩 C3B0 **可控版**接上条新增 **`PUT /projects/{project_id}/chapters/{chapter_no}/injection`** `InjectionOverrideRequest{pinned:[{kind,name}], excluded:[{kind,name}], recent_n:int|null(1..20)}` 返回 `InjectionResponse`同上**新增回显字段 `pinned`/`excluded`**`selected[].reasons` 可含新值 **`author_pin`**)。语义pin 强制纳入并加 `author_pin` 理由 / excluded 强制剔除**优先于 pin**/ recent_n 覆盖近况回看章数GET injection **draft 流式端点**均先读同一覆盖再 `assemble(override=...)`,故「看到的=写章用的」(不变量 #6 作者兜底)。持久化:**新表 `chapter_injection`**迁移 `ad2c4c663daf`唯一 `(project_id,chapter_no)`复用 outline 行已否决`select_relevant_entities` `pinned/excluded` frozenset 入参`assemble` `override` 关键字参 `domain/injection_repo.py``InjectionOverride`/`EntityRef`/`SqlInjectionOverrideRepo`upsert flush 端点 commit)。→ 影响 @frontend `pnpm gen:api`F1 pin/排除控件 + recent_n 步进器)。
- [2026-06-18] @llm C1`Gateway.run()` 现消费 `LlmRequest.output_schema`——`OpenAICompatAdapter.complete` schema 非空时经 **instructor**(`create_with_completion(response_model=...)`) 取已校验 Pydantic 实例并填 `LlmResponse.parsed` schema `parsed is None`纯文本路径不变记账仍 **1 条 usage_ledger**/调用usage raw completion 提取)。`ProviderResult` 新增 `parsed` 字段结构化路径经可注入 `StructuredClient` Protocol fake测试不联网)。→ 影响 T2.2续审节点可直接 `gateway.run(req).parsed`)、未来所有结构化输出 Agent
- [2026-07-06] @frontend 前端依赖新增灵感 关系图谱缩减版 / D4**无后端契约变更 gen:api无迁移**`apps/web/package.json` `@xyflow/react@^12.11.2`React FlowMITpeer react>=17 兼容 R19+ `@dagrejs/dagre@^3.0.0`(一次性初始布局,自带 TS 类型)。`pnpm install``pnpm-workspace.yaml` 被 pnpm 自动追加 `minimumReleaseAgeExclude`@xyflow/react/@xyflow/system 供应链豁免)+ `pnpm-lock.yaml` 更新。新增 `lib/characters/graphLayout.ts`(纯逻辑:角色+relations→节点/边+dagre 布局,仅用现有 `CharacterCardView.relations={name,kind,note}`——**边按 name-join、kind 作中文标签、节点按 role 上色,无 closeness/阵营**,悬空边跳过并计数)+ `components/characters/RelationshipGraph.tsx``'use client'`,经 CodexPage `dynamic(ssr:false)` 加载,显式容器高度 + import RF CSS + prefers-reduced-motion 关 fitView 动画 + 纸感配色)。消费方:无(叶子特性,挂在设定库人物 tab