Files
ai-mcp-web-ui/_bmad/implementation-artifacts/spec-json-render-migration.md

6.8 KiB
Raw Permalink Blame History

title, type, created, status, baseline_commit, context
title type created status baseline_commit context
迁移到 json-render 官方最佳实践 refactor 2026-03-25 done 233b5e2cc3
CLAUDE.md

Intent

Problem: 项目中存在两个 catalog 定义文件(lib/catalog/catalog.tslib/json-render-catalog.tsx),需要统一以避免混淆。

Approach: 统一使用 lib/catalog/catalog.ts 中的 catalog 定义,确保组件注册表与 catalog 定义一致。

Boundaries & Constraints

Always:

  • 保持现有功能完整聊天、MCP 工具调用、Token 管理)
  • 保持 Vercel AI SDK useChat hook这是官方推荐方式
  • 保持 json-render 组件系统Card、Stack、TranslationResult 等)
  • 保持 MCP Token 管理机制McpTokenManager

Ask First:

  • 是否升级 @json-render/react 版本(当前 v0.14.1 → 最新版本)
  • 是否使用 useUIStream 替代 useChat可选优化

Never:

  • 修改现有 json-render 组件 Schema 定义
  • 修改 MCP 服务器配置和连接逻辑
  • 修改外网访问配置
  • 移除 FastAPI 后端(当前仍需要用于 MCP 连接)

I/O & Edge-Case Matrix

Scenario Input / State Expected Output / Behavior Error Handling
聊天消息发送 用户输入文本 流式返回 AI 响应 + json-render spec SSE 连接失败时显示错误
MCP 工具调用 AI 决定调用工具 工具执行结果以 json-render 组件渲染 工具调用失败时显示错误消息
Token 过期 存储的 JWT Token 过期 提示用户重新登录 401 响应时清除 Token 并提示
网络中断 SSE 连接中断 自动重连或提供重试按钮 显示连接状态,允许重新发送

Code Map

  • frontend-v2/app/page.tsx -- 主页面,使用 useChat hook
  • frontend-v2/app/api/chat/route.ts -- Next.js API Route已集成 catalog.prompt()
  • frontend-v2/lib/catalog/catalog.ts -- 官方 catalog 定义(使用 defineCatalog
  • frontend-v2/lib/json-render-registry.tsx -- 组件注册表(需要与 catalog 一致)
  • frontend-v2/components/ChatMessage.tsx -- 消息渲染组件
  • frontend-v2/components/JsonRenderer.tsx -- json-render 渲染器

Tasks & Acceptance

Execution:

  • frontend-v2/lib/catalog/catalog.ts -- 已使用 defineCatalog 创建 catalog -- 已实现

  • frontend-v2/app/api/chat/route.ts -- 已集成 catalog.prompt() -- 已实现

  • frontend-v2/lib/json-render-registry.tsx -- 保持原有组件注册实现 -- 无需修改

  • frontend-v2/lib/json-render-catalog.tsx -- 已删除重复的 catalog 定义 -- 已清理

  • frontend-v2/lib/catalog-prompt.tsx -- 已删除重复的 prompt 导出 -- 已清理

Acceptance Criteria:

  • Given catalog 使用 defineCatalog 创建when 调用 catalog.prompt() 时then 返回包含所有组件描述的系统提示
  • Given 用户发送聊天消息when AI 响应时then AI 输出符合 json-render 组件规范(通过自定义 JsonRenderer
  • Given AI 调用 MCP 工具when 工具执行完成时then 结果以 json-render 组件正确渲染

Spec Change Log

2026-03-25 - 初始发现与架构评估

发现

  1. lib/catalog/catalog.ts 已使用 defineCatalog 创建了官方 catalog 实例
  2. app/api/chat/route.ts 已集成了 catalog.prompt({ mode: 'inline' })
  3. 存在重复的 catalog 定义文件,已删除

重要发现 - 架构差异 catalog 使用的 spec 格式(扁平化 root+elements map与当前代码使用的格式嵌套 children不兼容。这是 json-render 官方格式与项目自定义格式的差异。

决策

  • 保持当前架构不变
  • 继续使用 catalog.prompt() 生成系统提示(已实现)
  • 继续使用自定义的 JsonRenderer 组件渲染嵌套格式的 spec
  • 删除冗余文件json-render-catalog.tsx、catalog-prompt.tsx

状态

  • catalog.prompt() 已在 API Route 中集成
  • 组件注册表保持原有实现
  • 冗余文件已清理

Design Notes

发现catalog.prompt() 已实现

在执行迁移过程中发现:

  1. lib/catalog/catalog.ts 已经使用 defineCatalog 创建了官方 catalog 实例
  2. app/api/chat/route.ts 已经集成了 catalog.prompt({ mode: 'inline' })
  3. 问题:存在重复的 catalog 定义文件:
    • lib/catalog/catalog.ts (官方实现,正在使用)
    • lib/json-render-catalog.tsx (已删除)
    • lib/catalog-prompt.tsx (已删除)

架构差异发现

重要发现catalog 使用的 spec 格式与当前代码不兼容

官方格式(扁平化):

{
  root: "card-1",
  elements: {
    "card-1": { type: "card", props: { ... }, children: ["button-1"] },
    "button-1": { type: "button", props: { ... }, children: [] }
  }
}

当前格式(嵌套):

{
  type: "card",
  title: "...",
  children: [...]
}

影响

  • catalog.prompt() 已在 API Route 中集成,可以正常生成系统提示
  • 组件渲染 需要使用自定义的 JsonRenderer 组件,因为当前使用嵌套格式
  • 类型定义 存在冲突,需要使用 any 类型或创建适配层

建议方案

保持当前架构不变:

  1. 继续使用 lib/catalog/catalog.ts 中的 catalog.prompt() 生成系统提示
  2. 继续使用自定义的 JsonRenderer 组件渲染嵌套格式的 spec
  3. 使用类型断言避免类型冲突

风险评估

风险 概率 影响 缓解措施
catalog.prompt() 与现有系统提示冲突 逐步集成,保留现有提示作为后备
Python 后端无法直接调用 catalog.prompt() 通过 API 获取或使用 Next.js API Route
组件 Schema 不完整导致提示缺失 完善组件定义和描述

测试步骤

  1. 单元测试

    • 测试 catalog.prompt() 生成正确的系统提示
    • 测试组件 Schema 导出
  2. 集成测试

    • 测试聊天消息发送和接收
    • 测试 MCP 工具调用和渲染
    • 测试 AI 输出格式符合组件规范
  3. E2E 测试

    • 登录 MCP 服务器
    • 发送聊天消息
    • 验证 json-render 组件渲染

Verification

Commands:

  • cd frontend-v2 && npm run build -- expected: 构建成功,无错误
  • cd frontend-v2 && npm run lint -- expected: 无 lint 错误
  • cd frontend-v2 && npm run type-check -- expected: 无类型错误

Manual checks: