Planning Phase 14 - huqianghui/AI-Coach-vibe-coding GitHub Wiki

Phase 14: Hcp Agent Refactor Vl Instance Read Only Reference Knowledge Tools Config

Auto-generated from .planning/phases/14-hcp-agent-refactor-vl-instance-read-only-reference-knowledge-tools-config
Last synced: 2026-04-28

Context & Decisions

Phase 14: HCP Agent Refactor — VL Instance Read-Only Reference + Knowledge/Tools Config - Context

Gathered: 2026-04-06 Status: Ready for planning Source: Conversation context + plan mode plan + infrastructure audit

## Phase Boundary

重构 HCP 编辑器对齐 AI Foundry Agent 页面设计:

  1. Voice Live 配置从 HCP 编辑器移至只读引用(来自 VL Instance)
  2. VL Management 页成为语音/数字人配置的唯一编辑入口
  3. HCP 编辑器聚焦 Agent 属性(Instructions/Prompt、Knowledge、Tools)
  4. Avatar 缩略图使用 Azure CDN 真人图片(已在 Phase 13 实现)

关键前提:VL Instance 后端基础设施已完全构建(Model, Schema, Service, API, Migration, Frontend hooks 全部就绪)。Phase 14 主要是前端重构

## Implementation Decisions

VL Management 页面重构

  • VL Management 页改为 VL Instance CRUD 管理页(不再是 HCP 卡片仪表盘)
  • 每个实例卡片显示: 名称, 模型, 语音, 数字人角色缩略图, 引用 HCP 数
  • 创建/编辑 Dialog 包含完整配置表单:模型选择、语音设置、数字人选择、对话参数、Agent 指令覆盖
  • Avatar 选择器复用 voice-avatar-tab.tsx 的 Standard/Custom tabs + Photo/Video filter
  • 实例可以分配给多个 HCP(一对多关系)
  • 删除有 HCP 引用的实例 → 409 Conflict

HCP 编辑器 Voice Tab 简化

  • 从 950 行完整配置编辑器 → 简化为只读预览 + VL Instance 下拉选择器
  • 下拉选择器显示实例名称 + 模型 + 数字人角色缩略图
  • 只读展示选中实例的关键配置(不可在 HCP 中编辑 VL 配置)
  • "新建配置" 按钮跳转到 VL Management 页
  • 保留实时测试面板(使用选中实例的配置)

Backend: unassign endpoint

  • 需要新增 POST /voice-live/instances/unassign 端点(从 HCP 取消 VL 关联)
  • 现有 assign 端点: POST /voice-live/instances/{id}/assign

Avatar 缩略图

  • HCP-14-04 已在 Phase 13 的 voice-avatar-tab 改进中基本完成(使用 CDN 真人图片替代字母圆圈)
  • VL Management 实例卡片也需要显示数字人缩略图

Claude's Discretion

  • VL Instance 创建/编辑 Dialog 的具体布局和分区
  • Knowledge/Tools 区域的具体 UI 组件(Phase 14 scope 可能推迟到后续)
  • 实时测试面板的复用策略

<canonical_refs>

Canonical References

Downstream agents MUST read these before planning or implementing.

Backend — VL Instance 基础设施(已构建)

  • backend/app/models/voice_live_instance.py — ORM model with all 15 voice config fields
  • backend/app/schemas/voice_live_instance.py — 5 Pydantic schemas (Create, Update, Response, Summary, List, Assign)
  • backend/app/services/voice_live_instance_service.py — Full CRUD + assign + resolve_voice_config
  • backend/app/api/voice_live.py — 6 instance endpoints (POST/GET/PUT/DELETE + list + assign)
  • backend/alembic/versions/m16a_create_voice_live_instances.py — Migration creating table + FK + data migration

Backend — 现有配置解析

  • backend/app/services/voice_live_service.py — Token broker with resolve_voice_config
  • backend/app/services/voice_live_websocket.py — WebSocket config loading
  • backend/app/models/hcp_profile.py — HcpProfile with voice_live_instance_id FK

Frontend — VL Management 基础设施(已部分构建)

  • frontend/src/hooks/use-voice-live-instances.ts — TanStack Query hooks for all CRUD
  • frontend/src/pages/admin/voice-live-management.tsx — Basic management page (needs major rework)
  • frontend/src/components/admin/voice-live-chain-card.tsx — Instance display card (needs rework)
  • frontend/src/types/voice-live.ts — TypeScript types for VL Instance

Frontend — Avatar 选择器(复用源)

  • frontend/src/components/admin/voice-avatar-tab.tsx — 完整 avatar 选择器(Standard/Custom tabs, Photo/Video filter, CDN 缩略图)

i18n

  • frontend/public/locales/en-US/admin.json
  • frontend/public/locales/zh-CN/admin.json

</canonical_refs>

## Specific Ideas
  1. VL Management 页面参考 AI Foundry Voice Live Playground — admin 定义 voice live 实例,配置模型、avatar/voice、对话参数,然后 assign 给 HCP
  2. Avatar 选择器从 voice-avatar-tab.tsx 提取 — 当前在 HCP 编辑器中的 avatar 选择器需要提取为独立组件,在 VL Management 和 HCP Voice Tab 中复用
  3. 实例卡片显示数字人缩略图 — 使用 CDN URL,不是字母圆圈
  4. 配置解析优先级: VoiceLiveInstance → HcpProfile 旧字段(回退兼容)
## Deferred Ideas
  • Knowledge 区域(HCP-14-02)— 添加/移除知识库功能可能推迟到后续 phase
  • Tools 区域(HCP-14-03)— Function Call 配置可能推迟到后续 phase
  • 上述两项的后端 API 和模型尚未设计

Phase: 14-hcp-agent-refactor-vl-instance-read-only-reference-knowledge-tools-config Context gathered: 2026-04-06 via conversation context + plan mode

Plans (4)

# Plan File Status
14-01 14-01-PLAN.md Complete
14-02 14-02-PLAN.md Complete
14-03 14-03-PLAN.md Complete
14-04 14-04-PLAN.md Pending

UI Specification

Click to expand UI spec

Phase 14 — UI Design Contract

Visual and interaction contract for the HCP Agent Refactor phase. Generated by gsd-ui-researcher, verified by gsd-ui-checker.


Design System

Property Value
Tool Manual Radix UI wrappers (shadcn-style, initialized Phase 01)
Preset Custom Figma Make SaaS theme (Phase 01-02)
Component library Radix UI (Dialog, Select, Tabs, Switch, Slider, etc.)
Icon library lucide-react ^0.460.0
Font Inter + Noto Sans SC (sans-serif), JetBrains Mono (monospace)

Reused from existing library (no new UI primitives needed):

  • Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter
  • Select, SelectContent, SelectItem, SelectTrigger, SelectValue, SelectGroup, SelectLabel
  • Card, CardHeader, CardContent, CardFooter, CardTitle
  • Button, Badge, Input, Label, Textarea, Switch, Slider
  • Tabs, TabsList, TabsTrigger, TabsContent
  • Skeleton, ScrollArea
  • Shared: EmptyState

Spacing Scale

Declared values (must be multiples of 4):

Token Value Usage
xs 4px Icon gaps (size-1), inline padding (p-1)
sm 8px Compact element spacing (gap-2, p-2), avatar grid gaps
md 16px Default element spacing (gap-4, p-4, space-y-4)
lg 24px Section padding (space-y-6, gap-6), card grid gaps
xl 32px Layout gaps (space-y-8), page header to content
2xl 48px Page-level vertical rhythm (py-12 in empty states)
3xl 64px Not used in this phase

Exceptions: Avatar grid items use gap-2 (8px) for tight thumbnail layout. Dialog max-height uses max-h-[90vh] viewport-relative.


Typography

Role Size Weight Line Height Usage in Phase 14
Body 14px (text-sm) 400 (normal) 1.5 Card content rows, config preview values, dialog descriptions
Label 14px (text-sm) 600 (semibold) 1.5 Section headings (h4), form labels, card titles
Heading 24px (text-2xl) 600 (semibold) 1.5 Page title ("Voice Live Management")
Micro 10px (text-[10px]) 400 (normal) 1.3 Avatar name labels in grid, hint text below selectors

Note: Phase 14 uses only 2 weights (400 + 600) consistent with project convention (--font-weight-normal: 400, --font-weight-medium: 500 used as 600 semibold in headings).


Color

Role Value Usage
Dominant (60%) var(--background) / #FFFFFF Page background, dialog background
Secondary (30%) var(--card) / #FFFFFF with border Instance cards, config preview cards, form sections
Accent (10%) var(--primary) / #1E40AF Selected avatar ring, primary CTA buttons, link text
Destructive var(--destructive) / #EF4444 Delete buttons, unassign confirmation, remove icon hover
Muted surface var(--muted) / #F9FAFB Empty state background, avatar placeholder bg, skeleton loading
Muted text var(--muted-foreground) / #6B7280 Secondary labels, descriptions, icon tints, disabled text

Accent reserved for:

  • "Save" / "New Instance" primary CTA buttons
  • Avatar selection ring (ring-2 ring-primary border-primary)
  • Enabled badge (variant="default")
  • "Manage in Voice Live" link text
  • Instance selector dropdown active state

Component Inventory — Phase 14 Specific

1. VoiceLiveManagementPage (page)

File: frontend/src/pages/admin/voice-live-management.tsx Layout: space-y-8 vertical stack

  • Page header: title (text-2xl) + description (text-sm muted) + "New Instance" button
  • Summary stat cards: 3-column grid (grid-cols-2 md:grid-cols-3 gap-4)
  • Instance cards grid: grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6
  • Delete confirmation Dialog
  • Assign-to-HCP Dialog

States:

  • Loading: 6x Skeleton cards (h-56 rounded-lg)
  • Error: muted bg + error text + Retry button
  • Empty: EmptyState component with i18n copy
  • Populated: Instance card grid

2. VoiceLiveInstanceCard (component)

File: frontend/src/components/admin/voice-live-chain-card.tsx Layout: Card with CardHeader + CardContent + CardFooter

  • Header: Avatar thumbnail (w-12, aspect-[3/4]) + name + enabled/disabled Badge
  • Content: Model row, voice row (Mic icon), avatar row, HCP count (expandable)
  • Footer: Edit (ghost), Assign (ghost), Delete (ghost destructive)
  • Expanded: assigned HCP list with unassign X buttons, border-l-2 indent

Avatar thumbnail contract:

  • Container: w-12 aspect-[3/4] overflow-hidden rounded-lg bg-muted/30
  • CDN source: https://learn.microsoft.com/en-us/azure/ai-services/speech-service/text-to-speech-avatar/media/{character}-{style}.png
  • Fallback: gradient circle with initials (2-char) from getAvatarInitials()
  • Error handling: onError sets ref flag, re-renders to show fallback

3. VlInstanceDialog (component)

File: frontend/src/components/admin/vl-instance-dialog.tsx Layout: Dialog (sm:max-w-2xl max-h-[90vh] overflow-y-auto)

  • 6 sections separated by space-y-6:
    1. Identity: Name input + Description textarea + Enabled switch
    2. Model: VoiceLiveModelSelect (tiered: Pro/Standard/Lite)
    3. Voice: Voice name select + Temperature slider (0-2, step 0.1)
    4. Avatar: Filter tabs (All/Photo/Video) + scrollable grid (grid-cols-4 gap-2 max-h-60)
    5. Conversation: Turn detection + language (2-col grid) + 3 switches (noise/echo/EOU)
    6. Agent Instructions: Override textarea (3 rows)
  • Footer: Cancel (outline) + Save (primary, disabled when saving or name empty)

Avatar grid item contract:

  • Container: flex-col items-center gap-1 rounded-lg border p-2
  • Selected state: ring-2 ring-primary border-primary
  • Thumbnail: h-14 w-14 rounded-full object-cover
  • Label: text-[10px] leading-tight text-center truncate w-full

4. VoiceAvatarTab (component — read-only mode)

File: frontend/src/components/admin/voice-avatar-tab.tsx Layout: space-y-4 max-w-2xl

  • Section 1 — Instance Selector Card:
    • Select dropdown with instances (name + model badge)
    • X button to remove assignment
    • "Manage in Voice Live" link (ExternalLink icon)
    • New profile hint text (text-[10px])
  • Section 2 — Config Preview Card (when instance assigned):
    • CardTitle: "Configuration Preview" (text-sm semibold)
    • 2-column grid (grid-cols-2 gap-x-6 gap-y-3) with ConfigRow components
    • Rows: Model (Badge), Voice (Volume2 icon), Avatar (thumbnail + name), Temperature, Turn Detection, Language
    • Footer: Enabled/Disabled badge + HCP count
  • Section 3 — No Instance Empty State (when no instance):
    • bg-muted/50 rounded-lg p-6 centered layout
    • Monitor icon (size-10 muted)
    • Title + description + "Manage in Voice Live" outline button

ConfigRow contract:

  • Label: text-xs text-muted-foreground
  • Value: child content in div

AvatarThumbnail contract (inline):

  • Container: w-8 aspect-[3/4] overflow-hidden rounded-md bg-muted/30
  • Fallback: gradient initials circle

5. Knowledge Tab Placeholder

Location: Inside HCP editor Tabs Layout: EmptyState-like centered layout

  • BookOpen icon (lucide-react)
  • Title: i18n voiceLive.knowledgePlaceholderTitle ("Knowledge Base")
  • Body: i18n voiceLive.knowledgePlaceholderBody (future update notice)

6. Tools Tab Placeholder

Location: Inside HCP editor Tabs Layout: EmptyState-like centered layout

  • Wrench icon (lucide-react)
  • Title: i18n voiceLive.toolsPlaceholderTitle ("Function Call Tools")
  • Body: i18n voiceLive.toolsPlaceholderBody (future update notice)

7. HCP Profile Editor Tabs

File: frontend/src/pages/admin/hcp-profile-editor.tsx Tabs: 4 tabs (expanded from 2 in Phase 12):

  1. Profile (existing)
  2. Voice & Avatar (simplified to read-only)
  3. Knowledge (new placeholder)
  4. Tools (new placeholder)

Tab icons: Save, Volume2/Monitor, BookOpen, Wrench (from lucide-react)


Copywriting Contract

Element en-US Copy zh-CN Copy
VL Management page title "Voice Live Management" "Voice Live 管理"
VL Management description "Manage reusable Voice Live configuration instances. Create instances and assign them to HCP profiles." "管理可复用的 Voice Live 配置实例。创建实例并分配给 HCP 档案。"
Primary CTA (VL page) "New Instance" "新建实例"
Primary CTA (dialog) "Save" "保存"
Empty state heading (VL) "No Voice Live Instances" "暂无 Voice Live 实例"
Empty state body (VL) "Create your first Voice Live configuration instance to get started." "创建您的第一个 Voice Live 配置实例以开始使用。"
Error state (VL load) "Failed to load Voice Live instances. Click retry to try again." "加载 Voice Live 实例失败。点击重试再试一次。"
Delete confirmation "Are you sure you want to delete "{{name}}"?" "确定要删除 "{{name}}" 吗?"
Delete conflict "Cannot delete: {{count}} HCP profile(s) still reference this instance." "无法删除:仍有 {{count}} 个 HCP 档案引用此实例。"
Assign dialog title "Assign Instance to HCP" "将实例分配给 HCP"
Remove confirm (HCP tab) "Remove Voice Live Instance "{{name}}" from this HCP? The HCP will fall back to inline settings." "从此 HCP 移除 Voice Live 实例 "{{name}}"?HCP 将回退到内联设置。"
No instance (HCP tab) "No Voice Live Instance assigned" "未分配 Voice Live 实例"
Read-only hint "Voice/avatar settings come from the assigned Voice Live Instance. Edit in Voice Live Management." "语音/数字人设置来自分配的 Voice Live 实例。在 Voice Live 管理页面编辑。"
Knowledge placeholder "Knowledge base configuration (product materials, clinical references) will be available in a future update." "知识库配置(产品资料、临床参考)将在未来版本中提供。"
Tools placeholder "Function Call tool configuration will be available in a future update." "Function Call 工具配置将在未来版本中提供。"
VL dialog section: Model "Model" "模型"
VL dialog section: Voice "Voice" "语音"
VL dialog section: Avatar "Avatar" "数字人"
VL dialog section: Conversation "Conversation" "对话"
VL dialog section: Agent "Agent Instructions" "Agent 指令"

All copy is already externalized in i18n files (admin.json namespace, voiceLive.* and hcp.* keys).


Interaction Contracts

VL Instance CRUD Flow

  1. Create: Click "New Instance" -> VlInstanceDialog opens in create mode -> Fill 6 sections -> "Save" -> toast success -> dialog closes -> grid refreshes
  2. Edit: Click "Edit Instance" on card -> VlInstanceDialog opens with pre-filled values -> Modify -> "Save" -> toast success -> grid refreshes
  3. Delete: Click "Delete Instance" on card -> confirmation Dialog -> "Delete Instance" (destructive) -> toast success OR 409 conflict toast error
  4. Assign: Click "Assign to HCP" on card -> Select dialog with available HCPs -> "Assign to HCP" -> toast success
  5. Unassign: Expand HCP list on card -> click X next to HCP name -> instant unassign -> toast success

HCP Voice Tab Flow

  1. View: Open HCP editor -> "Voice & Avatar" tab -> shows instance selector + read-only preview (or empty state)
  2. Assign instance: Select from dropdown -> immediate API call (for existing profiles) or form state update (for new profiles)
  3. Remove instance: Click X button -> confirmation Dialog -> "Remove Assignment" (destructive) -> form value cleared
  4. Navigate: Click "Manage in Voice Live" link -> navigates to /admin/voice-live

HCP Editor Tab Navigation

  • Tab 1 "Profile": Existing identity/personality/knowledge/interaction fields
  • Tab 2 "Voice & Avatar": Read-only VL instance reference (simplified from Phase 12)
  • Tab 3 "Knowledge": Placeholder with BookOpen icon + future update notice
  • Tab 4 "Tools": Placeholder with Wrench icon + future update notice

Dialog Behavior

  • All dialogs use Radix Dialog primitive with onOpenChange for close behavior
  • Dialogs close on: overlay click, ESC key, Cancel button, successful save
  • Delete dialogs disable confirm button during isPending mutation
  • VlInstanceDialog disables Save when name is empty or during isPending

Responsive Behavior

Breakpoint VL Management Grid Stat Cards Dialog Width
Mobile (<640px) 1 column 2 columns Full width with padding
Tablet (640-1024px) 2 columns 3 columns sm:max-w-2xl (672px)
Desktop (>1024px) 3 columns 3 columns sm:max-w-2xl (672px)

HCP editor Voice tab: max-w-2xl (672px) constrains content width within the tab panel.


Accessibility

  • All form controls have associated Label elements via htmlFor/id pairs
  • Dialog titles use DialogTitle (maps to aria-labelledby)
  • Dialog descriptions use DialogDescription (maps to aria-describedby)
  • StatCards use aria-label with value + label text
  • Avatar grid items are <button> elements (keyboard navigable)
  • Selected avatar state communicated via visual ring (no aria-pressed — defer to visual cue per existing pattern)
  • Delete/Remove buttons show tooltip via title attribute
  • Switch components use id + Label htmlFor pattern

Registry Safety

Registry Blocks Used Safety Gate
Project UI library (Radix wrappers) Dialog, Select, Card, Button, Badge, Input, Label, Textarea, Switch, Slider, Tabs, Skeleton, ScrollArea, Form, Avatar not required (in-project)
lucide-react Plus, RefreshCw, Settings2, CheckCircle, Users, Pencil, Trash2, Mic, UserPlus, ChevronDown, ChevronUp, X, ExternalLink, Volume2, Monitor, ArrowLeft, Save, MessageSquare, BookOpen, Wrench not required (npm package)

No third-party registries used. No shadcn registry blocks. All components are project-internal.


Checker Sign-Off

  • Dimension 1 Copywriting: PASS
  • Dimension 2 Visuals: PASS
  • Dimension 3 Color: PASS
  • Dimension 4 Typography: PASS
  • Dimension 5 Spacing: PASS
  • Dimension 6 Registry Safety: PASS

Approval: pending

⚠️ **GitHub.com Fallback** ⚠️