* feat: add all Draw.io themes to settings panel
Add all available Draw.io themes (kennedy, atlas, dark, min, sketch, simple)
to the settings panel dropdown. Previously only min and sketch were available
as a toggle button.
Changes:
- Replace the Draw.io style toggle button with a dropdown selector
- Expand theme type from "min" | "sketch" to include all 6 themes
- Update localStorage validation to accept all themes
- Update handler from toggle to direct theme selection
Closes#499
* fix: localize theme labels, tighten DrawioTheme typing, sync dark param
- Move DRAWIO_THEMES + DrawioTheme to lib/drawio-themes.ts; reuse in
page.tsx, chat-panel.tsx and settings-dialog.tsx instead of `string`
- Localize theme dropdown labels (Dark/Minimal/Sketch/Simple) in
en/zh/ja/zh-Hant; keep proper-noun themes (Kennedy/Atlas) as-is
- Drop trailing colon from drawioStyleDescription and remove dead
switchTo/minimal/sketch keys in all 4 dictionaries
- Auto-sync drawio dark URL param when ui="dark" is selected
- Add aria-label to drawio-style SelectTrigger
* fix: use kennedy as default theme and label it "Default"
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
When ACCESS_CODE_LIST is configured on the server, the settings dialog
was not showing the access code input field in two cases:
1. Stale localStorage cache: if a user had previously visited without
ACCESS_CODE_LIST enabled, the cached value of accessCodeRequired=false
would be used indefinitely, hiding the password input.
2. Race condition on first visit: the dialog could open triggered
by an auth error before the async fetch to /api/config completed,
showing a blank settings dialog with no access code field.
Fix by re-fetching /api/config whenever the dialog opens (on open
change) instead of only once on mount with a cache guard. The cached
value in localStorage is still updated on success, keeping the fast
initial render intact while ensuring the dialog always reflects the
server configuration.
Fixes#811
Co-authored-by: octo-patch <octo-patch@github.com>
* fix: reduce CPU usage during large XML streaming
Skip Prism syntax highlighting while tool call is streaming — use plain
<pre> during streaming and only run Prism once at completion. Also throttle
scrollIntoView to once per 150ms to avoid layout thrashing.
Profiled with Playwright + CDP: for 200-cell diagrams the longest
browser task dropped from 6.7s to ~450ms and total long-task time
fell from ~10.9s to ~1.1s.
* fix: add trailing edge to scroll throttle
Ensures the chat scrolls to the bottom after streaming ends, even if
the last messages update arrives during the 150ms throttle window.
* 增加了ralph自动化编程梳理
* feat: US-001 - 为模板库建立独立的 IndexedDB 存储层
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-002 - 在空聊天状态用我的模板库替换官方示例
- 将 ChatLobby 中的 Quick Examples 替换为 TemplatePanel
- 当没有历史会话时,展示完整的模板库面板
- 当有历史会话时,展示可折叠的 "My Templates" 区域
- 使用 TemplatePanel 组件展示用户的个人模板库
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-004 - Provide template creation flow
- Create TemplateCreateDialog component with form fields for prompt, title, description, tags, and pinned
- Add i18n translations for template creation UI in en, zh, zh-Hant, ja
- Update TemplatePanel to integrate the create dialog
- Support initialPrompt prop for pre-filling from current input
- Validate required prompt field (empty prompt not allowed)
- Auto-generate default title from first 20 chars of Pin templates appear at top of list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-005 - 为模板卡片提供编辑、删除和复制操作
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-006 - Send template directly on click and record usage statistics
- Implement click-to-send template functionality with confirmation dialog
- Add clickCount and runCount increment logic
- Display runCount and lastUsedAt on template card
- Add i18n translations for confirmation dialog (en, zh, zh-Hant, ja)
- Pass onSendTemplate and currentInput props through component hierarchy
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-007 - Support template search, pin and default sorting
- Add search bar to TemplatePanel with real-time filtering by title, description, and tags
- Add pin/unpin toggle button on template cards (uses Bookmark icon with fill indicator)
- Search uses existing searchTemplates function from template-storage
- Sort uses existing sortTemplates function (pinned desc, runCount desc, lastUsedAt desc, updatedAt desc)
- Show empty state with Search icon when search returns no results
- List re-sorts immediately after pin/unpin toggle
- Add i18n keys: searchPlaceholder, searchNoResults, pin, unpin for all 4 languages
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-008 - Support saving current input as template
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-009 - Support saving historical user message as template
- Add "Save as Template" button to user messages
- Pre-fill prompt with original user message text
- Only show on user messages,- Dialog opens TemplateCreateDialog on click
- Template appears in list immediately after saving
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: US-010 - Support template import and export
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: remove local-only dirs from git tracking (.agents, .cursor, scripts, screenshots)
These directories contain local IDE configs, agent scripts, and
dev tooling that should not be part of the upstream repository.
Added them to .gitignore to prevent future accidental commits.
* chore: remove AGENTS.md from git tracking
* fix: add missing i18n keys for template export/import (en/zh/zh-Hant/ja)
* fix: review fixes for my-templates PR
- Fix fragile querySelector("form") with id-based lookup
- Add objectStoreNames.contains guards for IndexedDB upgrades
- Remove duplicate TemplateSchema, import from template-storage
- Revert contributor-specific .gitignore additions
- Fix broken i18n placeholders and missing translations (zh/ja/zh-Hant)
- Remove unused setFiles prop from ChatLobby
- Remove tags feature (unnecessary complexity)
- Improve template card layout: overlay icons on hover, align stats
- Add break-all and overflow-hidden for long prompt text in dialogs
- Move incrementClickCount into sendTemplate for accurate tracking
- Use Intl.RelativeTimeFormat for locale-aware relative time
* feat: restore Quick Examples panel and add lobby panel visibility settings
Bring back the ExamplePanel as a third collapsible section in ChatLobby
alongside Recent Chats and My Templates. Add toggle switches in Settings
to show/hide each lobby panel, persisted via localStorage.
* fix: template send race condition, import defaults, and empty title bug
- Use flushSync instead of setTimeout(0) in handleSendTemplate to
ensure React state is flushed before form submission
- Explicitly validate and default all fields in importTemplates to
prevent undefined counters from malformed import JSON
- Fall back to existing title in edit dialog instead of writing undefined
* fix: address Copilot review comments and remove PRD file
- Fix fallback formatLastUsed returning "Not used yet" for recent usage
- Remove dead mounted flag in TemplatePanel useEffect
- Respect panel visibility settings in no-history lobby state
- Reject empty/whitespace titles in import validation
- Trim title/prompt in importTemplates with default title fallback
- Remove tasks/prd-template-library-replaces-examples.md from repo
* fix: remove double sort, dead code, redundant stats, and break-all CSS
- Remove redundant sortTemplates call in loadTemplates (already sorted by getAllTemplates)
- Remove unused createEmptyTemplateInput and sortTemplates import
- Show "Not used yet" only once for unused templates instead of twice
- Use break-words instead of break-all on prompt textareas
---------
Co-authored-by: 杜雷 <dreamfly@126.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
- Replace newyear-referral URL with new Coding Plan referral URL across all files
- Update model name from K2-thinking to glm-4.7
- Add volcengine invite poster to Chinese README and about page
* feat: add custom system message setting for AI personalization
Allow users to enter custom instructions via a textarea in Settings
that get appended to the AI's system prompt. Includes server-side
validation (type check + 5000 char limit), localStorage persistence,
and i18n support for all 4 locales.
* fix: add accessibility htmlFor/id pairing on custom system message textarea
* feat: Add support for Chinese AI providers (GLM, Qwen, Kimi, MiniMax, Qiniu)
- Add minimax, glm, qwen, qiniu, kimi to ProviderName type
- Add provider configurations to PROVIDER_INFO with default base URLs
- Add suggested models for MiniMax in SUGGESTED_MODELS
- Add minimax/glm/qwen/qiniu/kimi cases to getAIModel using OpenAI-compatible SDK
- Update ALLOWED_CLIENT_PROVIDERS and error messages
- Add environment variable examples to env.example
Fixes: MiniMax API compatibility issue (invalid chat setting 2013)
* fix: Add missing providers to PROVIDER_ENV_VARS type
* fix: Handle null case in PROVIDER_ENV_VARS for new providers
* fix: Add minimax/glm/qwen/kimi/qiniu support to validate-model API
- Add getDefaultBaseUrl helper function
- Add validation cases for new providers in validate-model route
* fix: Add new providers to buildProviderOptions switch case
* fix: Merge multiple system messages into one for minimax/glm/qwen/kimi/qiniu
MiniMax API doesn't support multiple system messages.
This fix combines them into a single message for Chinese providers.
* fix: Handle null provider in system message check
* debug: Add logging for allMessages count
* fix: Use effective provider (including env var fallback) for isSingleSystemProvider check
* fix: apply biome formatting (line-wrapping)
* docs: add Chinese AI providers documentation (MiniMax, GLM, Qwen, Kimi, Qiniu)
- Add i18n translations for new providers in all language dictionaries
- Add provider configuration documentation in en/cn/ja docs
* fix: 改进 PR #722 的代码审查反馈
1. 删除重复的 getDefaultBaseUrl 函数,改用 model-config.ts 的 PROVIDER_INFO
2. validate-model 路由改用 AI SDK 的 createOpenAI + generateText
3. 修复 resolveBaseURL 回退逻辑,传入 PROVIDER_INFO 的 defaultBaseUrl
4. 删除无用的 .bak 备份文件
Co-authored-by: Shinyi <shinyi@openclaw.ai>
* fix: 修正中国 AI provider 端点配置
- qiniu: api.qiniucdn.com → api.qnaigc.com
- qwen: dashscope.aliyun.com → dashscope.aliyuncs.com
- 更新 env.example 文档链接
Co-authored-by: Shinyi <shinyi@openclaw.ai>
* feat: MiniMax 使用 Anthropic 兼容 API
- MiniMax 改用 createAnthropic (而非 createOpenAI)
- 支持 api.minimax.io/anthropic 和 api.minimaxi.com/anthropic
- 合并多个 system 消息为单个 (MiniMax/GLM/Qwen/Kimi/Qiniu)
- 更新默认模型为 MiniMax-M2.5 系列
- 支持 MINIMAX_BASE_URL 环境变量配置
Co-authored-by: Shinyi <shinyi@openclaw.ai>
* docs: 更新 MiniMax 文档
- 添加 Anthropic 兼容 API 说明
- 更新默认模型为 MiniMax-M2.5
- 添加国际版/中国大陆版配置示例
- 更新 env.example 注释
Co-authored-by: Shinyi <shinyi@openclaw.ai>
* fix: 完善 MiniMax 双端点支持及问题修复
- 支持 MiniMax Anthropic 兼容端点和 OpenAI 兼容端点自动切换
- 修正默认端点为 api.minimaxi.com (中国大陆可用)
- 修复端点路径缺少 /v1 的问题
- 添加前端 MiniMax logo 映射
- 移除调试日志
- 修正 env.example 默认配置
* chore: clean backup artifacts and align biome formatting
* fix: resolve effectiveProvider bug, deduplicate MiniMax URL logic, fix docs
- Fix critical bug: effectiveProvider was empty during auto-detection,
causing multi-system-message to be sent to MiniMax (which rejects it).
Now uses resolved provider from getAIModel instead of re-deriving it.
- Extract normalizeMiniMaxBaseURL() shared helper to eliminate duplication
between ai-providers.ts and validate-model/route.ts
- Add guard for undefined MiniMax baseURL to prevent hitting api.anthropic.com
- Fix docs: mark China mainland URL as default (matches code behavior)
- Restructure minimax/glm/qwen/kimi/qiniu validation to use shared pattern
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: document MiniMax dual API formats in docs and UI
- Add hint below Base URL input when MiniMax is selected, explaining
Anthropic-compatible (/anthropic) vs OpenAI-compatible (/v1) endpoints
- Update all 3 ai-providers docs (en/cn/ja) to list all 4 endpoint options
(China/International × Anthropic/OpenAI)
- Add i18n translations for the hint in all 4 locales
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: deduplicate PROVIDER_LOGO_MAP, remove unnecessary optional chaining
- Extract PROVIDER_LOGO_MAP to lib/types/model-config.ts (was duplicated
in model-config-dialog.tsx and model-selector.tsx)
- Remove unnecessary ?. on PROVIDER_INFO.minimax (it's a full Record)
---------
Co-authored-by: msga-oc <msga-oc@gitea.misakiga.top>
Co-authored-by: Shinyi <shinyi@openclaw.ai>
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: Turn off certain features of quota popup for self-hosting
This commit introduces a new variable, NEXT_PUBLIC_SELFHOSTED,
that alters the behavior of the quota popup. Downstream
consumers of the application may have their own quota-checking
logic, and the front-end reacts to the 429 error by displaying
the quota popup. In the case of a self-hosted version of the app,
it is inappropriate to ask for sponsorship or provide a
hyperlink to the public version of the tool to apply for an
increased quota. An alternative string translation is provided
with an empty message for adopter customization.
To use this feature, compile with NEXT_PUBLIC_SELFHOSTED=true
and those parts of the quota popup will be omitted.
The downstream consumer is still expected to customize
the internationalized strings for the popup content
to be appropriate to their organization on their local forks.
Signed-off-by: Bryon Nevis <bryon.nevis@intel.com>
* refactor: improve readability and provide sensible selfhosted defaults
- Extract nested ternary expressions into quotaMessage and tipHtml variables
- Combine two separate !isSelfHosted conditional blocks into one
- Replace null tipSelfHosted with meaningful default strings across all locales
---------
Signed-off-by: Bryon Nevis <bryon.nevis@intel.com>
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
The Lint & Unit Tests PR status check is failing
at the "Run lint" step over a half-dozen issues.
This is causing all PR's to fail the Lint & Unit tets check.
This fix resolves those issues.
Signed-off-by: Bryon Nevis <bryon.nevis@intel.com>
* Add Ollama Cloud support with Base URL and API Key configuration
* implemented feedback
* fix: use OLLAMA_BASE_URL env fallback in validate-model endpoint
* Remove dedicated Ollama configuration block
* security(ollama): prevent API key leak to client-controlled URLs
* added test
* fix: security hardening and Ollama Cloud default URL
- Add server OLLAMA_API_KEY fallback to validate-model endpoint with
SSRF guard mirroring ai-providers.ts
- Tighten top-level SSRF exemption: only exempt Ollama when no server
OLLAMA_API_KEY is configured
- Update Electron config to support OLLAMA_API_KEY env var
- Change default Ollama URL from localhost:11434 to ollama.com/api
(Ollama Cloud) for web UI users
- Add tests for server env combo, API-key-only, and SSRF guard scenarios
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
* feat(ui): conditional model selector shadow logic (#678)
- Update ModelSelectorList to conditionally render shadow based on scroll state
- Update CommandList to forward ref for scroll detection
- Resolves#678
* Update components/ui/command.tsx
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* fix(ui): update listRef type to match CommandList forwarded ref
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* enhancement: Pin Configure Models button to bottom of model selector (#637)
Keep "Configure Models..." and info text fixed at bottom of dropdown when the model list scrolls. Wire button to open Model Config dialog.
* Address PR review: use ModelSelectorItem, z-10 footer, padding on wrapper
* fix: reduce spacing between Configure Models button and info text
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
Enables ref forwarding for improved integration with parent components
and libraries that require direct DOM access. Enhances flexibility and
maintainability by switching to a forwardRef implementation.
Add full Traditional Chinese support for Hong Kong/Taiwan users by
creating a zh-Hant dictionary and registering the locale across the
web app, metadata, and Electron desktop menu system.
- Enable draw.io autosave and handle autosave events to update chartXML
- Clear modified state after autosave to avoid beforeunload prompts
- Disable confirmExit in draw.io configuration
- Set modified=false and keepmodified=false URL parameters
- Fix session save condition to also save when only diagram exists
- Fix: Do not close shared IndexedDB connection in isIndexedDBUsable()
This reverts commit e7c29fb410.
The PR introduced an IndexedDB error: 'Failed to execute transaction on IDBDatabase: The database connection is closing.'
* fix(electron): prevent beforeunload prompt by using autosave
- Enable draw.io autosave and handle autosave events to update chartXML
- Clear modified state after autosave to avoid beforeunload prompts
- Disable confirmExit in draw.io configuration
- Set modified=false and keepmodified=false URL parameters
- Fix session save condition to also save when only diagram exists
* fix: persist diagram-only saves and ref typing
* fix: harden persistence checks and export timeout
* enhancement: Add URL format hint to Base URL field (#593)
Add dynamic provider-specific format examples to Base URL field labels to clarify expected URL format. Includes missing defaultBaseUrl values for providers.
* fix: Use generic example URL instead of OpenAI URL for fallback
* [Feature] Add VLM-based diagram validation
Add automatic VLM (Vision Language Model) validation after display_diagram
tool execution. The system captures a screenshot of the rendered diagram,
sends it to a VLM for visual analysis, and uses feedback to improve
diagram quality through the existing retry mechanism.
Changes:
- Add /api/validate-diagram endpoint for VLM validation
- Add diagram-validator.ts for client-side validation orchestration
- Add validation-prompts.ts for VLM system prompts
- Add ValidationCard component to display validation status in chat
- Add PNG capture functionality to diagram context
- Integrate validation into tool handlers with retry support (max 3)
- Add "Improve with Suggestions" button for manual regeneration
- Add settings toggle to enable/disable VLM validation
- Add getValidationModel() helper in ai-providers.ts
* refactor(validation): use AI SDK structured outputs and address review feedback
- Replace generateText + manual JSON parsing with generateObject and Zod schema
for type-safe structured validation output
- Use AbortSignal.timeout() instead of Promise.race for cleaner timeout handling
- Add timeout validation with minimum 1000ms to handle malformed env values
- Remove unused xml parameter from validateRenderedDiagram API
- Remove parseValidationResponse function (now handled by schema)
- Clear validationStates on session switch and new chat to prevent memory leak
- Update 100ms render delay comment to clarify best-effort heuristic
- Remove unused useEffect import from ValidationCard
- Fix optional chaining lint warning in ValidationCard
- Add unit tests for formatValidationFeedback function
* refactor(validation): use AI SDK experimental_useObject hook instead of raw fetch
- Change API endpoint from generateObject to streamObject for useObject compatibility
- Create useValidateDiagram hook using AI SDK's experimental_useObject for reactive validation
- Update useDiagramToolHandlers to accept validation function as parameter
- Update chat-panel to use new useValidateDiagram hook
- Remove validateRenderedDiagram function from lib/diagram-validator.ts (now in hook)
- Export ValidationResultSchema from API route for client-side use
* fix(validation): extract schema to shared file for client/server compatibility
Move ValidationResultSchema to lib/validation-schema.ts to avoid importing
server-side modules (ai-providers) into client-side code. This fixes the
Turbopack build error caused by the hook importing from the API route.
* fix(validation): use 'Valid' instead of 'Complete' for validation success
Change ValidationCard success label from 'Complete' to 'Valid' to avoid
conflicting with ToolCallCard's 'Complete' badge in E2E tests. This fixes
the diagram-generation E2E test that expects a specific count of 'Complete'
badges.
* fix(validation): add aria-hidden to icons to prevent duplicate ID warning
* fix: improve VLM validation with bug fixes and i18n
- Fix race condition in pendingValidationRef (reject previous pending validation)
- Fix response format consistency (use streaming for all responses)
- Remove dead code (unused lastRequestRef and ValidationRequest interface)
- Consolidate duplicate types (re-export from validation-schema.ts)
- Add 'success_with_warnings' status for valid diagrams with warnings
- Fix tool card auto-collapse (only collapse once, respect user toggle)
- Set VLM validation default to disabled
- Add i18n support for diagram validation settings (en/zh/ja)
- Mark feature as experimental in settings UI
* fix: resolve TypeScript errors in electron-standalone
- Add forwardRef support to ChatInput component with ChatInputRef type
- Copy electron.d.ts to electron-standalone/electron folder
- Exclude electron-standalone from root tsconfig type checking
* fix: return empty string for valid result with no issues in formatValidationFeedback
* feat(i18n): add validation strings for ValidationCard component
- Add validation section to en.json, zh.json, ja.json dictionaries
- Update ValidationCard to use useDictionary hook
- Replace all hardcoded English strings with i18n keys
---------
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
- Replace forwardRef/useImperativeHandle with prop-based focus control
- Add shouldFocus and onFocused props to ChatInput
- Use useEffect with setTimeout for proper cleanup
- Removes unnecessary complexity while maintaining same functionality