2025-12-20 20:18:54 +05:30
|
|
|
|
{
|
|
|
|
|
|
"common": {
|
|
|
|
|
|
"save": "保存",
|
|
|
|
|
|
"cancel": "取消",
|
|
|
|
|
|
"close": "关闭",
|
|
|
|
|
|
"confirm": "确认",
|
|
|
|
|
|
"clear": "清除",
|
|
|
|
|
|
"edit": "编辑",
|
|
|
|
|
|
"delete": "删除",
|
|
|
|
|
|
"loading": "加载中...",
|
|
|
|
|
|
"new": "新建"
|
|
|
|
|
|
},
|
|
|
|
|
|
"nav": {
|
|
|
|
|
|
"about": "关于",
|
|
|
|
|
|
"editor": "编辑器",
|
|
|
|
|
|
"newChat": "开始新对话",
|
2025-12-22 21:54:25 +08:00
|
|
|
|
"github": "GitHub",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"settings": "设置",
|
|
|
|
|
|
"hidePanel": "隐藏聊天面板 (Ctrl+B)",
|
|
|
|
|
|
"showPanel": "显示聊天面板 (Ctrl+B)",
|
2025-12-30 23:45:31 +09:00
|
|
|
|
"aiChat": "AI 聊天"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"providers": {
|
|
|
|
|
|
"useServerDefault": "使用服务器默认值",
|
|
|
|
|
|
"openai": "OpenAI",
|
|
|
|
|
|
"anthropic": "Anthropic",
|
|
|
|
|
|
"google": "Google",
|
|
|
|
|
|
"azure": "Azure OpenAI",
|
|
|
|
|
|
"openrouter": "OpenRouter",
|
|
|
|
|
|
"deepseek": "DeepSeek",
|
2026-01-06 18:41:25 +08:00
|
|
|
|
"siliconflow": "SiliconFlow",
|
feat: Add support for Chinese AI providers (GLM, Qwen, Kimi, MiniMax, Qiniu)
* 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>
2026-03-07 17:53:47 +08:00
|
|
|
|
"modelscope": "ModelScope",
|
|
|
|
|
|
"minimax": "MiniMax",
|
|
|
|
|
|
"glm": "GLM",
|
|
|
|
|
|
"qwen": "Qwen",
|
|
|
|
|
|
"kimi": "Kimi",
|
2026-07-12 08:10:12 +08:00
|
|
|
|
"qiniu": "Qiniu",
|
|
|
|
|
|
"mimo": "MiMo (小米)"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"chat": {
|
|
|
|
|
|
"placeholder": "描述您的图表或上传文件...",
|
|
|
|
|
|
"send": "发送",
|
2026-01-29 19:10:25 +05:30
|
|
|
|
"stopGeneration": "停止生成",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"sendMessage": "发送消息",
|
|
|
|
|
|
"clearConversation": "清除对话",
|
|
|
|
|
|
"diagramHistory": "图表历史",
|
|
|
|
|
|
"saveDiagram": "保存图表",
|
|
|
|
|
|
"uploadFile": "上传文件(图片、PDF、文本)",
|
|
|
|
|
|
"minimalStyle": "简约",
|
|
|
|
|
|
"styledMode": "精致",
|
|
|
|
|
|
"minimalTooltip": "使用简约模式以加快生成速度(无颜色)",
|
|
|
|
|
|
"regenerate": "重新生成响应",
|
|
|
|
|
|
"copyResponse": "复制响应",
|
|
|
|
|
|
"copied": "已复制!",
|
|
|
|
|
|
"failedToCopy": "复制失败",
|
2025-12-30 19:52:57 +08:00
|
|
|
|
"failedToCopyDetail": "复制消息失败。请手动复制或检查剪贴板权限。",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"goodResponse": "有帮助",
|
|
|
|
|
|
"badResponse": "无帮助",
|
|
|
|
|
|
"clickToEdit": "点击编辑",
|
|
|
|
|
|
"editMessage": "编辑消息",
|
2026-01-05 20:53:50 +05:30
|
|
|
|
"saveAndSubmit": "保存并提交",
|
|
|
|
|
|
"ExtractURL": "从 URL 提取"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"examples": {
|
|
|
|
|
|
"title": "用 AI 创建图表",
|
|
|
|
|
|
"subtitle": "描述您想要创建的内容或上传图片进行复制",
|
|
|
|
|
|
"quickExamples": "快速示例",
|
|
|
|
|
|
"paperToDiagram": "文档转图表",
|
|
|
|
|
|
"paperDescription": "上传 .pdf, .txt, .md, .json, .csv, .py, .js, .ts 等文件",
|
|
|
|
|
|
"animatedDiagram": "动画图表",
|
|
|
|
|
|
"animatedDescription": "绘制带有动画连接器的 Transformer 架构",
|
|
|
|
|
|
"awsArchitecture": "AWS 架构",
|
|
|
|
|
|
"awsDescription": "使用 AWS 图标创建云架构图",
|
|
|
|
|
|
"replicateFlowchart": "复制流程图",
|
|
|
|
|
|
"replicateDescription": "上传并复制现有流程图",
|
|
|
|
|
|
"creativeDrawing": "创意绘图",
|
|
|
|
|
|
"creativeDescription": "绘制有趣且富有创意的内容",
|
|
|
|
|
|
"cachedNote": "示例已缓存,可即时响应",
|
|
|
|
|
|
"mcpServer": "MCP 服务器",
|
2026-04-06 10:17:38 +09:00
|
|
|
|
"mcpDescription": "在 Claude Desktop、VS Code 和 Cursor 中使用"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"settings": {
|
|
|
|
|
|
"title": "设置",
|
|
|
|
|
|
"description": "配置您的应用程序设置。",
|
2026-01-28 14:36:54 +01:00
|
|
|
|
"apiKeysModels": "API 密钥和模型",
|
|
|
|
|
|
"apiKeysModelsDescription": "配置 AI 提供商和 API 密钥。",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"accessCode": "访问码",
|
|
|
|
|
|
"accessCodePlaceholder": "输入访问码",
|
|
|
|
|
|
"accessCodeDescription": "使用此应用程序需要访问码。",
|
|
|
|
|
|
"aiProvider": "AI 提供商设置",
|
|
|
|
|
|
"aiProviderDescription": "使用您自己的 API 密钥来绕过使用限制。您的密钥仅存储在浏览器本地,不会存储在服务器上。",
|
|
|
|
|
|
"provider": "提供商",
|
|
|
|
|
|
"modelId": "模型 ID",
|
|
|
|
|
|
"apiKey": "API 密钥",
|
|
|
|
|
|
"apiKeyPlaceholder": "您的 API 密钥",
|
|
|
|
|
|
"baseUrl": "基础 URL(可选)",
|
|
|
|
|
|
"customEndpoint": "自定义端点 URL",
|
|
|
|
|
|
"overrides": "覆盖",
|
|
|
|
|
|
"clearSettings": "清除设置",
|
|
|
|
|
|
"useServerDefault": "使用服务器默认值",
|
2025-12-22 21:54:25 +08:00
|
|
|
|
"language": "语言",
|
|
|
|
|
|
"languageDescription": "选择界面语言。",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"theme": "主题",
|
|
|
|
|
|
"themeDescription": "界面和 DrawIO 画布的深色/浅色模式。",
|
|
|
|
|
|
"drawioStyle": "DrawIO 样式",
|
2026-05-15 22:14:20 +08:00
|
|
|
|
"drawioStyleDescription": "画布样式",
|
|
|
|
|
|
"themeDefault": "默认",
|
|
|
|
|
|
"themeDark": "深色",
|
|
|
|
|
|
"themeMinimal": "简约",
|
|
|
|
|
|
"themeSketch": "草图",
|
|
|
|
|
|
"themeSimple": "简单",
|
2025-12-28 18:46:10 +05:30
|
|
|
|
"diagramStyle": "图表样式",
|
|
|
|
|
|
"diagramStyleDescription": "切换简约与精致图表输出模式。",
|
2026-01-11 07:54:32 +06:00
|
|
|
|
"sendShortcut": "发送快捷键",
|
|
|
|
|
|
"sendShortcutDescription": "选择发送消息的方式。",
|
|
|
|
|
|
"enterToSend": "回车发送",
|
|
|
|
|
|
"ctrlEnterToSend": "Cmd/Ctrl+回车发送",
|
2025-12-28 18:46:10 +05:30
|
|
|
|
"diagramActions": "图表操作",
|
|
|
|
|
|
"diagramActionsDescription": "管理图表历史记录和导出",
|
|
|
|
|
|
"history": "历史记录",
|
2026-01-09 09:26:19 +09:00
|
|
|
|
"download": "下载",
|
|
|
|
|
|
"proxy": "代理设置",
|
|
|
|
|
|
"proxyDescription": "配置 API 请求的 HTTP/HTTPS 代理(仅桌面版)",
|
|
|
|
|
|
"httpProxy": "HTTP 代理",
|
|
|
|
|
|
"httpsProxy": "HTTPS 代理",
|
|
|
|
|
|
"applyProxy": "应用",
|
2026-01-20 20:52:04 +09:00
|
|
|
|
"proxyApplied": "代理设置已应用",
|
|
|
|
|
|
"diagramValidation": "图表验证(实验性)",
|
|
|
|
|
|
"diagramValidationDescription": "使用视觉语言模型验证生成的图表。需要支持视觉的模型,如 GPT-5.2 或 Sonnet-4.5。",
|
|
|
|
|
|
"enabled": "已启用",
|
2026-03-07 19:07:54 +09:00
|
|
|
|
"disabled": "已禁用",
|
|
|
|
|
|
"customSystemMessage": "自定义系统消息",
|
|
|
|
|
|
"customSystemMessageDescription": "添加自定义指令,将附加到 AI 的系统提示末尾。",
|
feat: add personal My Templates library alongside Quick Examples (#773)
* 增加了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>
2026-04-03 11:16:01 +08:00
|
|
|
|
"customSystemMessagePlaceholder": "例如:图表始终使用蓝色配色方案...",
|
fix: raise the output budget so reasoning models reach the tool call (#927)
* fix: raise the output budget so reasoning models reach the tool call
A reasoning model spends the output budget in order: thinking first, then prose,
then the tool call. With 16000 the thinking alone can consume all of it, so the
turn ends with finishReason "length" before display_diagram is ever called. The
canvas stays empty and nothing surfaces in the UI, because no tool call means no
tool error, and the client never reads finishReason.
Measured on openrouter deepseek/deepseek-v4-flash, the model from the report:
- max_tokens=800 with reasoning on returns reasoning_tokens=800, empty content,
finish_reason length. So reasoning is billed against this budget, not exempt.
- refining an existing diagram (19k chars of XML in the input) produced 49142
chars of reasoning, zero tool calls, finishReason "length" at 16000
- the same request at 40000 finished and called edit_diagram with 12 operations
64000 cannot just be sent to every model: bedrock claude-3-haiku caps at 4096,
nova-lite at 10000, and the openrouter deepseek-r1 endpoint counts input and
output against one 64000 ceiling. All three name the real limit in the 400, so
parse it and retry once. Verified: nova-lite logs "64000 rejected, retrying with
10000" and then completes its tool call.
Also expose the budget in Settings. It is sent as a header rather than read from
env only, so desktop users can raise it themselves without an env file.
vercel.json goes back to the 300s it had before #238 traded it for $2-4/month.
That is now Vercel's own default, and billing pauses while the function waits on
the model, so the saving that motivated 120s no longer applies. edgeone.json is
left alone: its 120 may be that platform's actual ceiling.
* fix: only reinterpret an error as a budget rejection when it says so
Review of the first commit found the retry could fire on errors that have
nothing to do with the budget, which would replace a readable provider error
with a truncated response: exactly the symptom this PR exists to remove.
- Drop the generic "lower than N" pattern. For the Bedrock message it was dead
code, since "model limit of N" matches first with the same number. Left live,
it would read a number out of any message shaped like "must be lower than 2".
- Skip errors whose status is not 400 or 422, so auth and rate-limit failures
are never reinterpreted.
- Require the parsed ceiling to be at least 1024. Below that a diagram cannot
come out whole, so retrying would hide the error behind broken XML.
- Validate MAX_OUTPUT_TOKENS from env the same way as the header, so a stray
"-1" falls back instead of reaching the provider.
Adds tests for the retry wrapper itself, which had none: it retries once with
the named ceiling, leaves a 401 alone, does not retry when the ceiling is not
smaller, propagates a second rejection, and preserves the other call options.
Re-verified against the live APIs: bedrock nova-lite still logs "64000 rejected,
retrying with 10000" and completes its tool call, and deepseek-v4-flash still
finishes normally at 64000.
2026-08-22 20:47:10 +09:00
|
|
|
|
"maxOutputTokens": "最大输出 token 数",
|
|
|
|
|
|
"maxOutputTokensDescription": "单次回复的额度,思考过程和图表 XML 共用。如果 AI 一直在思考却没有生成图表,请把它调大。留空则使用默认值。",
|
feat: add personal My Templates library alongside Quick Examples (#773)
* 增加了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>
2026-04-03 11:16:01 +08:00
|
|
|
|
"panelVisibility": "大厅面板",
|
|
|
|
|
|
"panelVisibilityDescription": "选择在聊天大厅显示哪些面板。",
|
|
|
|
|
|
"showRecentChats": "最近聊天",
|
|
|
|
|
|
"showMyTemplates": "我的模板",
|
|
|
|
|
|
"showQuickExamples": "快速示例"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"save": {
|
|
|
|
|
|
"title": "保存图表",
|
|
|
|
|
|
"description": "选择格式和文件名以保存您的图表。",
|
|
|
|
|
|
"format": "格式",
|
|
|
|
|
|
"filename": "文件名",
|
|
|
|
|
|
"filenamePlaceholder": "输入文件名",
|
|
|
|
|
|
"formats": {
|
|
|
|
|
|
"drawio": "Draw.io XML",
|
|
|
|
|
|
"png": "PNG 图片",
|
2026-04-03 07:50:57 +08:00
|
|
|
|
"svg": "SVG 图片",
|
|
|
|
|
|
"xmlsvg": "可编辑 SVG"
|
2026-01-04 09:41:32 +05:30
|
|
|
|
},
|
|
|
|
|
|
"savedSuccessfully": "保存成功!"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"history": {
|
|
|
|
|
|
"title": "图表历史",
|
|
|
|
|
|
"description": "在 AI 修改之前保存的每个图表。\n点击图表以恢复它",
|
|
|
|
|
|
"noHistory": "尚无历史记录。发送消息以创建图表历史。",
|
|
|
|
|
|
"version": "版本",
|
|
|
|
|
|
"restoreTo": "恢复到版本 {version}?"
|
|
|
|
|
|
},
|
|
|
|
|
|
"dialogs": {
|
|
|
|
|
|
"clearTitle": "清除所有内容?",
|
|
|
|
|
|
"clearDescription": "这将清除当前对话并重置图表。此操作无法撤消。",
|
|
|
|
|
|
"clearEverything": "清除所有内容",
|
|
|
|
|
|
"clearSuccess": "已开始新对话"
|
|
|
|
|
|
},
|
|
|
|
|
|
"errors": {
|
|
|
|
|
|
"maxFiles": "文件太多。最多允许 {max} 个。",
|
|
|
|
|
|
"onlyMoreAllowed": "只能再添加 {slots} 个文件",
|
|
|
|
|
|
"fileExceeds": "\"{name}\" 大小为 {size}(超过 {max}MB)",
|
|
|
|
|
|
"unsupportedType": "\"{name}\" 不是支持的文件类型",
|
|
|
|
|
|
"filesRejected": "{count} 个文件被拒绝:",
|
|
|
|
|
|
"andMore": "...还有 {count} 个",
|
|
|
|
|
|
"invalidAccessCode": "无效或缺少访问码。请在设置中配置。",
|
|
|
|
|
|
"networkError": "网络错误。请检查您的连接。",
|
|
|
|
|
|
"retryLimit": "已达到自动重试限制({max})。请手动重试。",
|
2025-12-30 19:52:57 +08:00
|
|
|
|
"continuationRetryLimit": "已达到继续重试限制({max})。图表可能过于复杂。",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"validationFailed": "图表验证失败。请尝试重新生成。",
|
|
|
|
|
|
"malformedXml": "AI 生成的图表 XML 无效。请尝试重新生成。",
|
|
|
|
|
|
"failedToProcess": "无法处理图表。请尝试重新生成。",
|
|
|
|
|
|
"sessionCorrupted": "会话数据已损坏。重新开始。",
|
|
|
|
|
|
"failedToSave": "无法保存消息到 localStorage",
|
|
|
|
|
|
"failedToRestore": "无法从 localStorage 恢复",
|
|
|
|
|
|
"failedToPersist": "卸载前无法持久化状态",
|
|
|
|
|
|
"failedToExport": "获取图表数据时出错",
|
2025-12-30 19:52:57 +08:00
|
|
|
|
"failedToLoadExample": "加载示例图片时出错",
|
|
|
|
|
|
"failedToRecordFeedback": "记录您的反馈失败。请重试。",
|
|
|
|
|
|
"storageUpdateFailed": "聊天已清除,但无法更新浏览器存储"
|
2025-12-20 20:18:54 +05:30
|
|
|
|
},
|
|
|
|
|
|
"quota": {
|
|
|
|
|
|
"dailyLimit": "已达每日配额",
|
|
|
|
|
|
"tokenLimit": "已达每日令牌限制",
|
|
|
|
|
|
"tpmLimit": "速率限制",
|
|
|
|
|
|
"tpmMessage": "请求过多。请稍等片刻。",
|
2025-12-22 19:30:20 +05:30
|
|
|
|
"tpmMessageDetailed": "达到速率限制({limit} 令牌/分钟)。请等待 {seconds} 秒后再发送请求。",
|
2025-12-29 12:12:22 +09:00
|
|
|
|
"messageApi": "看来您今天的体验次数已达上限。非常高兴您玩得开心,虽然本项目由字节跳动豆包慷慨赞助,但为了确保大家都能公平使用,我们不得不对使用量做一点小小的限制。",
|
2026-02-27 07:34:05 -08:00
|
|
|
|
"messageApiSelfHosted": null,
|
2025-12-29 12:12:22 +09:00
|
|
|
|
"messageToken": "看来您今天的 Token 用量已达上限。非常高兴您玩得开心,虽然本项目由字节跳动豆包慷慨赞助,但为了确保大家都能公平使用,我们不得不对使用量做一点小小的限制。",
|
2026-02-27 07:34:05 -08:00
|
|
|
|
"messageTokenSelfHosted": null,
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"tip": "<strong>提示:</strong>您可以使用自己的 API 密钥(点击设置图标)或自托管项目来绕过这些限制。",
|
2026-02-27 07:34:05 -08:00
|
|
|
|
"tipSelfHosted": "<strong>提示:</strong>您可以在设置中配置自己的 API 密钥以继续使用服务。",
|
2025-12-29 12:12:22 +09:00
|
|
|
|
"reset": "您的限制将在明天重置。感谢您的理解。",
|
|
|
|
|
|
"doubaoSponsorship": "<a href=\"{link}\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"underline hover:text-foreground\">点击此处注册</a>可获得每个模型 50 万免费 Token(包括豆包、DeepSeek 和 Kimi),然后在模型设置中配置您的 API Key。",
|
|
|
|
|
|
"configModel": "使用您的密钥",
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"selfHost": "自托管",
|
|
|
|
|
|
"sponsor": "赞助",
|
|
|
|
|
|
"learnMore": "了解更多 →",
|
|
|
|
|
|
"usedOf": "{used}/{limit}"
|
|
|
|
|
|
},
|
|
|
|
|
|
"tools": {
|
|
|
|
|
|
"generateDiagram": "生成图表",
|
|
|
|
|
|
"editDiagram": "编辑图表",
|
|
|
|
|
|
"appendDiagram": "继续图表",
|
|
|
|
|
|
"complete": "完成",
|
|
|
|
|
|
"error": "错误",
|
|
|
|
|
|
"truncated": "已截断"
|
|
|
|
|
|
},
|
|
|
|
|
|
"file": {
|
|
|
|
|
|
"reading": "读取中...",
|
|
|
|
|
|
"chars": "字符",
|
|
|
|
|
|
"removeFile": "移除文件"
|
|
|
|
|
|
},
|
2026-01-05 20:53:50 +05:30
|
|
|
|
"url": {
|
|
|
|
|
|
"title": "从 URL 提取内容",
|
|
|
|
|
|
"description": "粘贴 URL 以提取和分析其内容",
|
|
|
|
|
|
"Extracting": "提取中...",
|
|
|
|
|
|
"extract": "提取",
|
|
|
|
|
|
"Cancel": "取消",
|
|
|
|
|
|
"enterUrl": "请输入 URL",
|
|
|
|
|
|
"invalidFormat": "URL 格式无效"
|
|
|
|
|
|
},
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"reasoning": {
|
|
|
|
|
|
"thinking": "思考中...",
|
|
|
|
|
|
"thoughtFor": "思考了 {duration} 秒",
|
|
|
|
|
|
"thoughtBrief": "思考了几秒钟"
|
|
|
|
|
|
},
|
2025-12-30 19:52:57 +08:00
|
|
|
|
"dev": {
|
|
|
|
|
|
"title": "开发:XML 流式模拟器",
|
|
|
|
|
|
"preset": "预设:",
|
|
|
|
|
|
"selectPreset": "选择预设...",
|
|
|
|
|
|
"clear": "清除",
|
|
|
|
|
|
"placeholder": "在此粘贴 mxCell XML 或选择预设...",
|
|
|
|
|
|
"interval": "间隔:",
|
|
|
|
|
|
"chars": "字符:",
|
|
|
|
|
|
"streaming": "流式传输中...",
|
|
|
|
|
|
"simulate": "模拟",
|
|
|
|
|
|
"stop": "停止",
|
|
|
|
|
|
"testQuotaToast": "测试配额提示",
|
|
|
|
|
|
"simulatingMessage": "[开发] 模拟 XML 流式传输",
|
|
|
|
|
|
"successMessage": "成功显示图表。"
|
|
|
|
|
|
},
|
2025-12-20 20:18:54 +05:30
|
|
|
|
"about": {
|
|
|
|
|
|
"modelChange": "模型变更与用量限制",
|
|
|
|
|
|
"walletCrying": "(别名:我的钱包顶不住了)",
|
|
|
|
|
|
"seekingSponsorship": "寻求赞助(求大佬捞一把)",
|
|
|
|
|
|
"contactMe": "联系我",
|
|
|
|
|
|
"usageNotice": "由于使用量过高,我已将模型从 Claude 更换为 minimax-m2,并设置了一些用量限制。详情请查看关于页面。"
|
feat: multi-provider model configuration with UI/UX improvements (#355)
* feat: add multi-provider model configuration
- Add model config dialog for managing multiple AI providers
- Support for OpenAI, Anthropic, Google, Azure, Bedrock, OpenRouter, DeepSeek, SiliconFlow, Ollama, and AI Gateway
- Add model selector dropdown in chat panel header
- Add API key validation endpoint
- Add custom model ID input with keyboard navigation
- Fix hover highlight in Command component
- Add suggested models for each provider including latest Claude 4.5 series
- Store configuration locally in browser
* feat: improve model config UI and move selector to chat input
- Move model selector from header to chat input (left of send button)
- Add per-model validation status (queued, running, valid, invalid)
- Filter model selector to only show verified models
- Add editable model IDs in config dialog
- Add custom model input field alongside suggested models dropdown
- Fix hover states on provider buttons and select triggers
- Update OpenAI suggested models with GPT-5 series
- Add alert-dialog component for delete confirmation
* refactor: revert shadcn component changes, apply hover fix at usage site
* feat: add AWS credentials support for Bedrock provider
- Add AWS Access Key ID, Secret Access Key, Region fields for Bedrock
- Show different credential fields based on provider type
- Update validation API to handle Bedrock with AWS credentials
- Add region selector with common AWS regions
* fix: reset Test button after validation completes
* fix: reset validation button to Test after success
* fix: complete bedrock support and UI/UX improvements
- Add bedrock to ALLOWED_CLIENT_PROVIDERS for client credentials
- Pass AWS credentials through full chain (headers → API → provider)
- Replace non-existent GPT-5 models with real ones (o1, o3-mini)
- Add accessibility: aria-labels, focus-visible rings, inline errors
- Add more AWS regions (Ohio, London, Paris, Mumbai, Seoul, São Paulo)
- Fix setTimeout cleanup with useRef on component unmount
- Fix TypeScript type consistency in getSelectedAIConfig fallback
* chore: remove unused code
- Remove unused setAccessCodeRequired state in chat-panel.tsx
- Remove unused getSelectedModel export in model-config.ts
* fix: UI/UX improvements for model configuration dialog
- Add gradient header styling with icon badge
- Change Configuration section icon from Key to Settings2
- Add duplicate model detection with warning banner and inline removal
- Filter out already-added models from suggestions dropdown
- Add type-to-confirm for deleting providers with 3+ models
- Enhance delete confirmation dialog with warning icon
- Improve model selector discoverability (show model name + chevron)
- Add truncation for long model names with title tooltip
- Remove AI provider settings from Settings dialog (now in Model Config)
- Extract ValidationButton into reusable component
* fix: prevent duplicate model IDs within same provider
- Block adding model if ID already exists in provider
- Block editing model ID to match existing model in provider
* fix: improve duplicate model ID notifications
- Add toast notification when trying to add duplicate model
- Allow free typing when editing model ID, validate on blur
- Show warning toast instead of blocking input
* fix: improve duplicate model validation UX in config dialog
- Add inline error display for duplicate model IDs
- Show red border on input when error exists
- Validate on blur with shake animation for edit errors
- Prevent saving empty model names
- Clear errors when user starts typing
- Simplify error styling (small red text, no heavy chips)
2025-12-22 22:36:36 +09:00
|
|
|
|
},
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
|
"sessionHistory": {
|
|
|
|
|
|
"tooltip": "聊天历史",
|
|
|
|
|
|
"newChat": "新对话",
|
|
|
|
|
|
"empty": "暂无聊天记录",
|
|
|
|
|
|
"emptyHint": "开始对话吧",
|
|
|
|
|
|
"today": "今天",
|
|
|
|
|
|
"yesterday": "昨天",
|
|
|
|
|
|
"thisWeek": "本周",
|
|
|
|
|
|
"earlier": "更早",
|
|
|
|
|
|
"deleteTitle": "删除此对话?",
|
|
|
|
|
|
"deleteDescription": "这将永久删除此聊天会话及其图表。此操作无法撤消。",
|
|
|
|
|
|
"recentChats": "最近对话",
|
|
|
|
|
|
"justNow": "刚刚",
|
|
|
|
|
|
"searchPlaceholder": "搜索对话...",
|
|
|
|
|
|
"noResults": "未找到对话"
|
|
|
|
|
|
},
|
feat: add personal My Templates library alongside Quick Examples (#773)
* 增加了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>
2026-04-03 11:16:01 +08:00
|
|
|
|
"templates": {
|
|
|
|
|
|
"title": "我的模板库",
|
|
|
|
|
|
"subtitle": "您的个人 prompt 库,快速创建图表",
|
|
|
|
|
|
"emptyTitle": "暂无模板",
|
|
|
|
|
|
"emptyDescription": "创建您的第一个模板,开始构建个人 prompt 库",
|
|
|
|
|
|
"createFirst": "创建第一个模板",
|
|
|
|
|
|
"neverUsed": "未使用过",
|
|
|
|
|
|
"usedCount": "使用 {count} 次",
|
|
|
|
|
|
"myTemplates": "我的模板",
|
|
|
|
|
|
"createTitle": "创建模板",
|
|
|
|
|
|
"createDescription": "保存常用 prompt 以便重复使用。模板帮助您快速开始常用工作流。",
|
|
|
|
|
|
"promptLabel": "提示词",
|
|
|
|
|
|
"promptPlaceholder": "描述您想要创建的图表...",
|
|
|
|
|
|
"promptRequired": "提示词不能为空",
|
|
|
|
|
|
"titleLabel": "标题",
|
|
|
|
|
|
"titlePlaceholder": "输入标题",
|
|
|
|
|
|
"titleHint": "留空则使用提示词前 20 个字符作为标题",
|
|
|
|
|
|
"descriptionLabel": "描述",
|
|
|
|
|
|
"descriptionPlaceholder": "为此模板添加描述",
|
|
|
|
|
|
"pinnedLabel": "置顶模板",
|
|
|
|
|
|
"pinnedHint": "置顶的模板会显示在列表顶部",
|
|
|
|
|
|
"createButton": "创建模板",
|
|
|
|
|
|
"createFailed": "创建模板失败,请重试。",
|
|
|
|
|
|
"editTitle": "编辑模板",
|
|
|
|
|
|
"editDescription": "更新模板内容和设置。",
|
|
|
|
|
|
"updateFailed": "更新模板失败,请重试。",
|
|
|
|
|
|
"duplicate": "复制",
|
|
|
|
|
|
"copySuffix": "(副本)",
|
|
|
|
|
|
"deleteTitle": "删除此模板?",
|
|
|
|
|
|
"deleteDescription": "此操作将永久删除该模板,无法撤销。",
|
|
|
|
|
|
"confirmSendTitle": "替换当前输入?",
|
|
|
|
|
|
"confirmSendDescription": "您有未发送的内容。发送此模板将替换它。",
|
|
|
|
|
|
"confirmSendButton": "发送模板",
|
|
|
|
|
|
"searchPlaceholder": "搜索模板...",
|
|
|
|
|
|
"searchNoResults": "没有匹配的模板",
|
|
|
|
|
|
"pin": "置顶",
|
|
|
|
|
|
"unpin": "取消置顶",
|
|
|
|
|
|
"saveAsTemplate": "保存为模板",
|
|
|
|
|
|
"exportTemplates": "导出模板",
|
|
|
|
|
|
"importTemplates": "导入模板",
|
|
|
|
|
|
"exportEmpty": "没有可导出的模板",
|
|
|
|
|
|
"exportSuccess": "成功导出 {count} 个模板",
|
|
|
|
|
|
"importNoFile": "请选择一个 JSON 文件",
|
|
|
|
|
|
"importFailed": "导入失败:{error}",
|
|
|
|
|
|
"importSuccess": "成功导入 {imported} 个模板,跳过 {skipped} 个重复"
|
|
|
|
|
|
},
|
2026-01-20 20:52:04 +09:00
|
|
|
|
"validation": {
|
|
|
|
|
|
"title": "验证图表",
|
|
|
|
|
|
"capturing": "截图中",
|
|
|
|
|
|
"validating": "验证中",
|
|
|
|
|
|
"validatingWithAttempt": "验证中 ({attempt}/{max})",
|
|
|
|
|
|
"valid": "通过",
|
|
|
|
|
|
"validWithWarnings": "通过(有警告)",
|
|
|
|
|
|
"issuesFound": "发现问题",
|
|
|
|
|
|
"error": "错误",
|
|
|
|
|
|
"skipped": "已跳过",
|
|
|
|
|
|
"capturedScreenshot": "截图预览:",
|
|
|
|
|
|
"issuesFoundLabel": "发现的问题:",
|
|
|
|
|
|
"suggestions": "建议:",
|
|
|
|
|
|
"passedValidation": "图表通过视觉验证 - 未发现问题。",
|
|
|
|
|
|
"improvementRequested": "改进请求已发送 - 请查看下方新图表",
|
|
|
|
|
|
"improveWithSuggestions": "根据建议改进",
|
|
|
|
|
|
"regenerateWithFeedback": "使用验证反馈重新生成图表"
|
|
|
|
|
|
},
|
feat: multi-provider model configuration with UI/UX improvements (#355)
* feat: add multi-provider model configuration
- Add model config dialog for managing multiple AI providers
- Support for OpenAI, Anthropic, Google, Azure, Bedrock, OpenRouter, DeepSeek, SiliconFlow, Ollama, and AI Gateway
- Add model selector dropdown in chat panel header
- Add API key validation endpoint
- Add custom model ID input with keyboard navigation
- Fix hover highlight in Command component
- Add suggested models for each provider including latest Claude 4.5 series
- Store configuration locally in browser
* feat: improve model config UI and move selector to chat input
- Move model selector from header to chat input (left of send button)
- Add per-model validation status (queued, running, valid, invalid)
- Filter model selector to only show verified models
- Add editable model IDs in config dialog
- Add custom model input field alongside suggested models dropdown
- Fix hover states on provider buttons and select triggers
- Update OpenAI suggested models with GPT-5 series
- Add alert-dialog component for delete confirmation
* refactor: revert shadcn component changes, apply hover fix at usage site
* feat: add AWS credentials support for Bedrock provider
- Add AWS Access Key ID, Secret Access Key, Region fields for Bedrock
- Show different credential fields based on provider type
- Update validation API to handle Bedrock with AWS credentials
- Add region selector with common AWS regions
* fix: reset Test button after validation completes
* fix: reset validation button to Test after success
* fix: complete bedrock support and UI/UX improvements
- Add bedrock to ALLOWED_CLIENT_PROVIDERS for client credentials
- Pass AWS credentials through full chain (headers → API → provider)
- Replace non-existent GPT-5 models with real ones (o1, o3-mini)
- Add accessibility: aria-labels, focus-visible rings, inline errors
- Add more AWS regions (Ohio, London, Paris, Mumbai, Seoul, São Paulo)
- Fix setTimeout cleanup with useRef on component unmount
- Fix TypeScript type consistency in getSelectedAIConfig fallback
* chore: remove unused code
- Remove unused setAccessCodeRequired state in chat-panel.tsx
- Remove unused getSelectedModel export in model-config.ts
* fix: UI/UX improvements for model configuration dialog
- Add gradient header styling with icon badge
- Change Configuration section icon from Key to Settings2
- Add duplicate model detection with warning banner and inline removal
- Filter out already-added models from suggestions dropdown
- Add type-to-confirm for deleting providers with 3+ models
- Enhance delete confirmation dialog with warning icon
- Improve model selector discoverability (show model name + chevron)
- Add truncation for long model names with title tooltip
- Remove AI provider settings from Settings dialog (now in Model Config)
- Extract ValidationButton into reusable component
* fix: prevent duplicate model IDs within same provider
- Block adding model if ID already exists in provider
- Block editing model ID to match existing model in provider
* fix: improve duplicate model ID notifications
- Add toast notification when trying to add duplicate model
- Allow free typing when editing model ID, validate on blur
- Show warning toast instead of blocking input
* fix: improve duplicate model validation UX in config dialog
- Add inline error display for duplicate model IDs
- Show red border on input when error exists
- Validate on blur with shake animation for edit errors
- Prevent saving empty model names
- Clear errors when user starts typing
- Simplify error styling (small red text, no heavy chips)
2025-12-22 22:36:36 +09:00
|
|
|
|
"modelConfig": {
|
|
|
|
|
|
"title": "AI 模型配置",
|
|
|
|
|
|
"description": "配置多个 AI 提供商和模型",
|
|
|
|
|
|
"configure": "配置",
|
|
|
|
|
|
"addProvider": "添加提供商",
|
|
|
|
|
|
"addModel": "添加模型",
|
|
|
|
|
|
"modelId": "模型 ID",
|
|
|
|
|
|
"modelLabel": "显示名称",
|
|
|
|
|
|
"streaming": "启用流式输出",
|
|
|
|
|
|
"deleteProvider": "删除提供商",
|
|
|
|
|
|
"deleteModel": "删除模型",
|
|
|
|
|
|
"noModels": "尚未配置模型。添加模型以开始使用。",
|
|
|
|
|
|
"selectProvider": "选择一个提供商或添加新的",
|
|
|
|
|
|
"configureMultiple": "配置多个 AI 提供商并轻松切换",
|
|
|
|
|
|
"apiKeyStored": "API 密钥存储在您的浏览器本地",
|
|
|
|
|
|
"test": "测试",
|
|
|
|
|
|
"validationError": "验证失败",
|
2025-12-23 11:42:27 +09:00
|
|
|
|
"addModelFirst": "请先添加至少一个模型以进行验证",
|
|
|
|
|
|
"providers": "提供商",
|
|
|
|
|
|
"addProviderHint": "添加提供商即可开始使用",
|
|
|
|
|
|
"verified": "已验证",
|
|
|
|
|
|
"configuration": "配置",
|
|
|
|
|
|
"displayName": "显示名称",
|
|
|
|
|
|
"awsAccessKeyId": "AWS 访问密钥 ID",
|
|
|
|
|
|
"awsSecretAccessKey": "AWS Secret Access Key",
|
|
|
|
|
|
"awsRegion": "AWS 区域",
|
|
|
|
|
|
"selectRegion": "选择区域",
|
|
|
|
|
|
"apiKey": "API 密钥",
|
|
|
|
|
|
"enterApiKey": "输入您的 API 密钥",
|
|
|
|
|
|
"enterSecretKey": "输入您的 Secret Key",
|
|
|
|
|
|
"baseUrl": "基础 URL",
|
|
|
|
|
|
"optional": "(可选)",
|
2026-01-20 13:39:33 +00:00
|
|
|
|
"baseUrlWithExample": "基础 URL(可选,例如 {example})",
|
2025-12-23 11:42:27 +09:00
|
|
|
|
"customEndpoint": "自定义端点 URL",
|
feat: Add support for Chinese AI providers (GLM, Qwen, Kimi, MiniMax, Qiniu)
* 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>
2026-03-07 17:53:47 +08:00
|
|
|
|
"minimaxBaseUrlHint": "使用 /anthropic 端点为 Anthropic 兼容 API(推荐),或使用 /v1 端点为 OpenAI 兼容 API",
|
2026-07-12 08:10:12 +08:00
|
|
|
|
"mimoBaseUrlHint": "默认地址适用于按量付费密钥(sk-...)。Token Plan 订阅用户(tp-... 密钥)请设置为 https://token-plan-cn.xiaomimimo.com/v1",
|
2025-12-23 11:42:27 +09:00
|
|
|
|
"models": "模型",
|
|
|
|
|
|
"customModelId": "自定义模型 ID...",
|
|
|
|
|
|
"allAdded": "已全部添加",
|
|
|
|
|
|
"suggested": "推荐",
|
|
|
|
|
|
"noModelsConfigured": "尚未配置模型",
|
|
|
|
|
|
"modelIdEmpty": "模型 ID 不能为空",
|
|
|
|
|
|
"modelIdExists": "此模型 ID 已存在",
|
|
|
|
|
|
"configureProviders": "配置 AI 提供商",
|
|
|
|
|
|
"selectProviderHint": "从列表中选择提供商或添加新的以配置 API 密钥和模型",
|
|
|
|
|
|
"deleteConfirmDesc": "确定要删除 {name} 吗?这将移除所有配置的模型且无法撤销。",
|
|
|
|
|
|
"typeToConfirm": "输入 \"{name}\" 以确认",
|
|
|
|
|
|
"typeProviderName": "输入提供商名称...",
|
|
|
|
|
|
"modelsConfiguredCount": "已配置 {count} 个模型",
|
|
|
|
|
|
"validationFailedCount": "{count} 个模型验证失败",
|
|
|
|
|
|
"cancel": "取消",
|
|
|
|
|
|
"delete": "删除",
|
|
|
|
|
|
"clickToChange": "(点击更改)",
|
|
|
|
|
|
"usingServerDefault": "使用服务器默认模型",
|
|
|
|
|
|
"selectModel": "选择模型",
|
|
|
|
|
|
"searchModels": "搜索模型...",
|
|
|
|
|
|
"noVerifiedModels": "没有已验证的模型。请先测试您的模型。",
|
|
|
|
|
|
"noModelsFound": "未找到模型。",
|
|
|
|
|
|
"default": "默认",
|
|
|
|
|
|
"serverDefault": "服务器默认",
|
2026-01-15 21:28:22 +05:30
|
|
|
|
"serverModels": "服务器模型",
|
|
|
|
|
|
"userModels": "用户模型",
|
2025-12-23 11:42:27 +09:00
|
|
|
|
"configureModels": "配置模型...",
|
2025-12-26 11:19:59 +08:00
|
|
|
|
"onlyVerifiedShown": "仅显示已验证的模型",
|
|
|
|
|
|
"showUnvalidatedModels": "显示未验证的模型",
|
|
|
|
|
|
"allModelsShown": "显示所有模型(包括未验证的)",
|
2026-01-15 21:28:22 +05:30
|
|
|
|
"unvalidatedModelWarning": "此模型尚未验证",
|
feat: add file-based admin settings panel at /admin (#866)
* feat: add file-based admin settings panel at /admin
Settings saved in the panel are written to data/settings.json and
overlaid onto process.env, taking precedence over environment
variables and applying immediately without restart. Enable by setting
ADMIN_PASSWORD; on serverless platforms without persistent disk the
panel degrades to read-only.
* polish: admin panel UI improvements
- Provider logos in credential rows (shared ProviderLogo component,
extracted from model-config-dialog)
- Scroll-spy active state in the sidebar nav
- Green success state in the save bar that clears after a few seconds
- Wider content column (max-w-6xl) for less wasted space on desktop
* polish: admin panel section toggles and reorder
- Move Quota & Rate Limits to the end of the settings page
- Add enable switches to Observability and Quota sections; default off
with fields grayed out, auto-on when any field is already configured
* polish: make section enable switch more visible
Wrap the switch in a labeled pill ('Enabled'/'Disabled') with border
and background so the off state is clearly visible.
* refactor: derive admin registry from PROVIDER_INFO, simplify page state
- Provider options, labels, and base-URL placeholders now come from
PROVIDER_INFO instead of hand-copied lists (fixes SiliconFlow .com/.cn
placeholder drift; panel names now match the model-config dialog)
- Replace free-text subgroup strings + SUBGROUP_PROVIDERS reverse map
with a typed provider field on SettingDef
- Precompute SETTINGS_BY_GROUP and PROVIDER_SUBGROUPS at module level
- Merge justSaved into saveMessage, drop unused mainRef, hoist
fetchSettings out of the component, dedupe savedText logic
- Serialize from SETTINGS_REGISTRY directly; json validators in a map
instead of a hardcoded key check
- Make allowPrivateUrls a function so ALLOW_PRIVATE_URLS edits in the
admin panel apply without restart
* feat: graphical model management in admin panel
Replace the provider credential fields and raw AI_MODELS_CONFIG JSON
textarea with a Models section mirroring the in-app model settings UI:
provider instance list with logos, credential fields per provider type,
model add/remove with suggestions, per-model connectivity test, and a
default-provider star.
On save the server derives everything the runtime needs into
settings.json: credential env vars (with _2 suffixes for multiple
instances of one provider), AI_MODELS_CONFIG, and AI_PROVIDER/AI_MODEL
for the default. Secrets round-trip as masked markers and are never
sent back to the browser. The general settings registry now only
covers non-provider settings (generation, access, features,
observability, quota).
* fix: allow testing unsaved providers in admin panel
The test button previously looked up credentials by providerId in the
saved settings, so testing a newly added (unsaved) provider failed with
'Unknown provider or model'. The test endpoint now accepts the client's
current provider state; newly typed secrets are used as-is and masked
markers are resolved against the stored values, so testing works both
before and after saving.
* fix: merge env AI_MODELS_CONFIG with admin panel providers
Previously, saving in the admin panel wrote a complete AI_MODELS_CONFIG
into settings.json, which (by overlay precedence) replaced any config
from .env or ai-models.json — admins lost their env-configured models.
The panel no longer writes AI_MODELS_CONFIG. Instead its providers are
merged with the env baseline at read time in loadRawServerModelsConfig,
and panel credentials go to ADMIN_-prefixed env vars wired up via
apiKeyEnv/baseUrlEnv so they never shadow standard vars. Env-based
providers now appear read-only in the panel, name clashes are rejected,
and a panel default overrides the env default. data/ is now gitignored.
* fix: block global-credential providers already managed via env
Bedrock, Vertex AI, and Ollama credentials live in fixed env vars with
no apiKeyEnv redirection, so a panel instance of one of these would
silently override the credentials that env-configured models rely on.
The API now rejects saving such a provider when the env config already
uses that type, and the Add Provider dropdown disables it with a
'managed via env' note.
* fix: address admin panel review findings
- Security: test-model no longer resolves a stored secret when the
request's baseUrl/provider differs from the stored entry, closing a
path where a tampered baseUrl could exfiltrate a saved key
- Save failures are now visible: the save bar shows the error in red
(was masked by the persistent 'Unsaved changes' text), and per-field
validation errors from the settings API are surfaced under each field
- The Observability/Quota enable switch is now real: toggling off stages
deletion of the group's saved values, and the toggle no longer snaps
back to Enabled after saving
- Env provider's default star is hidden when a panel provider is the
active default (no more double star)
- Clearing a credential field reverts to the stored value instead of
silently deleting it; an explicit X button removes a stored secret
- Form inputs are disabled during an in-flight save
* refactor(admin): split 1549-line admin page into focused modules
Extract admin-shared.ts (types + fetch helper), setting-field.tsx
(registry-driven fields), and models-section.tsx (provider/model
manager) from page.tsx. Pure mechanical move, no behavior change.
* feat(admin): share credential fields with user dialog and localize panel
Extract ProviderCredentialsFields (display name + per-provider
credential inputs) used by both the user ModelConfigDialog and the
admin Models panel; secret input passed via renderSecret (plaintext
vs masked), test button via footer slot. Add full i18n for the admin
panel across en/zh/ja/zh-Hant, reusing modelConfig.* for shared parts.
* fix(admin): address Copilot review findings
- Reflect built-in defaults for boolean settings (ALLOW_PRIVATE_URLS
defaults on) and allow clearing a saved boolean back to default,
so the SSRF toggle matches actual runtime behavior.
- Harden JSON loading: filter settings values to strings only, and
schema-validate stored ADMIN_PROVIDERS entries, dropping malformed
ones instead of letting them reach runtime code.
- Set beforeunload returnValue so the unsaved-changes prompt shows in
all browsers; reject non-finite numbers in settings validation.
- Fix README/CN/JA docs that claimed the panel auto-generates
AI_MODELS_CONFIG (providers are merged at read time, not written).
- Add unit tests for corrupted-file value filtering and provider
schema validation.
* docs: move admin panel details to dedicated docs/{en,cn,ja}/admin-panel.md
The READMEs now carry a short blurb + link, matching the existing
per-topic docs (docker.md, ai-providers.md, ...). Removes the ~22-line
inline section and the duplicated data/settings.json mentions.
* fix(admin): address follow-up Copilot findings on the prior fixes
- loadAdminProviders now validates against a stored-shape schema where
secrets are plain strings, so a hand-edited ADMIN_PROVIDERS holding an
{isSet} marker is dropped instead of later crashing maskSecret().
- loadSettings guards against array values (typeof [] === 'object'),
which would otherwise overlay numeric keys onto process.env.
- Admin SecretInput uses the bare id so the shared component's
<Label htmlFor> stays associated (only one ProviderDetail mounts).
- Add tests: marker-secret rejection, array-values guard, bedrock
multi-secret round-trip.
2026-06-15 00:40:35 +09:00
|
|
|
|
"serverDefaultModel": "服务器默认模型",
|
|
|
|
|
|
"showValue": "显示值",
|
|
|
|
|
|
"hideValue": "隐藏值"
|
|
|
|
|
|
},
|
|
|
|
|
|
"admin": {
|
|
|
|
|
|
"title": "管理员设置",
|
|
|
|
|
|
"loginPrompt": "输入管理员密码(即 ADMIN_PASSWORD 环境变量)以管理服务器设置。",
|
|
|
|
|
|
"password": "密码",
|
|
|
|
|
|
"signIn": "登录",
|
|
|
|
|
|
"signingIn": "正在登录…",
|
|
|
|
|
|
"loginFailed": "登录失败",
|
|
|
|
|
|
"precedence": "文件覆盖环境变量 · 环境变量覆盖默认值",
|
|
|
|
|
|
"notWritable": "此部署环境下设置文件不可写(无服务器平台没有持久化磁盘)。设置以只读方式显示——请改用环境变量进行配置。",
|
|
|
|
|
|
"settingGroups": "设置分组",
|
|
|
|
|
|
"enabled": "已启用",
|
|
|
|
|
|
"disabled": "已禁用",
|
|
|
|
|
|
"enableGroup": "启用 {group}",
|
|
|
|
|
|
"unsavedChanges": "有未保存的更改",
|
|
|
|
|
|
"saved": "设置已保存,更改立即生效。",
|
|
|
|
|
|
"saveFailed": "保存失败。请检查网络连接后重试。",
|
|
|
|
|
|
"invalidSettings": "部分设置无效。",
|
|
|
|
|
|
"discard": "放弃",
|
|
|
|
|
|
"saveChanges": "保存更改",
|
|
|
|
|
|
"saving": "正在保存…",
|
|
|
|
|
|
"sourceSaved": "已保存",
|
|
|
|
|
|
"sourceEnv": "环境变量",
|
|
|
|
|
|
"sourceSavedTitle": "在管理员设置文件中设置",
|
|
|
|
|
|
"sourceEnvTitle": "通过环境变量设置",
|
|
|
|
|
|
"restartRequired": "需要重启",
|
|
|
|
|
|
"modified": "已修改",
|
|
|
|
|
|
"notSet": "未设置",
|
|
|
|
|
|
"savedReplace": "已保存({hint})——输入以替换",
|
|
|
|
|
|
"showValue": "显示值",
|
|
|
|
|
|
"hideValue": "隐藏值",
|
|
|
|
|
|
"removeValue": "移除值",
|
|
|
|
|
|
"removeValueTitle": "移除已保存的值",
|
|
|
|
|
|
"resetToDefault": "恢复默认",
|
|
|
|
|
|
"models": "模型",
|
|
|
|
|
|
"modelsDescription": "面向所有用户的服务端 provider 和模型——无需个人 API 密钥。当用户未选择模型时,使用默认 provider 的第一个模型。",
|
|
|
|
|
|
"addProviderHint": "添加一个 provider,为所有用户提供服务端模型。",
|
|
|
|
|
|
"selectProviderHint": "选择或添加一个 provider 以配置其凭证和模型。",
|
|
|
|
|
|
"addProviderToOfferModels": "至少添加一个模型,才能向用户开放此 provider。",
|
|
|
|
|
|
"managedViaEnv": "(通过环境变量管理)",
|
|
|
|
|
|
"envReadOnly": "在 AI_MODELS_CONFIG / ai-models.json 中定义——此处只读。请编辑环境配置以更改。",
|
|
|
|
|
|
"defaultModel": "默认模型",
|
|
|
|
|
|
"noModelsConfigured": "未配置模型",
|
|
|
|
|
|
"modelCount": "{count} 个模型",
|
|
|
|
|
|
"modelCountPlural": "{count} 个模型",
|
|
|
|
|
|
"default": "默认",
|
|
|
|
|
|
"setAsDefault": "设为默认 provider",
|
|
|
|
|
|
"defaultProvider": "默认 provider",
|
|
|
|
|
|
"modelIdPlaceholder": "模型 ID…",
|
|
|
|
|
|
"addModel": "添加模型",
|
|
|
|
|
|
"suggested": "推荐",
|
|
|
|
|
|
"test": "测试",
|
|
|
|
|
|
"testOk": "正常({ms} 毫秒)",
|
|
|
|
|
|
"testFailed": "失败",
|
|
|
|
|
|
"removeModel": "移除 {model}",
|
|
|
|
|
|
"deleteProviderTitle": "删除 {name}?",
|
|
|
|
|
|
"deleteProviderDesc": "保存后,其凭证和模型将从服务器上移除。",
|
|
|
|
|
|
"cancel": "取消",
|
|
|
|
|
|
"delete": "删除",
|
|
|
|
|
|
"groups": {
|
|
|
|
|
|
"generation": {
|
|
|
|
|
|
"title": "生成",
|
|
|
|
|
|
"description": "应用于所有聊天请求的输出参数。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"access": {
|
|
|
|
|
|
"title": "访问控制",
|
|
|
|
|
|
"description": "限制谁可以使用此部署。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"features": {
|
|
|
|
|
|
"title": "功能",
|
|
|
|
|
|
"description": "可选功能和安全开关。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"observability": {
|
|
|
|
|
|
"title": "可观测性",
|
|
|
|
|
|
"description": "对 LLM 调用进行 Langfuse 追踪。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"quota": {
|
|
|
|
|
|
"title": "配额与速率限制",
|
|
|
|
|
|
"description": "按 IP 的用量限制。强制执行需要 DynamoDB 表。"
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
"settings": {
|
|
|
|
|
|
"TEMPERATURE": {
|
|
|
|
|
|
"label": "温度",
|
|
|
|
|
|
"description": "对于拒绝温度参数的推理模型,请留空。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"MAX_OUTPUT_TOKENS": {
|
|
|
|
|
|
"label": "最大输出 token 数"
|
|
|
|
|
|
},
|
|
|
|
|
|
"ACCESS_CODE_LIST": {
|
|
|
|
|
|
"label": "访问码",
|
|
|
|
|
|
"description": "以逗号分隔的列表。用户需输入其中之一才能聊天。留空 = 开放访问。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"ENABLE_VLM_VALIDATION": {
|
|
|
|
|
|
"label": "VLM 图表验证",
|
|
|
|
|
|
"description": "使用视觉模型对生成的图表进行可视化验证。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"VALIDATION_MODEL": {
|
|
|
|
|
|
"label": "验证模型",
|
|
|
|
|
|
"description": "留空时回退到默认 AI 模型。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"VALIDATION_TIMEOUT": {
|
|
|
|
|
|
"label": "验证超时(毫秒)"
|
|
|
|
|
|
},
|
|
|
|
|
|
"ENABLE_HISTORY_XML_REPLACE": {
|
|
|
|
|
|
"label": "历史 XML 压缩",
|
|
|
|
|
|
"description": "用占位符替换历史记录中的旧图表 XML。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"ALLOW_PRIVATE_URLS": {
|
|
|
|
|
|
"label": "允许私有 URL",
|
|
|
|
|
|
"description": "关闭以阻止对私有 IP 和内部主机名的请求(SSRF 防护)。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"LANGFUSE_PUBLIC_KEY": {
|
|
|
|
|
|
"label": "Langfuse Public Key"
|
|
|
|
|
|
},
|
|
|
|
|
|
"LANGFUSE_SECRET_KEY": {
|
|
|
|
|
|
"label": "Langfuse Secret Key"
|
|
|
|
|
|
},
|
|
|
|
|
|
"LANGFUSE_BASEURL": {
|
|
|
|
|
|
"label": "Langfuse Base URL"
|
|
|
|
|
|
},
|
|
|
|
|
|
"DAILY_REQUEST_LIMIT": {
|
|
|
|
|
|
"label": "每日请求上限",
|
|
|
|
|
|
"description": "每个 IP 每天。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"DAILY_TOKEN_LIMIT": {
|
|
|
|
|
|
"label": "每日 token 上限",
|
|
|
|
|
|
"description": "每个 IP 每天。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"TPM_LIMIT": {
|
|
|
|
|
|
"label": "每分钟 token 数"
|
|
|
|
|
|
},
|
|
|
|
|
|
"DYNAMODB_QUOTA_TABLE": {
|
|
|
|
|
|
"label": "DynamoDB 表",
|
|
|
|
|
|
"description": "留空时配额强制执行被禁用。"
|
|
|
|
|
|
},
|
|
|
|
|
|
"DYNAMODB_REGION": {
|
|
|
|
|
|
"label": "DynamoDB 区域"
|
|
|
|
|
|
},
|
|
|
|
|
|
"QUOTA_TIMEZONE": {
|
|
|
|
|
|
"label": "配额时区",
|
|
|
|
|
|
"description": "每日重置边界所用的时区。"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-12-20 20:18:54 +05:30
|
|
|
|
}
|
|
|
|
|
|
}
|