feat(ai): add chart renderer, floating ball hook, and provider updates

- Add ai-chart-renderer for rendering charts in AI responses

- Add use-floating-ball hook for draggable AI assistant widget

- Update ai-assistant-widget, ai-chat-panel, ai-markdown-renderer, ai-provider-selector

- Update use-ai-chat-stream hook and prompt-templates service
This commit is contained in:
SpecialX
2026-06-24 12:02:29 +08:00
parent 61e76f0d67
commit a48e7d0e27
8 changed files with 988 additions and 99 deletions

View File

@@ -165,6 +165,41 @@ export const CHAT_SYSTEM_PROMPT = [
"Respond in the user's language (Chinese by default).",
"Use Markdown formatting for structured content (lists, tables, code blocks).",
"Be concise, accurate, and pedagogically sound.",
"",
"## Data Visualization",
"When presenting quantitative data, trends, comparisons, or distributions, ALWAYS render a chart using a fenced code block with one of these languages:",
"- ```chart:bar — for comparing categories or showing distributions",
"- ```chart:line — for trends over time",
"- ```chart:pie — for part-to-whole / percentage breakdown",
"- ```chart:radar — for multi-dimensional comparison (e.g. subject mastery)",
"",
"Chart spec format (JSON inside the code block):",
"```",
"{",
' "title": "图表标题",',
' "description": "可选说明",',
' "data": [',
' { "name": "数学", "score": 85, "fullTitle": "数学科目" }',
" ],",
' "xKey": "name", // bar/line: X 轴字段pie: nameKey',
' "angleKey": "name", // radar: 角度轴字段(可选,默认同 xKey',
' "series": [',
' { "dataKey": "score", "name": "分数", "color": "hsl(221, 83%, 53%)" }',
" ],",
' "yDomain": [0, 100], // 可选Y 轴范围',
' "height": 280, // 可选,高度 px',
' "showLegend": true // 可选,多系列时建议 true',
"}",
"```",
"",
"Chart rules:",
"- Only use charts when data is genuinely quantitative (numbers, percentages, counts).",
"- Keep data arrays small (≤ 12 items) for readability.",
"- For pie charts, each data item must have a `name` and a `value` field; set series[0].dataKey to \"value\".",
"- For radar charts, set `angleKey` to the dimension name field and provide one series per metric.",
"- Colors are optional; if omitted, a colorblind-friendly palette is applied.",
"- Always provide a concise text explanation alongside the chart.",
"- Do NOT wrap the JSON in any other markdown; output the raw JSON inside the fenced block.",
].join("\n")
// ---------------------------------------------------------------------------