From 97a1c0b1d7551d0bb7a47e0cd5f73fd4ace049dc Mon Sep 17 00:00:00 2001 From: "dayuan.jiang" Date: Sat, 10 Oct 2026 07:46:56 +0900 Subject: [PATCH] feat(ui): tidy the start screen and the chat panel details Start screen - The five examples are one row of picture tiles (title under the picture); the old cards cut their descriptions off with an ellipsis - "Open .drawio file" leaves the example grid and sits with "Start with a blank canvas" below it, both as outlined buttons - The "Paper to diagram" example gets a thumbnail of its result (public/paper_demo.svg) like the other four - The caption says what happens: examples use saved answers, so they appear at once and do not call the AI - Shorter lede Chat panel - The version card's "" icon button becomes a "Show XML" text link in the summary line; the summary runs under the title row, so Undo is the card's only button - Settings uses the gear icon; new diagram uses a file-plus icon instead of the pen that reads as "edit" - The message box has the same side padding as the message column Copy - The model picker says "Server model" instead of "Default" when the server's model is in use - The theme description no longer claims the diagram always stays on a white sheet (the canvas follows the theme) - en, zh, ja and zh-Hant dictionaries updated together --- components/chat/chat-panel.tsx | 10 ++-- components/chat/lobby-hero.tsx | 74 +++++++++++++----------------- components/chat/tool-activity.tsx | 52 ++++++++++----------- components/model-selector.tsx | 4 +- components/workspace/workspace.tsx | 4 +- lib/i18n/dictionaries/en.json | 8 ++-- lib/i18n/dictionaries/ja.json | 8 ++-- lib/i18n/dictionaries/zh-Hant.json | 8 ++-- lib/i18n/dictionaries/zh.json | 8 ++-- public/paper_demo.svg | 1 + 10 files changed, 84 insertions(+), 93 deletions(-) create mode 100644 public/paper_demo.svg diff --git a/components/chat/chat-panel.tsx b/components/chat/chat-panel.tsx index 4ad8b395..e37c8cad 100644 --- a/components/chat/chat-panel.tsx +++ b/components/chat/chat-panel.tsx @@ -1,10 +1,10 @@ import { ChevronDown, Download, + FilePlus, MessageSquareDashed, PanelRightClose, - Settings2, - SquarePen, + Settings, } from "lucide-react" import { useRef } from "react" import { DevXmlSimulator } from "@/components/dev-xml-simulator" @@ -139,14 +139,14 @@ export function ChatPanel({ disabled={engine.isBusy} data-testid="new-chat-button" > - + openSettings()} data-testid="settings-button" > - + {!mobile && ( )} -
+
0 && diff --git a/components/chat/lobby-hero.tsx b/components/chat/lobby-hero.tsx index ec168246..542612fd 100644 --- a/components/chat/lobby-hero.tsx +++ b/components/chat/lobby-hero.tsx @@ -18,14 +18,18 @@ interface Example { file?: { path: string; name: string; type: string } } +/** Secondary start buttons: outlined, so they read as clickable */ +const startButtonClass = + "inline-flex h-8 items-center gap-1.5 rounded-lg border border-border bg-card px-3 text-[13px] text-foreground transition-colors hover:bg-accent [&_svg]:text-muted-foreground" + async function loadExampleFile(file: NonNullable) { const response = await fetch(getAssetUrl(file.path)) const blob = await response.blob() return new File([blob], file.name, { type: file.type }) } -/** One start-screen choice: a small picture, a title and one line */ -function ExampleCard({ +/** One start-screen example: a small picture over its title */ +function ExampleTile({ onClick, title, description, @@ -35,6 +39,7 @@ function ExampleCard({ }: { onClick: () => void title: string + /** Shown as the tooltip: the title alone names the example */ description: string picture: React.ReactNode /** An icon on a tinted tile instead of a diagram on paper */ @@ -45,24 +50,20 @@ function ExampleCard({ ) @@ -92,6 +93,7 @@ export function LobbyHero({ key: "paper", title: dict.examples.paperToDiagram, description: dict.examples.paperDescription, + image: "/paper_demo.svg", prompt: "Summarize this paper as a diagram", file: { path: "/chain-of-thought.txt", @@ -185,10 +187,12 @@ export function LobbyHero({ placeholder={t.placeholder} /> + {/* Examples: one row of tiles; the ways to bring your own + diagram follow as a separate group */}
{examples.map((example) => @@ -209,7 +213,7 @@ export function LobbyHero({ ) : ( - pickExample(example)} title={example.title} @@ -221,7 +225,7 @@ export function LobbyHero({ ) : ( @@ -231,48 +235,34 @@ export function LobbyHero({ /> ), )} - {!compact && ( - - } - plain - /> - )}
-

+

{dict.examples.cachedNote}

-
+ {/* Ways to start without an example, as plain buttons */} +
{engine.sessions.length > 0 && ( - )} - {compact && ( - - )} + ) - // What the AI wrote, on every card (main showed it on every tool call) - const codeButton = ( - + // What the AI wrote: a text link in the summary line, so the card's + // only button is the action (undo or restore) + const summaryLine = ( +
+ {summary} + {/* The link wraps as one unit with its separator */} + + · + + +
) const codePanel = showCode && (
@@ -231,15 +236,12 @@ function VersionCard({ /> {badge} -
+
{title}
-
- {summary} -
+ {summaryLine}
- {codeButton} {restoreButton}
{codePanel} @@ -271,17 +273,12 @@ function VersionCard({ {t.compare} -
+ {/* Title row with the action; the summary runs under both */} +
{badge} -
-
- {title} -
-
- {summary} -
+
+ {title}
- {codeButton} {canUndo ? (
{codePanel}
diff --git a/components/model-selector.tsx b/components/model-selector.tsx index 1b146d66..532a4bc1 100644 --- a/components/model-selector.tsx +++ b/components/model-selector.tsx @@ -220,14 +220,14 @@ export function ModelSelector({ {selectedModel ? shortModelName(selectedModel.modelId) - : dict.modelConfig.default} + : dict.modelConfig.serverDefault} ) : ( // Keep an sr-only label for screen readers when hidden {selectedModel ? selectedModel.modelId - : dict.modelConfig.default} + : dict.modelConfig.serverDefault} )} diff --git a/components/workspace/workspace.tsx b/components/workspace/workspace.tsx index 584ba636..f8d992fa 100644 --- a/components/workspace/workspace.tsx +++ b/components/workspace/workspace.tsx @@ -1,6 +1,6 @@ "use client" -import { MessageSquare, PanelRightOpen, Settings2, Shapes } from "lucide-react" +import { MessageSquare, PanelRightOpen, Settings, Shapes } from "lucide-react" import { usePathname, useRouter } from "next/navigation" import { useEffect, useRef, useState } from "react" import { CanvasStage } from "@/components/canvas/canvas-stage" @@ -100,7 +100,7 @@ function StartBar({ onClick={() => openSettings()} data-testid="settings-button" > - +
) diff --git a/lib/i18n/dictionaries/en.json b/lib/i18n/dictionaries/en.json index 4150ab4e..5dbe820a 100644 --- a/lib/i18n/dictionaries/en.json +++ b/lib/i18n/dictionaries/en.json @@ -72,7 +72,7 @@ "replicateDescription": "Upload and replicate an existing flowchart", "creativeDrawing": "Creative drawing", "creativeDescription": "Draw something fun and creative", - "cachedNote": "Examples open instantly and don't use your model.", + "cachedNote": "Examples use saved answers: they appear instantly and don't call the AI.", "mcpServer": "MCP Server", "mcpDescription": "Use in Claude Desktop, VS Code & Cursor" }, @@ -96,7 +96,7 @@ "language": "Language", "languageDescription": "Choose your interface language.", "theme": "Theme", - "themeDescription": "Light or dark interface. The diagram always stays on a white sheet, the way it exports.", + "themeDescription": "Light or dark interface. The canvas follows the same theme.", "diagramStyle": "Diagram style", "diagramStyleDescription": "How the AI draws new diagrams: Styled uses colors and icons, Minimal keeps shapes plain.", "sendShortcut": "Send shortcut", @@ -400,7 +400,7 @@ "searchModels": "Search models...", "noModelsFound": "No models found.", "default": "Default", - "serverDefault": "Server Default", + "serverDefault": "Server model", "serverModels": "Server Models", "userModels": "User Models", "configureModels": "Configure Models...", @@ -695,7 +695,7 @@ }, "lobby": { "title": "What would you like to draw?", - "lede": "Describe a diagram, or upload a screenshot or PDF. You get a regular draw.io diagram that you can keep editing and export.", + "lede": "Describe a diagram or upload a screenshot or PDF. You get a draw.io diagram you can keep editing and export.", "placeholder": "For example: a login sequence diagram with SMS codes and retries", "recent": "Recent diagrams", "drawYourself": "Start with a blank canvas", diff --git a/lib/i18n/dictionaries/ja.json b/lib/i18n/dictionaries/ja.json index dc5abd09..6622c945 100644 --- a/lib/i18n/dictionaries/ja.json +++ b/lib/i18n/dictionaries/ja.json @@ -72,7 +72,7 @@ "replicateDescription": "既存のフローチャートをアップロードして複製", "creativeDrawing": "自由なイラスト", "creativeDescription": "楽しくてクリエイティブなものを描く", - "cachedNote": "例はすぐに開き、モデルは使いません。", + "cachedNote": "例は保存済みの回答を使うので、すぐに表示され、AI を呼び出しません。", "mcpServer": "MCP サーバー", "mcpDescription": "Claude Desktop、VS Code、Cursor で使用" }, @@ -96,7 +96,7 @@ "language": "言語", "languageDescription": "インターフェース言語を選択します。", "theme": "テーマ", - "themeDescription": "画面をライトにするかダークにするか。図はエクスポートしたときと同じく、常に白い用紙の上に表示されます。", + "themeDescription": "画面をライトにするかダークにするか。キャンバスも同じテーマになります。", "diagramStyle": "図のスタイル", "diagramStyleDescription": "AI が新しい図を描くときのスタイル。スタイル付きは色やアイコンを使い、ミニマルは素朴な図形だけにします。", "sendShortcut": "送信のショートカット", @@ -355,7 +355,7 @@ "searchModels": "モデルを検索...", "noModelsFound": "モデルが見つかりません。", "default": "デフォルト", - "serverDefault": "サーバーデフォルト", + "serverDefault": "サーバーのモデル", "serverModels": "サーバーモデル", "userModels": "ユーザーモデル", "configureModels": "モデルを設定...", @@ -695,7 +695,7 @@ }, "lobby": { "title": "どんな図を描きますか?", - "lede": "図の内容を説明するか、スクリーンショットや PDF をアップロードしてください。できあがるのは通常の draw.io の図なので、続けて編集もエクスポートもできます。", + "lede": "図を説明するか、スクリーンショットや PDF をアップロードしてください。できあがるのは編集もエクスポートもできる draw.io の図です。", "placeholder": "例:SMS 認証とリトライを含むログインのシーケンス図", "recent": "最近の図", "drawYourself": "白紙のキャンバスから始める", diff --git a/lib/i18n/dictionaries/zh-Hant.json b/lib/i18n/dictionaries/zh-Hant.json index 375c2246..0945d9d7 100644 --- a/lib/i18n/dictionaries/zh-Hant.json +++ b/lib/i18n/dictionaries/zh-Hant.json @@ -72,7 +72,7 @@ "replicateDescription": "上傳並複製現有流程圖", "creativeDrawing": "創意繪畫", "creativeDescription": "繪製有趣且富有創意的內容", - "cachedNote": "範例會立即開啟,不呼叫模型。", + "cachedNote": "範例使用保存好的答案,立即顯示,不呼叫 AI。", "mcpServer": "MCP 伺服器", "mcpDescription": "在 Claude Desktop、VS Code 和 Cursor 中使用" }, @@ -96,7 +96,7 @@ "language": "語言", "languageDescription": "選擇介面語言。", "theme": "主題", - "themeDescription": "介面用淺色還是深色。圖紙始終是白底,和匯出後的樣子一致。", + "themeDescription": "介面用淺色還是深色,畫布跟隨同一主題。", "diagramStyle": "圖形風格", "diagramStyleDescription": "AI 畫新圖時的風格:精緻會用顏色和圖示,簡約只用樸素的圖形。", "sendShortcut": "傳送快速鍵", @@ -400,7 +400,7 @@ "searchModels": "搜尋模型...", "noModelsFound": "未找到模型。", "default": "預設", - "serverDefault": "伺服器預設", + "serverDefault": "伺服器模型", "serverModels": "伺服器模型", "userModels": "使用者模型", "configureModels": "配置模型...", @@ -695,7 +695,7 @@ }, "lobby": { "title": "說說你要畫什麼", - "lede": "描述一張圖,或上傳截圖、PDF。畫出來的是標準的 draw.io 圖表,可以接著改,也可以匯出。", + "lede": "描述一張圖,或上傳截圖、PDF。得到的是可以繼續編輯和匯出的 draw.io 圖。", "placeholder": "例如:使用者登入的時序圖,包含簡訊驗證碼和失敗重試", "recent": "最近的圖紙", "drawYourself": "從空白畫布開始", diff --git a/lib/i18n/dictionaries/zh.json b/lib/i18n/dictionaries/zh.json index e0908271..fdba8076 100644 --- a/lib/i18n/dictionaries/zh.json +++ b/lib/i18n/dictionaries/zh.json @@ -72,7 +72,7 @@ "replicateDescription": "上传并复制现有流程图", "creativeDrawing": "创意绘画", "creativeDescription": "绘制有趣且富有创意的内容", - "cachedNote": "示例会立即打开,不调用模型。", + "cachedNote": "示例使用保存好的答案,立即显示,不调用 AI。", "mcpServer": "MCP 服务器", "mcpDescription": "在 Claude Desktop、VS Code 和 Cursor 中使用" }, @@ -96,7 +96,7 @@ "language": "语言", "languageDescription": "选择界面语言。", "theme": "主题", - "themeDescription": "界面用浅色还是深色。图纸始终是白底,和导出后的样子一致。", + "themeDescription": "界面用浅色还是深色,画布跟随同一主题。", "diagramStyle": "图形风格", "diagramStyleDescription": "AI 画新图时的风格:精致会用颜色和图标,简约只用朴素的图形。", "sendShortcut": "发送快捷键", @@ -400,7 +400,7 @@ "searchModels": "搜索模型...", "noModelsFound": "未找到模型。", "default": "默认", - "serverDefault": "服务器默认", + "serverDefault": "服务器模型", "serverModels": "服务器模型", "userModels": "用户模型", "configureModels": "配置模型...", @@ -695,7 +695,7 @@ }, "lobby": { "title": "说说你要画什么", - "lede": "描述一张图,或者上传截图、PDF。画出来的是标准的 draw.io 图表,可以接着改,也可以导出。", + "lede": "描述一张图,或上传截图、PDF。得到的是可以继续编辑和导出的 draw.io 图。", "placeholder": "比如:用户登录的时序图,包含短信验证码和失败重试", "recent": "最近的图纸", "drawYourself": "从空白画布开始", diff --git a/public/paper_demo.svg b/public/paper_demo.svg new file mode 100644 index 00000000..d32f8465 --- /dev/null +++ b/public/paper_demo.svg @@ -0,0 +1 @@ +
Chain-of-Thought Prompting
Elicits Reasoning in Large Language Models
Chain-of-Thought PromptingElicits Reasoning in Large Language Models
Wei et al. (Google Research, Brain Team) | NeurIPS 2022
Wei et al. (Google Research, Brain Team) | NeurIPS 2022
💡 Core Idea
💡 Core Idea
Chain of Thought = A series of intermediate reasoning steps that lead to the final answer

Simply provide a few CoT demonstrations as exemplars in few-shot prompting
Chain of Thought = A series of intermediate reasoning steps thatlead to the final answerSimply provide a few CoT demonstrations as exemplars infew-shot prompting
⚖️ Standard vs Chain-of-Thought Prompting
⚖️ Standard vs Chain-of-Thought Prompting
Standard Prompting
Standard Prompting
Q: Roger has 5 tennis balls. He buys 2 more cans. Each can has 3 balls. How many now?
Q: Roger has 5 tennis balls. He buys2 more cans. Each can has 3 balls.How many now?
A: The answer is 11.
A: The answer is 11.
❌ Often Wrong
❌ Often Wrong
Chain-of-Thought
Chain-of-Thought
Q: Roger has 5 tennis balls. He buys 2 more cans. Each can has 3 balls. How many now?
Q: Roger has 5 tennis balls. He buys2 more cans. Each can has 3 balls.How many now?
A: 2 cans × 3 = 6 balls.
5 + 6 = 11. Answer: 11
A: 2 cans × 3 = 6 balls.5 + 6 = 11. Answer: 11
✓ Correct!
✓ Correct!
🔑 Key Properties
🔑 Key Properties
1️⃣ Decomposes multi-step problems
1️⃣ Decomposes multi-step problems
2️⃣ Interpretable reasoning window
2️⃣ Interpretable reasoning window
3️⃣ Applicable to any language task
3️⃣ Applicable to any language task
4️⃣ No finetuning required
4️⃣ No finetuning required
📈 Emergent Ability
📈 Emergent Ability
CoT only works with
~100B+ parameters

Small models produce
fluent but illogical chains
CoT only works with~100B+ parametersSmall models producefluent but illogical chains
📊 Key Results
📊 Key Results
GSM8K (Math)
GSM8K (Math)
18%
18%
57%
57%
Standard → CoT (PaLM 540B)
Standard → CoT (PaLM 540B)
🧪 Benchmarks Tested
🧪 Benchmarks Tested
🔢 Arithmetic
GSM8K, SVAMP, ASDiv, AQuA, MAWPS
🔢 ArithmeticGSM8K, SVAMP, ASDiv, AQuA,MAWPS
🧠 Commonsense
CSQA, StrategyQA, Date, Sports, SayCan
🧠 CommonsenseCSQA, StrategyQA, Date, Sports,SayCan
🔣 Symbolic
Last Letter Concat, Coin Flip
🔣 SymbolicLast Letter Concat, Coin Flip
🎯 Task Types & Results
🎯 Task Types & Results
Arithmetic
Reasoning
ArithmeticReasoning
SOTA on GSM8K
(57% vs 55% prior)
SOTA on GSM8K(57% vs 55% prior)
Commonsense
Reasoning
CommonsenseReasoning
SOTA StrategyQA
(75.6% vs 69.4%)
SOTA StrategyQA(75.6% vs 69.4%)
Symbolic
Reasoning
SymbolicReasoning
OOD Generalization
to longer sequences
OOD Generalizationto longer sequences
🤖 Models Tested
🤖 Models Tested
• GPT-3 (175B)
• GPT-3 (175B)
• LaMDA (137B)
• LaMDA(137B)
• PaLM (540B)
• PaLM (540B)
• Codex
• Codex
• UL2 (20B)
• UL2 (20B)
No finetuning - prompting only!
No finetuning - prompting only!
✨ Key Takeaways
✨ Key Takeaways
✓ Simple yet powerful
✓ Simple yet powerful
✓ Emergent at scale
✓ Emergent at scale
✓ Broadly applicable
✓ Broadly applicable
✓ No training needed
✓ No training needed
✓ State-of-the-art results
✓ State-of-the-art results
📝 Prompt Format
📝 Prompt Format
〈 Input, Chain of Thought, Output 〉
〈 Input, Chain of Thought, Output 〉
⚠️ Limitations
⚠️ Limitations
• Requires large models (~100B+)
• No guarantee of correct reasoning
• Costly to serve in production
• Requires large models (~100B+)• No guarantee of correct reasoning• Costly to serve in production
🚀 Impact
🚀 Impact
Foundational technique for modern LLM reasoning - inspired many follow-up works including Self-Consistency, Tree-of-Thought, etc.
Foundational technique for modern LLMreasoning - inspired many follow-up worksincluding Self-Consistency, Tree-of-Thought,etc.
Text is not SVG - cannot display
\ No newline at end of file