* 🐛 fix(desktop): remove electron-liquid-glass to fix click event blocking
The electron-liquid-glass native addon was blocking all click events in the
Electron desktop app window. Remove the dependency and restore vibrancy-based
transparency with semi-transparent body background via `.desktop` CSS class.
* 🔨 chore(desktop): remove electron-liquid-glass from native modules config
* ♻️ refactor: replace per-message useNewScreen with centralized useConversationSpacer
Replace the old per-message min-height approach with a single spacer element appended to the virtual list, simplifying scroll-to-top UX when user sends a new message.
* 🔧 refactor: streamline handleSendButton logic and enhance editor focus behavior
Removed redundant editor null check and added double requestAnimationFrame calls to ensure the editor is focused after sending a message.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: clear input immediately on send to preserve drafts typed during streaming
Move inputMessage reset before the async streaming lifecycle so text
entered while the assistant is responding is not overwritten on completion.
Also normalize null/undefined in operation context matching so that
cancelOperations works correctly in null-topic sessions.
Fixes LOBE-2647
* 🐛 fix: resolve TS2322 null-vs-undefined type error in useOperationState test
* ✨ feat(desktop): Linux window specialization
- Add minimize/maximize/close buttons for Linux (WinControl)
- Linux: no tray, close main window quits app
- Linux: native window shadow and opaque background
- i18n for window control tooltips
Made-with: Cursor
* 🌐 i18n: add window control translations for all locales
Made-with: Cursor
* 🐛 fix(desktop): show WinControl in SimpleTitleBar only on Linux
Made-with: Cursor
* 🐛 fix(desktop): limit custom titlebar controls to Linux
Avoid rendering duplicate window controls on Windows and keep the Linux maximize button in sync with the current window state.
Made-with: Cursor
---------
Co-authored-by: LiJian <onlyyoulove3@gmail.com>
* style: update claude 4.6 series 1M contextWindow
* chore: cleanup bedrock search tag
chore: cleanup bedrock retired model
chore: cleanup bedrock retired model
chore: cleanup bedrock retired model
* fix: fix ci test
* 💄 style: remove platform-specific Spotlight reference from searchLocalFiles
Replace "using Spotlight (macOS) or native search" with "using native search"
since the actual search implementation is platform-dependent and the LLM
doesn't need to know the specific backend.
Fixes LOBE-5778
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ⚡️ perf: remove duplicate API descriptions from tool system prompt
API identifiers and descriptions are already in the tools schema passed
via the API tools parameter. Repeating them in the system prompt wastes
tokens. Now only tools with systemRole (usage instructions) are injected.
Also rename XML tags: plugins→tools, collection→tool,
collection.instructions→tool.instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 💄 style: inject tool description when no systemRole instead of skipping
Tools without systemRole now show their description as <tool> children.
Tools with systemRole use <tool.instructions> wrapper as before.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 💄 style: always emit <tool> tag, fallback to "no description"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update tools
* fix
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ✨ feat: inject all installed skills into <available_skills> for AI discovery
Previously, only skills explicitly added to the agent's plugins list appeared
in <available_skills>. Now all installed skills are exposed so the AI can
discover and activate them via activateSkill.
Changes:
- Frontend: use getAllSkills() instead of getEnabledSkills(plugins)
- Backend: pass skillMetas through createOperation → RuntimeExecutors → serverMessagesEngine
- Add skillsConfig support to serverMessagesEngine
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: use DB + builtin skills for available_skills instead of provider manifests
lobehubSkillManifests are tool provider manifests (per-provider, containing
tool APIs), not skill metadata. Using them for <available_skills> incorrectly
showed provider names (e.g. "Arvin Xu") as skills.
Now fetches actual skills from AgentSkillModel (DB) + builtinSkills for correct
<available_skills> injection.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 💄 style: use XML structure for online-devices in system prompt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ♻️ refactor: extract online-devices prompt to @lobechat/prompts package
Move device XML prompt generation from builtin-tool-remote-device into
the shared prompts package for reusability and consistency.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ✅ test: add failing tests for Remote Device suppression when auto-activated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ⚡️ perf: suppress Remote Device tool when device is auto-activated
When a device is auto-activated (single device in IM/Bot or bound device),
the Remote Device management tool (listOnlineDevices, activateDevice) is
unnecessary — saves ~500 tokens of system prompt + 2 tool functions.
- Add autoActivated flag to deviceContext
- Move activeDeviceId computation before tool engine creation
- Disable Remote Device in enableChecker when autoActivated
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* update system role
* update system role
* ♻️ refactor: use agentId instead of slug for OpenAPI responses model field
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: use JSON round-trip instead of structuredClone in InMemoryAgentStateManager
structuredClone fails with DataCloneError when state contains non-cloneable
objects like DOM ErrorEvent (from Neon DB WebSocket errors).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: only inject available_skills when tools are enabled
Restore plugins guard to prevent skills injection when tool use is
disabled (plugins is undefined), fixing 28 test failures.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ✅ test: update system message assertions for skills injection
Use stringContaining instead of exact match for system message content,
since available_skills may now be appended after the date.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
🐛 fix: use jsonb ? operator instead of ->> to avoid Neon rt_fetch bug
The ->> operator in WHERE clauses triggers a Neon-specific
`rt_fetch used out-of-bounds` error. Switch to the ? operator
which is semantically equivalent for checking key existence.
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* ♻️ refactor: centralize NavBar dev mode logic into useNavLayout hook
Extract scattered isDevMode checks from Nav, BottomMenu, Footer, and
UserPanel into a single useNavLayout hook with declarative devOnly
metadata. Also restore dev-mode-gated home page modules and fix
LangButton visual alignment in UserPanel.
* ✅ test: update PanelContent test to match LangButton Menu removal
When a builtin tool executor is not found, invokeBuiltinTool now returns
a structured error object instead of silently returning undefined. Also
adds a fallback in call_tool executor for undefined results to prevent
agent loop from terminating abnormally.
Fixes LOBE-5318
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix(desktop): update bundled agent-browser to v0.20.1 and align native-mode docs
Upgrade desktop bundled agent-browser to 0.20.1 and remove obsolete AGENT_BROWSER_NATIVE runtime override since native mode is now default. Update builtin agent-browser skill descriptions to reflect the new default behavior.
Made-with: Cursor
* ✨ feat: enable agent-browser skill on Windows desktop
Made-with: Cursor
* 🔧 refactor: remove isWindows from ToolAvailabilityContext interface
Updated the ToolAvailabilityContext interface to remove the isWindows property, simplifying the context checks in the isBuiltinSkillAvailableInCurrentEnv function.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* update skills
* 🐛 fix: respect agent-level memory config priority over user settings
Agent chatConfig.memory.enabled now takes priority. Falls back to user-level
memory setting when agent config is absent.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🐛 fix: resolve tsgo type error in memory integration test
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* 🌐 i18n: add auto top-up payment method hint translations
* ♻️ refactor: split Stats into separate settings tab and rename Subscription group to Plans
* 🌐 i18n: update auto top-up payment method hint copy
* 🌐 i18n: add auto top-up payment method hint translations for all locales
* 🌐 i18n: rename Subscription Plans tab to Plans
* 🌐 i18n: add high usage FAQ, rename Text Generation to Chat Message, rename tab.plans
* ✨ feat: add subscribeStreamEvents to InMemoryStreamEventManager and use factory for stream route
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: remove duplicate agentExecution types and fix stream route test mock
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: prevent Enter key submission during IME composition in LoginStep
* ♻️ refactor: extract useIMECompositionEvent hook for IME composition tracking
Made-with: Cursor
---------
Co-authored-by: Innei <tukon479@gmail.com>
* ✨ feat: add slash action tags in chat input
Made-with: Cursor
* ✨ feat: enhance editor with new slash actions and localization updates
- Added new slash actions: change tone, condense, expand, polish, rewrite, summarize, and translate.
- Updated localization files for English and Chinese to include new action tags and slash commands.
- Removed deprecated useSlashItems component and integrated its functionality directly into InputEditor.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: add slash placement configuration to chat input components
- Introduced `slashPlacement` prop to `ChatInputProvider`, `StoreUpdater`, and `InputEditor` for customizable slash menu positioning.
- Updated initial state to include `slashPlacement` with default value 'top'.
- Adjusted `ChatInput` and `InputArea` components to utilize the new `slashPlacement` prop.
This enhancement allows for better control over the user interface in chat input interactions.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: implement command bus for slash action tags processing
Add command bus system to parse and execute slash commands (compact context,
new topic). Refactor action tag categories from ai/prompt to command/skill.
Add useEnabledSkills hook for dynamic skill registration.
* feat: compress command
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: compress
Signed-off-by: Innei <tukon479@gmail.com>
* fix: skill inject
* ✨ feat: slash action tags with context engine integration
Made-with: Cursor
* ✨ feat: add topic reference builtin tool and server runtime
Made-with: Cursor
* ✨ feat: add topic mention items and update ReferTopic integration
Made-with: Cursor
* 🐛 fix: preserve editorData through assistant-group edit flow and update RichTextMessage reactively
- EditState now forwards editorData from EditorModal to modifyMessageContent
- modifyMessageContent accepts and passes editorData to updateMessageContent
- RichTextMessage uses useEditor + effect to update document on content change instead of key-based remount
- Refactored RichTextMessage plugins to use shared createChatInputRichPlugins()
* ✨ feat(context-engine): add metadata types and update processors/providers
Made-with: Cursor
* ✨ feat(chat-input): add slash action tags and restore failed input state
* 🔧 chore: update package dependencies and enhance Vite configuration
- Changed @lobehub/ui dependency to a specific package URL.
- Added multiple SPA entry points and layout files to the Vite warmup configuration.
- Removed unused monorepo packages from sharedOptimizeDeps and added various dayjs locales for better localization support.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @lobehub/ui dependency to version 5.4.0 in package.json
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: correct SkillsApiName.runSkill to activateSkill and update trimmed content assertions
* 🐛 fix: resolve type errors in context-engine tests and InputEditor slashPlacement
* 🐛 fix: update runSkill to activateSkill in conversationLifecycle test
* 🐛 fix: avoid regex backtracking in placeholder parser
* ✨ feat(localization): add action tags and tooltips for slash commands across multiple languages
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: preserve file attachments when /newTopic has no text content
* cleanup
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* fix command issue
* add run command UI
* fix API key
* add apikey page
* add apikey
* 🐛 fix: update apiKey model tests to use new sk-lh- prefix format
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Add `--file` option to `lh topic delete` command, allowing users to
pass topic IDs via a file (one per line or JSON array) for bulk deletion.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: add the activatedSkills to improve the execScripte tools
* feat: change the activePath into call market endpoint
* fix: clean the code
* feat: fixed the execScript in desktop ts error
✨ feat: preload bundled i18n resources synchronously and reload actual language in background
For non-default languages, preload bundled en-US resources synchronously to avoid
Suspense on first render, then reload the user's actual language from backend
in the background. This ensures instant rendering with fallback text while the
correct translations load asynchronously.
* 🐛 fix: ensure always-on builtin tools and user-selected plugins are enabled in tool engine
- Add alwaysOnToolIds (lobe-tools, lobe-skills) that are always enabled regardless of user selection
- Include user-selected plugins in enableChecker rules for both frontend and server-side tool engines
- Change enableCheckerFactory default from enabled to disabled (tools must be explicitly enabled via rules)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: improve input loading state to cover sendMessage through AI generation
- Add isInputLoading state that includes sendMessage operation type, so input stays
in loading state from the moment user sends until AI finishes generating
- Add INPUT_LOADING_OPERATION_TYPES constant (superset of AI_RUNTIME_OPERATION_TYPES + sendMessage)
- Update ChatInput to use isInputLoading instead of isAIGenerating for disable/loading state
- Update stopGenerating to cancel all input-loading operations and restore editor on cancel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✅ test: fix stopGenerating tests to match updated action implementation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix agent
* 🐛 fix: add missing selector mocks in toolEngineering tests
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* style: update moonshot models
* 🔨 chore: extend `video_url` support for OpenAI SDK
* fix: fix ci error
* hotfix: fix sensenova baseUrl error
* fix: fix kimi-k2.5 video tag from LobeHub
* fix: wenxin flag
* chore: cleanup utils
* style: add video tag for `glm-4.1/4.5v`
remove video tag for sensenova due to not support in OpenAI mode
* add response api framework
* finish response api structure
* finish response api structure
* ✨ feat: implement basic text generation for Response API (LOBE-5858)
- Add instructions extraction from system/developer input messages
- Add instructions param to ExecAgentParams, append to agent systemRole
- Implement extractPrompt, extractAssistantContent, extractUsage in ResponsesService
- Wire up execAgent + executeSync flow for non-streaming and streaming
- Add logprobs field to output_text content parts for schema compliance
- Fix truncation field to output string enum instead of object
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat: implement real token-level streaming for Response API (LOBE-5859)
- Replace fake streaming (executeSync → emit events) with real streaming
- Subscribe to InMemoryStreamEventManager for live stream_chunk events
- Run executeSync in background, convert text chunks to output_text.delta SSE events
- Add missing schema fields: item_id on content_part/text events, logprobs on delta/done events
- Fix content_part.added/done to include item_id per OpenResponses spec
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat: implement tool calling output extraction for Response API (LOBE-5860)
- Add extractOutputItems to convert AgentState messages to OpenResponses output items
- Extract assistant tool_calls → function_call output items
- Extract tool result messages → function_call_output output items
- Skip message items for assistant messages that have tool_calls (avoid duplicates)
- Add status field to function_call_output items per OpenResponses spec
- Update FunctionCallOutputItemSchema with optional status field
- Output array reflects execution order: function_call → function_call_output → message
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat: implement multi-turn conversations via previous_response_id (LOBE-5861)
Encode topicId in response.id to enable stateless multi-turn conversation
chaining. When previous_response_id is provided, extract topicId and pass
to execAgent via appContext, which automatically loads history messages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: add missing type fields for OpenResponses compliance (logprobs, item_id, input_tokens_details)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): CLI Phase 5 - agent KB/file/pin, thread management, eval expansion
- Add agent subcommands: pin/unpin, kb-files, add-file/remove-file/toggle-file, add-kb/remove-kb/toggle-kb
- Create thread command with list/list-all/delete subcommands
- Expand eval with internal benchmark/dataset/testcase/irun management
- Move existing external eval commands under `eval ext` namespace
- Add comprehensive unit tests for all new functionality
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 💄 style(cli): rename eval `irun` to `run` since external moved to `ext` namespace
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ♻️ refactor(cli): merge external eval commands into unified tree with --external flag
Remove separate `eval ext` namespace; use `--external` flag on overlapping commands
(dataset get, run get) and integrate external-only commands directly into the tree.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): CLI Phase 6 - miscellaneous command enhancements
- file: add upload (hash check + create), edit (move to folder), kb-items
- user: new command with info, settings, preferences, update-avatar, update-name
- model: add batch-update, sort order
- plugin: add create (without settings, distinct from install)
- generation: add delete
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(settings): improve tool detector display layout
- Move version to left side with Name, display as Tag
- Right side: two lines (Available status + path), right-aligned
- Unavailable: single line centered
- Add runtime environment detectors (Node, Python, npm)
- Add i18n for system tools settings
Made-with: Cursor
* 🔧 fix(toolDetectors): ensure successful version check for Python runtime
- Update pythonDetector to enforce successful invocation of `--version` for confirming usable runtime.
- Removed redundant version handling logic to streamline the detection process.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* fix: add the history count limit back in agents params settings
* fix: fixed the test
* fix: change the default settings snap the enableHistoryCount as false
* fix: change the history process to the first into MessageEngine
* fix: fixed some count limited
* fix: fixed the enableHistoryCount check test
* fix: change the getEnableHistoryCountById logic
* fix cli alias
* 🐛 fix(cli): fix gen text non-streaming mode and streaming SSE parsing
- Add `responseMode: 'json'` for non-streaming requests to get plain JSON instead of SSE
- Fix streaming SSE parser to handle LobeHub's JSON string format (e.g. `"Hello"`)
- Support both OpenAI and Anthropic response formats in non-streaming mode
- Add E2E tests for all generate commands (text, list, tts, asr, alias)
- Update skills knowledge.md docs with new kb commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): unify skill install command and add e2e tests
Merge import-github/import-url/import-market into a single `skill install <source>` command with auto-detection (GitHub URL/shorthand, ZIP URL, or marketplace identifier). Add alias `skill i`. Add comprehensive e2e and unit tests for skill commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🔨 chore: fix linter formatting in memory e2e test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: add vitest-environment node declaration to aiProvider test
Fix server-side env variable access error by declaring node environment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix cli review
* fix test
* ✨ feat(cli): add web search and crawl support to search command
Add --web flag for web search via tools TRPC client, and search view
subcommand for viewing results (URLs via crawl, local resources by type:id).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): add device management command with TRPC endpoints
Add `lh device` command for managing connected devices via server-side
TRPC API, complementing the existing `lh connect` (device-as-client).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): add bot integration management command
Add `lh bot` top-level command for managing agent bot integrations
(Discord, Slack, Telegram, Lark/Feishu). Includes list, view, add,
update, remove, enable/disable, and connect subcommands.
Also adds `list` procedure to agentBotProvider TRPC router for
querying all bots with optional agent/platform filters.
Closes LOBE-5900
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix(i18n): preload default language from JSON to avoid Suspense on first render
- Sync load en-US common/error/chat from locales/en-US/*.json
- Use JSON (not locales/default/*.ts) as runtime values - TS source is type-only
- Prevents useTranslation from suspending, avoids CLS from 44px skeleton fallback
Made-with: Cursor
* ✨ feat(i18n): enable partial loading of languages and add tests for dynamic namespace loading
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* fix cli alias
* 🐛 fix(cli): fix gen text non-streaming mode and streaming SSE parsing
- Add `responseMode: 'json'` for non-streaming requests to get plain JSON instead of SSE
- Fix streaming SSE parser to handle LobeHub's JSON string format (e.g. `"Hello"`)
- Support both OpenAI and Anthropic response formats in non-streaming mode
- Add E2E tests for all generate commands (text, list, tts, asr, alias)
- Update skills knowledge.md docs with new kb commands
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat(cli): unify skill install command and add e2e tests
Merge import-github/import-url/import-market into a single `skill install <source>` command with auto-detection (GitHub URL/shorthand, ZIP URL, or marketplace identifier). Add alias `skill i`. Add comprehensive e2e and unit tests for skill commands.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🔨 chore: fix linter formatting in memory e2e test
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: add vitest-environment node declaration to aiProvider test
Fix server-side env variable access error by declaring node environment.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix cli review
* fix test
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: desktop onboarding
* ♻️ refactor(desktop): reinstate onboarding guard before auto OIDC
- Add getDesktopOnboardingCompleted/setDesktopOnboardingCompleted back to localStorage
- These functions persist across sign-out, preventing unexpected OIDC popups
- Fix for Codex review feedback on PR #12890
* ♻️ refactor(desktop): use sessionStorage for onboarding completed flag
* ✅ test(desktop): fix BrowserManager test for async initializeBrowsers
* ♻️ refactor(cli): extract shared @lobechat/local-file-shell package
Extract common file and shell operations from Desktop and CLI into a
shared package to eliminate ~1500 lines of duplicated code. CLI now
uses @lobechat/file-loaders for rich format support (PDF, DOCX, etc.).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* update
* update commands
* update version
* update deps
* refactor version issue
* ✨ feat(local-file-shell): add cwd support, move/rename ops, improve logging
- Add missing `cwd` parameter to `runCommand` (align with Desktop)
- Add `moveLocalFiles` with batch support and detailed error handling
- Add `renameLocalFile` with path validation and traversal prevention
- Add error logging in shell runner's error/completion handlers
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* support update model and provider in cli
* fix desktop build
* fix
* 🐛 fix: pin fast-xml-parser to 5.4.2 in bun overrides
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add the skills in community pages
* feat: add some skills & import the import routes
* feat: add detail used pages & prompt
* feat: add the skill sort way
* fix: ts fixed
* fix: ts fixed
* fix: test fixed
* fix: test fixed
- Use same app name (LobeHub) and icon as stable for canary builds
- Add build channel tag in Settings > About for non-stable channels (Canary, Nightly, Beta)
- Add getBuildChannel IPC to expose build-time channel for display
Made-with: Cursor
* ✨ feat(tool-detectors): add browser automation support and refactor tool detector categories
- Introduced browser automation detectors to the tool detector manager.
- Updated tool categories to include 'browser-automation'.
- Refactored imports to use type imports where applicable for better clarity.
- Cleaned up unnecessary comments in tool filters.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: add browser automation tool detection UI
* 🔧 chore: update react-scan version and enhance agent-browser documentation
- Updated `react-scan` dependency from version 0.4.3 to 0.5.3 in package.json.
- Improved documentation in `content.ts` for the agent-browser, clarifying command usage and workflows.
- Added development mode flag `__DEV__` in sharedRendererConfig for better environment handling.
- Integrated `scan` functionality in `initialize.ts` to enable scanning in development mode.
- Updated global type definitions to include `__DEV__` constant for clarity.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore(builtin-skills): add dependency and refactor skill filtering logic
- Added `@lobechat/const` as a dependency in package.json.
- Introduced a new function `shouldEnableBuiltinSkill` to determine if a skill should be enabled based on the environment.
- Refactored the `builtinSkills` export to filter skills using the new logic.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore(builtin-skills): refactor skill management and add filtering logic
- Removed unnecessary dependency from package.json.
- Simplified skill filtering logic by introducing `filterBuiltinSkills` and `shouldEnableBuiltinSkill` functions.
- Updated various components to utilize the new filtering logic for managing builtin skills based on the environment.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(builtin-skills): introduce new skill APIs and refactor manifest structure
- Added new APIs for skill management: `runSkillApi`, `readReferenceApi`, and `exportFileApi` to enhance functionality.
- Created a base manifest file (`manifest.base.ts`) to centralize API definitions.
- Updated the desktop manifest (`manifest.desktop.ts`) to utilize the new base APIs.
- Refactored existing manifest to streamline API integration and improve maintainability.
- Introduced a detailed system prompt for better user guidance on skill usage.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: desktop skill runtime, skill store inspectors, and tool UI updates
Made-with: Cursor
* ✨ feat: enhance skill import functionality and testing
- Updated `importFromUrl` method in `SkillImporter` to accept additional options for identifier and source.
- Modified `importFromMarket` in `agentSkillsRouter` to utilize the new options for better tracking of skill imports.
- Added integration tests to ensure stable behavior when re-importing skills from the market, verifying that identifiers remain consistent across imports.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update .gitignore and package.json dependencies
- Added 'bin' to .gitignore to exclude binary files from version control.
- Included 'fflate' as a new dependency in package.json to support file compression in the application.
- Updated writeFile method in LocalFileCtr to handle file content as Uint8Array for improved type safety.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update package.json dependencies
- Removed 'fflate' from dependencies and added it to devDependencies for better organization.
- Ensured proper formatting by adding a newline at the end of the file.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: add agent-browser download script and integrate binary handling
- Introduced a new script to download the `agent-browser` binary, ensuring it is available for the application.
- Updated `electron-builder.mjs` to include the binary in the build process.
- Modified `dir.ts` to define the binary directory path based on the packaging state.
- Enhanced the `App` class to set environment variables for the agent-browser integration.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: add DevTools toggle to Linux and Windows menus
- Introduced a new menu item for toggling DevTools with the F12 accelerator key in both Linux and Windows menu implementations.
- Added a separator for better organization of the view submenu items.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: integrate agent-browser binary download into build process
- Added functionality to download the `agent-browser` binary during the build process in `electron-builder.mjs`.
- Enhanced the download script with detailed logging for better visibility of the download status and errors.
- Updated the `App` class to log the binary directory path for improved debugging.
- Reintroduced the `AuthRequiredModal` in the layout for desktop users.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: mock binary directory path in tests
- Added a mock for the binary directory path in the App tests to facilitate testing of the agent-browser integration.
- This change enhances the test environment by providing a consistent path for the binary during test execution.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: improve authorization notification handling
- Updated the `notifyAuthorizationRequired` method to implement trailing-edge debounce, ensuring that rapid 401 responses are coalesced and the IPC event is sent after the burst settles.
- Refactored the notification logic to enhance clarity and maintainability.
✨ feat: add desktop onboarding redirect
- Introduced a `useEffect` hook in `StoreInitialization` to redirect users to the `/desktop-onboarding` page if onboarding is not completed, ensuring a smoother user experience on fresh installs.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix(desktop): hide Agent Browser skill on Windows
Made-with: Cursor
* 🔧 chore: update memory limits for build processes
- Increased the `NODE_OPTIONS` memory limit for both `build:next` and `build:spa` scripts from 6144 to 7168, optimizing build performance and resource management.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(openai): add GPT-5.3 Chat model with enhanced features and pricing details
* ✨ feat: add Codex Max Reasoning Effort parameter and slider component for enhanced model configuration
* ✨ feat: update Qwen model configurations and add new Qwen3.5 models with detailed descriptions and pricing
* ✨ feat: add GPT-5.4 and GPT-5.4 pro models with pricing and capabilities to the model bank
* ✨ feat: add GPT-5.4, GPT-5.4 pro, and GPT-5.3 Chat models with detailed capabilities and pricing to the model bank
* ✨ feat: 更新 zhipu 聊天模型的定价参数,移除不必要的 textOutput 参数
* ✨ feat: 移除 Gemini 3 Pro 模型的详细信息,标记为已弃用
* 🐛 fix: redirect to desktop onboarding when not completed
Desktop app was missing the redirect to `/desktop-onboarding` when
onboarding hadn't been completed. The `useDesktopUserStateRedirect`
callback silently returned instead of navigating, causing:
- Users never see the onboarding flow on fresh install
- `AuthRequiredModal` suppressed because onboarding guard fails
* 🐛 fix: remove desktop onboarding routes from proxy configuration
The `/desktop-onboarding` and its regex route have been removed from the proxy configuration. This change simplifies the routing logic as the onboarding flow is now handled directly in the user state redirect logic.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(openapi): add API key hash support for secure storage
* ✨ feat(openapi): enhance message translation and knowledge base functionality
- Added MessageTranslationController and associated routes for managing message translations, including fetching, creating, updating, and deleting translations.
- Introduced KnowledgeBaseController with routes for CRUD operations on knowledge bases, including file management and access control.
- Updated existing message and translation routes to improve structure and naming consistency.
- Refactored related services and types to support new features and ensure type safety.
This update enhances the API's capabilities for handling message translations and knowledge base management, improving overall functionality and user experience.
* fix: allow OWNER scope to list agents in agents route
- Add OWNER scope to AGENT_READ permission check
- Aligns list behavior with AgentService.queryAgents ownership filter
- Allows owner-scoped users to list their own agents
* 🔧 refactor(rbac): improve import structure in rbac.ts
- Changed import statements to separate type imports from regular imports for better clarity and organization.
- This refactor enhances code readability and maintains consistency in the import structure.
* fix: 修复 chunk 服务与 async router 的循环依赖
- 将 createAsyncCaller 的静态导入改为动态导入 (await import)
- 打破 file.ts -> chunk/index.ts -> async/index.ts 的循环依赖链
- 使用 --skip-dynamic-imports 参数的 dpdm 验证循环依赖已解决
* 🐛 fix: resolve CI failures
* test: 补充 apiKey、KeyVaultsEncrypt、ChunkService 单测至 100% 覆盖率
- test(database): 补充 apiKey.ts query() 解密失败分支测试
- test(server): 补充 KeyVaultsEncrypt 非法密钥/密文格式 getUserKeyVaults 测试
- test(server): 新增 ChunkService 完整测试覆盖异步任务创建/触发/失败回写
所有新增测试通过 (46/46),目标文件覆盖率均达 100%
🌐 chore: translate non-English comments to English in src/app/(backend) and src/app/[variants]/(auth)
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* ✨ feat(cli): add agent run and status commands
Implement `lh agent run` for executing agents with SSE streaming
and `lh agent status` for checking operation status. Includes
`--replay` option for offline replay from saved JSON fixtures.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix(cli): preserve SSE frame state across read boundaries and enable verbose logging
- Move eventType/eventData outside the read loop so partial SSE frames
split across chunks are not silently dropped
- Call setVerbose(true) when --verbose is passed so logger helpers
actually print detailed tool arguments and results
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* ✨ feat: add new NVIDIA models with thinking budget support
- Add 7 new models: MiniMax-M2.1, DeepSeek V3.2, GLM-4.7, GLM-5, Kimi K2.5, MiniMax-M2.5, Qwen3.5-397B-A17B
- Add thinkingBudget support for qwen3.5-397b-a17b model
- Update test case description
* 🐛 fix: remove thinking budget and add video support for Qwen3.5-397B-A17B
* 🐛 fix: support authoritize in no browser environment
* wip: remove tests
* 📝 docs: remove redundant alerts
* 🐛 fix: could not invoke brower in windows
* wip: add link and unlink cli to global
This release includes **31 commits**. Key updates are below.
### New Features and Enhancements
- Added **Telegram bot access** support.
- Added **electron page tabs** functionality for desktop.
- Added **device code auth flow** for authentication.
- Added **GPT-5.4** model support.
- Show **last used auth provider** on sign-in page for better UX.
- Support **clearing hotkey bindings** in desktop ShortcutManager.
- Added **Gemini 3.1 Flash Lite Preview** model and thinkingLevel5
extend param.
- Added **auto aspect ratio and image search** support for Nano Banana
2.
- User memories now default to inject user persona instead of
identities.
### Desktop Improvements
- Unified **update channel switching** with S3 distribution.
- Added **S3 publish for canary/nightly** and S3 cleanup (keep latest
15).
- Added electron page tabs functionality.
### Stability and Fixes
- Fixed agents fork not working in community deploy.
- Fixed animation for single-line messages between reasoning and tool
calls.
- Fixed Discord bot conflict with keyPrefix.
- Fixed skew plugin issue.
- Fixed `userMemories` database failure on extra structure mismatch.
- Fixed old LobeHub plugins update issue.
- Fixed context-engine tool type recovery from manifest when models
strip suffixes.
- Added `await` to `handleResponseAPIMode` for proper error handling.
- Fixed M2M token for community agents/MCP/skill list.
- Fixed scripts to support Win32.
- Improved gateway and device gateway CI.
### Credits
Huge thanks to these contributors (alphabetical):
@arvinxx @huangkairan @Innei @LiJian @Luis-Sambrano @nekomeowww
@rdmclin2 @ReneWang @sxjeru @tjx666
🐛 fix(ci): target channel yml files instead of latest*.yml for version prefix
The merge-mac-files step already renames latest*.yml to {channel}*.yml
(e.g., canary-mac.yml). The previous fix targeted release/latest*.yml
which matched nothing, so the sed was a no-op.
Now targets release/${CHANNEL}*.yml directly, with latest*.yml as fallback.
The latest*.yml files uploaded to S3 channel root lacked the $VERSION/
prefix in their URLs, causing electron-updater to request files at
the wrong path (e.g., /canary/LobeHub-Canary-xxx.zip instead of
/canary/2.1.38-canary.1/LobeHub-Canary-xxx.zip), resulting in 404.
Now sed -i modifies latest*.yml in-place before uploading, and
channel-specific yml files are copied from the already-modified ones.
After auto-tag-release.yml was introduced, semantic-release in release.yml
stopped working because the tag already exists when it runs. This caused
CHANGELOG.md to never be updated.
Fix: move changelog generation into auto-tag-release.yml with a custom
script that parses git log and generates gitmoji-formatted entries,
matching the existing CHANGELOG.md format. Remove the broken
semantic-release step from release.yml.
After auto-tag-release.yml was introduced, semantic-release in release.yml
stopped working because the tag already exists when it runs. This caused
CHANGELOG.md to never be updated.
Fix: move changelog generation into auto-tag-release.yml with a custom
script that parses git log and generates gitmoji-formatted entries,
matching the existing CHANGELOG.md format. Remove the broken
semantic-release step from release.yml.
🐛 fix(ci): correct stable renderer tar source path
Use the current Electron renderer output directory when creating the stable renderer archive so Linux desktop release builds stop failing after packaging succeeds.
Made-with: Cursor
* fix: slove the agnets fork not work in communtiy deploy
* fix: slove the secure token set & registerM2MToken not batch
* Revert "fix: slove the secure token set & registerM2MToken not batch"
This reverts commit 4485e57165.
* ✨ feat: add GPT-5.4 model support and fix reasoning payload pruning
- Add GPT-5.4 model card to model-bank
- Update planCardModels to use gpt-5.4
- Add gpt-5.4 to responsesAPIModels
- Fix pruneReasoningPayload to strip logprobs/top_logprobs for reasoning models
- Add logprobs, top_logprobs to ChatStreamPayload type
- Extend reasoning_effort to include none and xhigh
- Add success log for non-fallback requests in RouterRuntime
- Fix log parameter mismatch in RouterRuntime
Fixes LOBE-5735
* 🐛 fix: match gpt-5.4 to gpt5_2ReasoningEffort in openrouter and vercelaigateway
* 🐛 fix: update OpenRouterReasoning effort type to include none and xhigh
* 🐛 fix: use tiered pricing for gpt-5.4 based on 272K token threshold
* 🌐 chore: update i18n translations
* 🐛 fix: update claude-sonnet model version to 4-6 in planCardModels
* ✨ feat: add GPT-5.4 Pro model support
* 🐛 fix: remove dated snapshot for gpt-5.4-pro in responsesAPIModels
* 🐛 fix: add tierBy support for cross-unit tiered pricing threshold
OpenAI charges output at 1.5x when INPUT exceeds 272K tokens.
The tiered strategy previously only checked the unit's own quantity
to select a tier. Added optional tierBy field to TieredPricingUnit
so output/cacheRead tiers can reference input quantity for selection.
* 🐛 fix: use totalInputTokens for tiered pricing tier selection
Tiered pricing tiers should be determined by total prompt size
(totalInputTokens), not each unit's own quantity. This fixes output
and cacheRead being charged at the wrong tier rate when the prompt
exceeds the threshold but the individual unit quantity does not.
* 🔧 chore: update @lobehub/ui dependency to a specific version URL and enhance ShortcutManager functionality
- Updated @lobehub/ui dependency in package.json to a specific version URL.
- Improved ShortcutManager to handle empty accelerator bindings, allowing users to clear shortcuts.
- Updated tests to reflect changes in shortcut handling and added localization for clear binding messages in both Chinese and English.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @lobehub/ui dependency to version 5.4.0 in package.json
- Changed the @lobehub/ui dependency from a specific version URL to version 5.4.0 for improved stability and consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @lobehub/ui dependency to use caret versioning in package.json
- Changed the @lobehub/ui dependency from a fixed version to caret versioning (^5.4.0) to allow for minor updates and improvements.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* 👷 ci(desktop): add S3 cleanup for canary/nightly (keep latest 15)
- Create `.github/actions/desktop-cleanup-s3/` reusable composite action
- Add S3 version cleanup step to canary and nightly cleanup jobs
- Cleanup runs after both publish-release and publish-s3 complete
* 👷 ci(desktop): fix S3 yml upload and add debug output
- Restore latest*.yml → {channel}*.yml logic (electron-builder always generates latest-*.yml)
- Upload both {channel}*.yml and latest*.yml to S3
- Change upload glob from latest* to *.yml for robustness
- Add yml file listing debug output in both upload and publish steps
👷 ci(desktop): extract S3 publish logic into reusable composite action
- Create `.github/actions/desktop-publish-s3/` composite action for S3 upload
- Add `publish-s3` job to canary and nightly workflows (previously missing)
- Refactor stable workflow to use the shared action
- Fix canary/nightly builds not uploading to S3 despite UPDATE_SERVER_URL being set
* ✨ feat: add electron page tabs functionality
Implement browser-style page tabs in the Electron titlebar:
- Add TabBar component with explicit tab creation via context menu (desktop only)
- Tab creation triggers: TopicItem/PageItem context menu "Open in New Tab" or double-click
- TabBar only visible when tab count >= 2
- Update active tab's reference when navigating within it (tab follows user navigation)
- Reuse existing plugin system (pluginRegistry, 11 page plugins, PageReference types)
- Persist tabs to localStorage with automatic recovery on restart
- Apply logic to TopicItem (agent & group) and PageItem
Changes:
- src/store/electron/actions/tabPages.ts: New store slice with tab state + actions
- src/features/Electron/titlebar/TabBar/: New UI component + storage + hooks
- src/features/Electron/navigation/: New useTabNavigation hook + extracted cachedData helper
- src/app/.../Topic/List/Item/: Double-click creates tab, context menu "Open in New Tab"
- src/app/.../page/.../Item/: Double-click creates tab, context menu "Open in New Tab"
- i18n: New keys in topic.ts and file.ts namespaces
* ✨ feat: enhance agent topic plugin and tab resolution logic
- Added a new line to ensure the cached title is included when resolving tabs in the useResolvedTabs hook.
- Minor adjustment in the agentTopicPlugin to improve code clarity.
These changes improve the handling of cached titles in the tab resolution process and enhance the overall functionality of the agent topic plugin.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: enhance agent and conversation handling in PageEditor
- Refactored PageAgentProvider to eliminate direct pageAgentId prop, improving context management.
- Updated Conversation and Copilot components to utilize conversation state for agent selection, ensuring better handling of chat-group session IDs.
- Adjusted FileCopilot to synchronize active agent ID with conversation context, enhancing file interaction capabilities.
These changes streamline agent management and improve the overall user experience in the PageEditor feature.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update ESLint suppressions for chat service [skip ci]
- Removed the suppression for `object-shorthand` in `src/services/chat/index.ts` to improve code quality.
- Adjusted the ESLint suppressions in `eslint-suppressions.json` for better linting consistency.
These changes enhance the linting process by ensuring adherence to coding standards in the chat service files.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: optimize NavigationBar panel width handling
* ✨ feat: add tab context menu with close actions
Add right-click context menu on tab items:
- Close current tab
- Close other tabs
- Close tabs to the left (disabled on first tab)
- Close tabs to the right (disabled on last tab)
* 🐛 fix: defer single-click navigation on desktop to prevent double-click addTab race
* ✨ feat: implement onActivate method for RecentlyViewed plugins to manage store state transitions
- Added onActivate method to RecentlyViewedPlugin interface for handling tab activations.
- Updated agentPlugin and agentTopicPlugin to switch topics based on tab activation.
- Enhanced PluginRegistry to notify plugins on tab activation.
- Modified TabBar to trigger onActivate when a tab is activated.
- Improved AgentIdSync to preserve topic state during agent switches.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: update test for BackendProxyProtocolManager to throw on upstream fetch failure
- Changed test description to reflect behavior change from returning a 502 status to throwing an error.
- Updated test implementation to use expect().rejects.toThrow for handling fetch errors.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: use optional chaining for agent configuration properties
- Updated agent configuration properties to use optional chaining for safer access.
- This change prevents potential runtime errors when properties are undefined.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: optimize navigation handling in TabBar with startTransition
- Introduced startTransition for navigation updates to improve performance and user experience.
- Updated handleActivate, handleCloseOthers, handleCloseLeft, and handleCloseRight methods to use startTransition for routing.
- Enhanced code readability by grouping navigation logic within startTransition.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(desktop): add update channel settings for desktop app
* 🔧 chore(desktop): update test scripts for multi-channel update flow
- Support stable/nightly/canary channel structure in generate-manifest.sh
- Add --all-channels flag for generating manifests across all channels
- Dual-mode run-test.sh: packaged (full updater) and --dev (UI only)
- Fix package:mac:local to skip signing for local builds
- Document Squirrel.Mac signature validation limitation
* 🔧 chore(desktop): update local app update configuration
- Change provider from GitHub to Generic for local testing.
- Update local server URL and cache directory settings.
- Revise comments for clarity on usage and configuration.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix(desktop): fix update channel switch race condition and downgrade flag
- P1: Use generation counter to discard stale check results when channel
is switched mid-flight. Pending recheck is scheduled after current check
completes instead of forcing concurrent checks.
- P2: Explicitly reset allowDowngrade=false on non-downgrade transitions
to prevent stale downgrade permission from persisting.
- Fix GitHub fallback repo name (lobe-chat -> lobehub).
* 🔧 chore(settings): remove dynamic import for Beta component from componentMap
- Eliminated the dynamic import for the Beta settings tab, streamlining the component map.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore(settings): simplify UpdateChannel component structure
- Refactored the UpdateChannel component to streamline the Select component usage by removing unnecessary nested children.
Signed-off-by: Innei <tukon479@gmail.com>
* update
* 🐛 fix(desktop): strip channel suffix from UPDATE_SERVER_URL before appending channel
The UPDATE_SERVER_URL secret may already contain a channel path (e.g., /stable).
Previously, the code unconditionally appended /{channel}, resulting in double
paths like /stable/stable/stable-mac.yml.
Now both electron-builder.mjs and UpdaterManager strip any trailing channel
suffix before re-appending the correct channel, supporting both legacy URLs
(with channel) and clean base URLs.
* update
* update
* redesign ui
- Added `getUpdaterState` method to `UpdaterManager` for retrieving current update status.
- Introduced `UpdaterState` type to encapsulate update progress, stage, and error messages.
- Updated UI components to reflect update states, including checking, downloading, and latest version notifications.
- Enhanced menu items for macOS and Windows to display appropriate update statuses.
- Localized new update messages in English and Chinese.
This improves user experience by providing real-time feedback during the update process.
Signed-off-by: Innei <tukon479@gmail.com>
* Enhance UpdaterManager tests and mock implementations
- Updated tests for UpdaterManager to reflect changes in broadcasting update states, including 'checking', 'downloading', and 'error' stages.
- Modified mock implementations in macOS and Windows test files to include `getUpdaterState` and `installNow` methods for better state management.
- Improved test coverage for update availability and download processes.
These changes ensure more accurate testing of the update flow and enhance the overall reliability of the UpdaterManager functionality.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* support keyPrefix
* feat: add telegram platform implementation
* feat: add telegram front end ui
* feat: support webhookProxyUrl
* chore: add more log info
* fix: header align
* chore: add onNewMessage to platform specific
* fix: test connnectitvity and add application id
* feat: support local tunnel
* chore: optimize telegram message format
* fix: webhook secrect
* feat: keep typing interval
---------
Co-authored-by: arvinxx <arvinx@foxmail.com>
When a short message is sandwiched between reasoning and tool call blocks,
component remount during streaming causes the fadeIn animation to replay.
Disable animation for these tool-adjacent single-line messages to prevent
the visual flicker.
* fix: skew plugin
Signed-off-by: Innei <tukon479@gmail.com>
* refactor(vite): enhance vercelSkewProtection to handle static imports and improve coverage
- Added handling for static import/export declarations to ensure correct deployment links.
- Updated coverage documentation to reflect new handling for static imports and additional cases.
- Adjusted comment numbering for clarity in the processing steps.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: dev proxy
Signed-off-by: Innei <tukon479@gmail.com>
* refactor(AssistantGroup): streamline contentId handling in GroupMessage component
- Simplified the logic for determining contentId by directly using lastAssistantMsg?.id.
- Moved the creation and generation state checks to follow the contentId assignment for better clarity.
Signed-off-by: Innei <tukon479@gmail.com>
* ♻️ refactor: remove chunk error reload retry, keep notification only
Made-with: Cursor
* fix: inject
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* Update sync.yml
* ✨ feat: update aspect ratio defaults to 'auto' for image generation models
* ✨ feat: enhance grounding metadata handling with image search results support
* ✨ feat: filter empty strings from searchQueries in groundingMetadata and update favicon handling in SearchGrounding component
* ✨ feat: add inputToolTokens tracking and update related components for tool usage
* ✨ feat: enhance search grounding with image results and update related components
* ✨ feat: add ImageSearchRef component and related tests for image reference handling
* fix test: rename VertexAIStream to GoogleGenerativeAIStream for consistency in test cases
* Update sync.yml
* 🐛 fix: add unsaved changes guard to prevent data loss on navigation
Migrate from BrowserRouter to createBrowserRouter (data router API) to enable
route-level navigation blocking. Add UnsavedChangesGuard component that uses
useBlocker to prevent leaving editor pages with unsaved changes, auto-saving
before navigation. Remove legacy renderRoutes/RouteConfig dead code.
Fixes LOBE-4973
* 🔧 chore: remove unused ESLint suppressions for welcome.ts
Cleaned up eslint-suppressions.json by removing suppressions related to sort-keys-fix and typescript-sort-keys for welcome.ts, as they are no longer needed.
Signed-off-by: Innei <tukon479@gmail.com>
* ⚡ perf: skip JSON snapshot on selection-only Lexical updates
Reintroduce dirtyElements/dirtyLeaves guard before editor.getDocument('json')
and deep-equality check, avoiding O(document-size) work on caret/selection
updates that do not mutate content.
* 🔧 test: update UnsavedChangesGuard tests to use message.destroy instead of message.success
Signed-off-by: Innei <tukon479@gmail.com>
* fix: dayjs init
- Moved dayjs plugin extensions (relativeTime, utc, isToday, isYesterday) to src/initialize.ts for centralized initialization.
- Removed redundant extensions from individual components to prevent duplicate calls.
- Updated locale loading logic in Locale.tsx to ensure correct dayjs locale handling.
This change improves performance by ensuring dayjs plugins are only extended once during application initialization.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: update router configuration to use RouteObject type
- Changed the type of desktopRoutes from RouteConfig[] to RouteObject[] for better compatibility with react-router-dom.
- Removed the RouteConfig interface from the router utility file to streamline the codebase.
This refactor enhances the router's integration with the latest routing library standards.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: enhance Vite configuration and chunk management
- Added a function to suppress Vite's default URL print in the server configuration.
- Updated chunk file naming strategy in sharedRollupOutput to organize output files into specific directories based on chunk type (i18n, vendor, assets).
- Removed redundant dayjs chunk handling logic to streamline the manualChunks function.
These changes improve the clarity of the build output and enhance the server's configuration options.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: add collapsible error stack with __CI__ default expand
- Add Collapse + Highlighter for error stack in Error component
- Define __CI__ in Vite (sharedRendererDefine) based on process.env.CI
- Add __CI__ to global.d.ts
- Add error.stack i18n to all 18 locales
Made-with: Cursor
* chore: update build:spa:copy script to handle multiple asset directories
- Modified the build:spa:copy script in package.json to iterate over multiple directories (assets, i18n, vendor) for both desktop and mobile builds, improving the asset copying process.
This change enhances the build process by ensuring all relevant directories are copied correctly.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: mark initialize.ts as sideEffects to prevent tree-shaking
sideEffects: false caused Rollup to drop the side-effect-only import
of initialize.ts, removing dayjs.extend(relativeTime) and enableMapSet()
from the production bundle.
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ♻️ refactor: replace minImageSize with width/height min/max constraints
Refactor image dimension validation from a single `minImageSize` value
to flexible `width`/`height` objects with `min`/`max`, consistent with
the `duration` field's min/max pattern.
* ♻️ refactor: handle single-axis constraints in dimension error messages
Build dimension constraint text dynamically (e.g. "width ≥ 300px" or
"width ≥ 300px, height ≥ 300px") instead of interpolating raw
minWidth/minHeight values, preventing "300xundefinedpx" when only one
axis is constrained.
* ♻️ refactor(video): add max dimension constraint per official docs
Seedance image dimensions: 300-6000px per official documentation.
* ✨ feat(video): add aspect ratio validation for image uploads
Support aspectRatio constraint (width/height) with min/max in schema.
Seedance config: aspectRatio { min: 0.4, max: 2.5 } per official docs.
* ♻️ refactor(locales): add image dimension validation messages for multiple languages
* 🐛 fix(desktop): stub better-auth client for Electron and improve drag regions
Add auth-client.desktop.ts noop stub so the Electron renderer build
skips the real better-auth dependency that was crashing module evaluation
and preventing React from mounting.
Also fix drag-bar regions in splash.html and error.html, and add
dev:desktop convenience script.
* ♻️ refactor(desktop): lazy-init better-auth client with remote server URL
Replace noop stub with Proxy-based lazy initialization that creates the
real better-auth client on first use, using the configured remote server
URL from the electron store as baseURL.
* 🔧 fix(desktop): update Proxy target in lazyProp for better-auth client initialization
Change the Proxy target in the lazyProp function from a noop stub to a function, ensuring the apply trap works correctly for lazy initialization of the better-auth client.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix(profile): restrict SSO providers display to non-desktop view
Update the condition for rendering the SSO Providers Row in the Profile Settings to only show when the user is logged in and not on a desktop device. This change improves the user interface by preventing unnecessary display on desktop screens.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
- Remove desktop-related build steps from Dockerfile
- Simplify next.config.ts, only apply Vercel-specific config on Vercel
- Remove webpack customization from define-config.ts
- Fix String() type conversion in video.ts
* ✨ feat: add support for new image resolution and thinking level parameters in model configurations
* ✨ feat: add Gemini 3.1 Flash Image model with enhanced capabilities and update model configurations
* 🐛 fix: adjust temperature setting based on model modalities in LobeGoogleAI
* ✨ feat: add DeepSeek V3.2 model and update existing model configurations
* ✨ feat: add ImageResolution2Slider and ThinkingLevel4Slider components; remove obsolete imports
* ✨ feat: add imageAspectRatio2 parameter for Nano Banana 2 model; update related components and configurations
* 🐛 fix: refactor outputTextTokens calculation for clarity and consistency
* ⚡️ perf(spa): lazy import spaHtmlTemplates to reduce initial bundle
* 🔧 chore: update package dependencies and Vite configuration
- Bump @lobehub/icons version from ^4.1.0 to ^4.9.0 in package.json for improved features and fixes.
- Set Vite server host to '0.0.0.0' for better accessibility during development.
- Refactor asset URL rewriting in route.ts to simplify the return statement in the development mode.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(analytics): enhance Google and Vercel analytics integration
- Refactored GoogleAnalytics component to accept a `gaId` prop for improved flexibility.
- Updated VercelAnalytics component to accept a `debug` prop, allowing for dynamic debugging.
- Modified Analytics index to pass the appropriate props to Google and Vercel components based on environment settings.
- Removed the obsolete LobeAnalyticsProviderWrapper.vite.tsx file to streamline the codebase.
This update improves the configurability of analytics components and cleans up unused files.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* feat: improve the inject model context plugins decriptions
fix: change the conversation-flow to change the subAgent message show place
fix: eslint fixed
fix: slove the inject not work problem
feat: add the lost agent management inject open
feat: add the AgentManagementInjector
fix: add the exec task mode & improve the Pre-load agents
fix: improve the executor import way & update the getEffectiveAgentId function
fix: slove the test problem
🐛 fix: support agnet manager ments (#12171)
feat: add the sub agents in context scope to support call subagent
refactor agent management implement
update
add builtin agent management
* fix types
* fix import
* fix test
* fix tests
* fix tests
* 🐛 fix: update provider request filtering to include settings for disabling browser requests
* 🐛 test: add unit tests for isProviderDisableBrowserRequest function
* 🐛 fix(models): remove deprecated AI models and add Step 3.5 Flash model
* ✨ feat(model-bank): add Qwen3 Coder Next and GLM-4.7 models; remove Qianfan Lightning 128B A19B
* feat: add new Qwen3.5 and MiniMax-M2.5 models with updated pricing and capabilities
* feat: update cerebras and ollamacloud models with new Qwen3.5 capabilities and adjust pricing in qwen model
* init plan
* 📝 docs: update SPA plan for dev mode Worker cross-origin handling
- Clarified the handling of Worker cross-origin issues in dev mode, emphasizing the need for `workerPatch` to wrap cross-origin URLs as blob URLs.
- Enhanced the explanation of the dev mode's resource URL rewriting process for better understanding.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: Phase 1 - 环境变量整治
- Fix Pyodide env var mismatch (NEXT_PUBLIC_PYPI_INDEX_URL → pythonEnv.NEXT_PUBLIC_PYODIDE_PIP_INDEX_URL)
- Consolidate python.ts to use pythonEnv instead of direct process.env
- Remove NEXT_PUBLIC_ prefix from server-side MARKET_BASE_URL (5 files)
* 🏗️ chore: Phase 2 - Vite 工程搭建
- Add vite.config.ts with dual build (desktop/mobile via MOBILE env)
- Add index.html SPA template with __SERVER_CONFIG__ placeholder
- Add entry.desktop.tsx and entry.mobile.tsx SPA entry points
- Add dev:spa, dev:spa:mobile, build:spa, build:spa:copy scripts
- Install @vitejs/plugin-react and linkedom
* ♻️ refactor: Phase 3 - 第一方包 Next.js 解耦
- Replace next/link with <a> in builtin-tool-web-browsing (4 files, external links)
- Replace next/image with <img> in builtin-tool-agent-builder/InstallPlugin.tsx
- Add Vite import.meta.env compat for isDesktop in const/version.ts, builtin-tool-gtd, builtin-tool-group-management
* ♻️ refactor: Phase 4a - Auth 页面改用直接 next/navigation 和 next/link
- 9 auth files: @/libs/next/navigation → next/navigation
- 5 auth files: @/libs/next/Link → next/link
- Auth pages remain in Next.js App Router, need direct Next.js imports
* ♻️ refactor: Phase 4b - Next.js 抽象层替换为 react-router-dom/vanilla React
- navigation.ts: useRouter/usePathname/useSearchParams/useParams → react-router-dom
- navigation.ts: redirect/notFound → custom error throws
- navigation.ts: useServerInsertedHTML → no-op for SPA
- Link.tsx: next/link → react-router-dom Link adapter (href→to, external→<a>)
- Image.tsx: next/image → <img> wrapper with fill/style support
- dynamic.tsx: next/dynamic → React.lazy + Suspense wrapper
* ✨ feat: Phase 5 - 新建 SPAGlobalProvider
- Create SPAServerConfig type (analyticsConfig, clientEnv, theme, featureFlags, locale)
- Add window.__SERVER_CONFIG__ and __MOBILE__ to global.d.ts
- Create SPAGlobalProvider (client-only Provider tree mirroring GlobalProvider)
- Includes AuthProvider for user session support
- Update entry.desktop.tsx and entry.mobile.tsx to wrap with SPAGlobalProvider
* ♻️ refactor: add SPA catch-all route handler with Vite dev proxy
- Create (spa)/[[...path]]/route.ts for serving SPA HTML
- Dev mode: proxy Vite dev server, rewrite asset URLs, inject Worker patch
- Prod mode: read pre-built HTML templates
- Build SPAServerConfig with analytics, theme, clientEnv, featureFlags
- Update middleware to pass SPA routes through to catch-all
* ♻️ refactor: skip auth checks for SPA routes in middleware
SPA pages are all public (no sensitive data in HTML).
Auth is handled client-side by SPAGlobalProvider's AuthProvider.
Only Next.js auth routes and API endpoints go through session checks.
* ♻️ refactor: replace Next.js-specific analytics with vanilla JS
- Google.tsx: replace @next/third-parties/google with direct gtag script
- ReactScan.tsx: replace react-scan/monitoring/next with generic script
- Desktop.tsx: replace next/script with native script injection
* ♻️ refactor: migrate @t3-oss/env-nextjs to @t3-oss/env-core
Replace framework-specific env validation with framework-agnostic version.
Add clientPrefix where client schemas exist.
* ♻️ refactor: replace next-mdx-remote/rsc with react-markdown
Use client-side react-markdown for MDX rendering instead of
Next.js RSC-dependent next-mdx-remote.
* 🔧 chore: update build scripts and Dockerfile for SPA integration
- build:docker now includes SPA build + copy steps
- dev defaults to Vite SPA, dev:next for Next.js backend
- Dockerfile copies public/spa/ assets for production
- Add public/spa/ to .gitignore (build artifact)
* 🗑️ chore: remove old Next.js route segment files and serwist PWA
- Delete [variants] page.tsx, error.tsx, not-found.tsx, loading.tsx
- Delete root loading.tsx and empty [[...path]] directory
- Delete unused loaders directory
- Remove @serwist/next PWA wrapper from Next.js config
* plan2
* ✨ feat: add locale detection script to index.html for SPA dev mode
* ♻️ refactor: remove locale and theme from SPAServerConfig
* ✨ feat: add [locale] segment with force-static and SEO meta generation
* ♻️ refactor: remove theme/locale reads from SPAGlobalProvider
* ✨ feat: set vite base to /spa/ for production builds
* ✨ feat: auto-generate spaHtmlTemplates from vite build output
* 🔧 chore: register dev:next task in turbo.json for parallel dev startup
* ♻️ refactor: rename (spa) route group to spa segment, rewrite SPA routes via middleware
* ✨ feat: add Vite-compatible i18n/locale modules with import.meta.glob and resolve aliases
* 🔧 fix: use custom Vite plugin for module redirects instead of resolve.alias
* very important
* build
* 🔧 chore: update build scripts and clean up Vite configuration by removing unused plugin and code
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ refactor: remove all electron modifier scripts
Modifiers are no longer needed with Vite SPA renderer build.
* ✨ feat: add Vite renderer entry to electron-vite config
Add renderer build configuration to electron-vite, replacing the old
Next.js shadow workspace build flow. Delete buildNextApp.mts and
moveNextExports.ts, update package.json scripts accordingly.
* ✨ feat: add .desktop suffix files for eager i18n loading
Create 4 .desktop files that use import.meta.glob({ eager: true })
for synchronous locale access in Electron desktop builds, replacing
the async lazy-loading used in web SPA builds.
* 🔧 refactor: adapt Electron main process for Vite renderer
Replace nextExportDir with rendererDir, update protocol from
app://next to app://renderer, simplify file resolution to SPA
fallback pattern, update _next/ asset paths to /assets/.
* 🔧 chore: update electron-builder files config for Vite renderer
Replace dist/next references with dist/renderer, remove Next.js
specific exclusion rules no longer applicable to Vite output.
* 🗑️ chore: remove @ast-grep/napi dependency
No longer needed after removing electron modifier scripts.
* 🔧 refactor: unify isDesktop to __ELECTRON__ compile-time constant
Remove NEXT_PUBLIC_IS_DESKTOP_APP and VITE_IS_DESKTOP_APP env vars.
Unify isDesktop in @lobechat/const using __ELECTRON__ defined by Vite.
Re-export from builtin-tool packages. Scripts use DESKTOP_BUILD.
* update
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: use electron-vite ELECTRON_RENDERER_URL instead of hardcoded port 3015
Replace hardcoded http://localhost:3015 with process.env.ELECTRON_RENDERER_URL
injected by electron-vite dev server. Clean up stale Next.js references.
* 🐛 fix: use local renderer-entry shim to resolve Vite root path issue
HTML entry ../../src/entry.desktop.tsx resolves to /src/entry.desktop.tsx
in URL space, which Vite cannot find within apps/desktop/ root. Add a
local shim that imports across root via module resolver instead.
* 🔧 refactor: extract shared renderer Vite config into sharedRendererConfig
Deduplicate plugins (nodeModuleStub, platformResolve, tsconfigPaths) and
define (__MOBILE__, __ELECTRON__, process.env) between root vite.config.ts
and electron.vite.config.ts renderer section.
* 🔧 refactor: move all renderer plugins and optimizeDeps into shared config
sharedRendererPlugins now includes react, codeInspectorPlugin alongside
nodeModuleStub, platformResolve, tsconfigPaths. Add sharedOptimizeDeps
for pre-bundling list. Both root and electron configs consume shared only.
* 🐛 fix: set electron renderer root to monorepo root for correct glob resolution
import.meta.glob with absolute paths (e.g. /node_modules/antd/...) resolved
within apps/desktop/ instead of monorepo root. Change renderer root to ROOT_DIR,
add electronDesktopHtmlPlugin middleware to rewrite / to /apps/desktop/index.html,
and remove the now-unnecessary renderer-entry.ts shim.
* desktop vite !!
Signed-off-by: Innei <tukon479@gmail.com>
* sync import !!
Signed-off-by: Innei <tukon479@gmail.com>
* clean ci!!
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: update SPA path structure and clean up dependencies
- Changed the path in .gitignore and related files from [locale] to [variants] for SPA templates.
- Updated index.html to set body height to 100%.
- Cleaned up package.json by removing unused dependencies and reorganizing devDependencies.
- Refactored RendererUrlManager to use a constant for SPA entry HTML path.
- Removed obsolete route.ts file from the SPA structure.
- Adjusted proxy configuration to reflect the new SPA path structure.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update build script to include mobile SPA build
- Modified the build script in package.json to add the mobile SPA build step.
- Ensured the build process accommodates both desktop and mobile SPA versions.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update build scripts and improve file encoding consistency
- Modified the build script in package.json to ensure the SPA copy step runs after the build.
- Updated file encoding in generateSpaTemplates.mts from 'utf-8' to 'utf8' for consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 fix: correct Blob import syntax and update global server config type
- Fixed the Blob import syntax in route.ts to ensure proper module loading.
- Updated the global server configuration type in global.d.ts for improved type safety.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 test: update RendererUrlManager test to reflect new file path
- Modified the mock implementation in RendererUrlManager.test.ts to check for the updated file path '/mock/export/out/apps/desktop/index.html'.
- Adjusted the expected resolved path in the test to match the new structure.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: remove catch-all example file and update imports
- Deleted the catch-all example file `catch-all.eg.ts` to streamline the codebase.
- Updated import paths in `ClientResponsiveLayout.tsx` and `ClientResponsiveContent/index.tsx` to use the new dynamic import location.
- Added type declarations for HTML templates in `spaHtmlTemplates.d.ts`.
- Adjusted `tsconfig.json` to include the updated file structure.
- Enhanced type definitions in `global.d.ts` and fixed locale loading in `locale.vite.ts`.
Signed-off-by: Innei <tukon479@gmail.com>
* e2e
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: remove unused build script for Vercel deployment
- Deleted the `build:vercel` script from package.json to streamline the build process.
- Ensured the remaining build scripts are organized and relevant.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 config: update Vite build input for mobile support
- Changed the build input path in vite.config.ts to conditionally use 'index.mobile.html' for mobile builds, enhancing support for mobile SPA versions.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 feat: add compatibility checks for import maps and cascade layers
- Implemented functions to check for browser support of import maps and CSS cascade layers.
- Redirected users to a compatibility page if their browser does not support the required features.
- Updated the build script in package.json to use the experimental analyze command for better performance.
Signed-off-by: Innei <tukon479@gmail.com>
* chore: rename
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 feat: refactor authentication layout and introduce global providers
- Created a new `RootLayout` component to streamline the layout structure.
- Removed the old layout file for variants and integrated necessary features into the new layout.
- Added `AuthGlobalProvider` to manage authentication context and server configurations.
- Introduced language and theme selection components for enhanced user experience.
- Updated various components to utilize the new context and improve modularity.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 config: exclude build artifacts from serverless functions
- Updated the `next.config.ts` to exclude SPA, desktop, and mobile build artifacts from serverless functions.
- Added paths for `public/spa/**`, `dist/**`, `apps/desktop/build/**`, and `packages/database/migrations/**` to the exclusion list.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 config: refine exclusion of build artifacts from serverless functions
- Updated `next.config.ts` to specify exclusion paths for desktop and mobile build artifacts.
- Changed exclusions from `dist/**` and `apps/desktop/build/**` to `dist/desktop/**`, `dist/mobile/**`, and `apps/desktop/**` for better clarity and organization.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 fix: update BrowserRouter basename for local development
- Modified the `ClientRouter` component to conditionally set the `basename` of `BrowserRouter` based on the `__DEBUG_PROXY__` variable, improving local development experience.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 feat: implement mobile SPA workflow and S3 asset management
- Added a new workflow for building and uploading mobile SPA assets to S3, including environment variable configurations in `.env.example`.
- Updated `package.json` to include a new script for the mobile SPA workflow.
- Enhanced the Vite configuration to support dynamic CDN base paths.
- Refactored the template generation script to handle mobile HTML templates more effectively.
- Introduced new modules for uploading assets to S3 and generating mobile HTML templates.
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: extract origin from MOBILE_S3_PUBLIC_DOMAIN to prevent double key prefix
* 🔧 fix: update mobile HTML template to use the latest asset versions
- Modified the mobile HTML template to reference the updated JavaScript asset version for improved functionality.
- Ensured consistency in the template structure while maintaining existing styles and scripts.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update dependencies and refine service worker integration
- Removed outdated dependencies related to Serwist from package.json and tsconfig.json.
- Added vite-plugin-pwa to enhance PWA capabilities in the Vite configuration.
- Updated service worker registration logic in the PWA installation component.
- Introduced a new local development proxy route for debugging purposes.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: refactor development scripts and remove Turbo configuration
- Updated the `dev` script in `package.json` to use a new startup sequence script for improved development workflow.
- Removed the outdated `turbo.json` configuration file as it is no longer needed.
- Introduced `devStartupSequence.mts` to manage the startup of Next.js and Vite processes concurrently.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 feat: update entry points and introduce debug proxy for local development
- Changed the main entry point in `index.html` from `entry.desktop.tsx` to `entry.web.tsx` for improved web compatibility.
- Added an `initialize.ts` file to enable `immer`'s `enableMapSet` functionality.
- Introduced a new `__DEBUG_PROXY__` variable in global types to support local development proxy features.
- Implemented a debug proxy route to facilitate local development with dynamic HTML injection and script handling.
- Removed outdated mobile routing components to streamline the codebase.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: replace BrowserRouter with RouterProvider for improved routing
- Updated entry points for desktop, mobile, and web to utilize RouterProvider and createAppRouter for better routing management.
- Removed the deprecated renderRoutes function in favor of a more streamlined router configuration.
- Enhanced router setup to support error boundaries and dynamic routing.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: remove direct access handling for SPA routes in proxy configuration
- Eliminated the handling of direct access to pre-rendered SPA pages in the proxy configuration.
- Simplified the request processing logic by removing checks for SPA routes, streamlining the middleware response flow.
Signed-off-by: Innei <tukon479@gmail.com>
* update
* 🔧 refactor: enhance Worker instantiation logic in mobile HTML template
* 🐛 fix: remove duplicate waitForPageWorkspaceReady calls in page CRUD e2e steps
* 🔧 refactor: simplify createTracePayload function by using btoa for base64 encoding
* 🔧 refactor: specify locales in import.meta.glob for dayjs and antd
* 🔧 refactor: replace Node.js Buffer with web-compatible btoa for base64 encoding in file upload
* 🐛 fix: disable consistent-type-imports rule for mdx files to prevent eslint crash
* 🔧 refactor: add height style to root div for consistent layout
* 🔧 refactor: replace btoa with Buffer for base64 encoding in trace and file upload handling
* 🔧 refactor: extract nextjsOnlyRoutes to a separate file for better organization
* 🔧 refactor: enable Immer MapSet plugin in tests for better state management
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: integrate sharedRollupOutput configuration and increase cache size for better performance
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove obsolete desktop.routes.test.ts file as it is no longer needed
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: use cross-env for env vars in npm scripts (Windows CI)
Co-authored-by: Cursor <cursoragent@cursor.com>
* 🔧 chore: update Dockerfile for web-only build and adjust npm scripts to use pnpm
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: enhance Dockerfile prebuild process with environment checks and add new dependencies
- Updated Dockerfile to include environment checks before removing desktop-only code.
- Added new dependencies in package.json: @aws-sdk/client-bedrock-runtime, @opentelemetry/auto-instrumentations-node, @opentelemetry/resources, @opentelemetry/sdk-metrics, and ajv.
- Configured Rollup to exclude @aws-sdk/client-bedrock-runtime from the SPA bundle.
- Introduced dockerPrebuild.mts script for environment variable validation and information logging.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: enhance Vite and Electron configurations with environment loading and trace encoding improvements
- Updated Vite and Electron configurations to load environment variables using loadEnv.
- Modified trace encoding in utils to use TextEncoder for better compatibility.
- Adjusted sharedRendererConfig to expose only necessary public environment variables.
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove plans directory (migrated to discussion)
* ♻️ refactor: inject NEXT_PUBLIC_* env per key in Vite define
Co-authored-by: Cursor <cursoragent@cursor.com>
* ✨ feat: add loading screen with animation to enhance user experience
- Introduced a loading screen with a brand logo and animations for better visual feedback during loading times.
- Implemented CSS styles for the loading screen and animations in index.html.
- Removed the loading screen from the DOM once the layout is ready using useLayoutEffect in SPAGlobalProvider.
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove unnecessary external dependency from Vite configuration
- Eliminated the external dependency '@aws-sdk/client-bedrock-runtime' from the Vite configuration to streamline the build process for the SPA bundle.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: add web app manifest link in index.html and enable PWA support in Vite configuration
- Added a link to the web app manifest in index.html to enhance PWA capabilities.
- Enabled manifest support in Vite configuration for improved service worker functionality.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update link rel attributes for improved SEO and consistency
- Modified link rel attributes in multiple components to remove 'noreferrer' and standardize to 'nofollow'.
- Adjusted imports in PageContent components for better organization.
Signed-off-by: Innei <tukon479@gmail.com>
* update provider
* ✨ feat: enhance loading experience and update package dependencies
- Added a loading screen with animations and a brand logo in index.html for improved user feedback during loading times.
- Introduced CSS styles for the loading screen and animations.
- Updated package.json files across multiple packages to include "@lobechat/const" as a dependency.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: update proxy
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove GlobalLayout and Locale components
- Deleted GlobalLayout and Locale components from the GlobalProvider directory to streamline the codebase.
- This removal is part of a refactor to simplify the layout structure and improve maintainability.
Signed-off-by: Innei <tukon479@gmail.com>
* chore: clean up console logs and improve component structure
- Removed unnecessary console log statements from AgentForkTag components in both agent and community directories to enhance code cleanliness.
- Refactored UserAgentList component for better readability by restructuring the useUserDetailContext hook and adjusting the layout of Flexbox components.
Signed-off-by: Innei <tukon479@gmail.com>
* chore: remove console log from MemoryAnalysis component
* chore: update mobile HTML template with new asset links
- Replaced the previous asset links in the mobile HTML template with updated versions to ensure the latest resources are utilized.
- Adjusted the link rel attributes for module preloading to enhance performance and loading efficiency.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: correct variable assignment in createClientTaskThread integration test
- Updated the assignment of the second parent message in the createClientTaskThread integration test to improve clarity and ensure proper data handling.
- Changed the variable name from 'secondParentMsg' to 'inserted' for better context before extracting the first message from the inserted results.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor: simplify authentication check in define-config
- Removed the dependency on the isDesktop variable in the authentication check to streamline the logic.
- Enhanced the clarity of the redirection process for protected routes by focusing solely on the isLoggedIn status.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(dev): enhance local development setup with debug proxy instructions
- Added detailed instructions for starting the development environment in CLAUDE.md, including commands for SPA and full-stack modes.
- Updated README.md and README.zh-CN.md to reflect new commands and the debug proxy URL for local development.
- Introduced a Vite plugin to print the debug proxy URL upon server start, facilitating easier local development against the production backend.
- Corrected the debug proxy route in entry.web.tsx and define-config.ts for consistency.
This improves the developer experience by providing clear guidance and tools for local development.
Signed-off-by: Innei <tukon479@gmail.com>
* optimize perf
* optimize perf
* optimize perf
* remove speedy plugin
* add dayjs vendor
* Revert "remove speedy plugin"
This reverts commit bf986afeb1.
---------
Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
* chore: align agent rename usage with agent profile editor
* fix: agent content emoji picker popupProps
* chore: agent and agent group use emoji background color in session list
* chore: remove fixed popupProps
* fix: user select problem
* feat: add back model config button
* chore: refact model detail props
* chore: add model detail loading
* chore: adjust dropdown side offset
* 🐛 fix: correct eslint command syntax in lint-ts.sh script
* ✨ feat: add scroll functionality for active model in List component
* ✨ feat: improve scroll behavior for active model in List component
🐛 fix(docker): hoist @napi-rs/canvas for PDF parsing in Docker
Add `@napi-rs/canvas-*` to public-hoist-pattern in .npmrc to fix
`DOMMatrix is not defined` error when parsing PDFs in Docker.
## Summary
Merge latest changes from main into canary.
## Changes
- Merge branch main into canary via
codex/merge-main-into-canary-20260221
- Resolve one merge conflict in packages/model-bank/src/types/aiModel.ts
by keeping both ModelParamsSchema and VideoModelParamsSchema imports
## Summary by Sourcery
Update NVIDIA provider to support preserved thinking and
reasoning_content for new reasoning-capable chat models and bump package
version.
New Features:
- Add NVIDIA chat model entries for MiniMax-M2.1, DeepSeek V3.2,
GLM-4.7, GLM-5, and Kimi K2.5 with reasoning support.
Enhancements:
- Extend NVIDIA runtime payload handling to map reasoning to
reasoning_content and to translate thinking into either thinking or
enable_thinking/clear_thinking depending on model capabilities.
- Refine NVIDIA provider tests to cover GLM preserved thinking behavior
and reasoning_content conversion across models.
Build:
- Bump package version from 2.1.31 to 2.1.32.
Only 4 checkouts truly need full git history (tag operations, branch sync).
The remaining 18 occurrences were used in build/lint/test jobs that only
need the current commit. Also removed redundant fetch-tags: true where
fetch-depth: 0 already implies full tag fetch.
* ✨ feat(nvidia): add interleaved thinking support with new reasoning models
- Add MiniMax-M2.1, DeepSeek V3.2, GLM-4.7, GLM-5, Kimi K2.5 to NVIDIA model bank
- Add reasoning conversion for interleaved thinking mode
- Add tests for GLM-5 and DeepSeek V3.2 thinking
* ♻️ refactor(nvidia): simplify payload handling logic
- Remove redundant THINKING_MODELS and INTERLEAVED_THINKING_MODELS sets
- Apply reasoning -> reasoning_content conversion for all NVIDIA models
- Apply thinking -> chat_template_kwargs conversion based on user input only
- Let API decide if model supports the parameters instead of client-side filtering
* ♻️ refactor(nvidia): add preserved thinking support with model-specific params
contentBlocksToString() was prepending APP_URL via urlJoin() to item.data,
but item.data already contained the full URL after processContentBlocks()
uploaded to S3. This caused URLs like:
https://example.com/https://example.com/f/uuid
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
#### 💻 Change Type
<!-- For change type, change [ ] to [x]. -->
- [ ] ✨ feat
- [ ] 🐛 fix
- [ ] ♻️ refactor
- [X] 💄 style
- [ ] 👷 build
- [ ] ⚡️ perf
- [ ] ✅ test
- [ ] 📝 docs
- [ ] 🔨 chore
#### 🔗 Related Issue
Closes#10346
<!-- Link to the issue that is fixed by this PR -->
<!-- Example: Fixes #xxx, Closes #xxx, Related to #xxx -->
#### 🔀 Description of Change
1. 更新的文生图,图生图模型列表,`z-image` `wan2.5` `wan2.6` `qwen-image-plus/max`
`qwen-image-edit-plus/max`
2. 新增 `image2image` endpoint,为老版本图生图模型进行兼容
3. 默认使用 `multimodal-generation` endpoint(新模型目前调研下来都是用这个了,同时支持图生图和文生图)
4. 支持多区域 Dashscope URL,跟随 baseUrl 参数,自动切分 `/compatible-mode/v1` 默认北京区域
北京 https://dashscope.aliyuncs.com
新加坡 https://dashscope-intl.aliyuncs.com
弗吉尼亚 https://dashscope-us.aliyuncs.com
|Endpoint||
|-|-|
|`multimodal-generation`|<img width="826" height="547" alt="image"
src="https://github.com/user-attachments/assets/38206851-94bc-48cc-8a57-24ed7155782f"
/><img width="521" height="383" alt="image"
src="https://github.com/user-attachments/assets/40fe0ed0-35fd-443d-868f-3ae2c27352f9"
/><img width="681" height="557" alt="image"
src="https://github.com/user-attachments/assets/8101b0f1-81c8-4892-a6e2-b51b5b0e0235"
/>|
|`text2image`|<img width="600" height="564" alt="image"
src="https://github.com/user-attachments/assets/39e82a4f-5305-4f30-ae4d-e5339f401e6d"
/>|
<!-- Thank you for your Pull Request. Please provide a description
above. -->
#### 🧪 How to Test
<!-- Please describe how you tested your changes -->
<!-- For AI features, please include test prompts or scenarios -->
- [ ] Tested locally
- [ ] Added/updated tests
- [ ] No tests needed
#### 📸 Screenshots / Videos
<!-- If this PR includes UI changes, please provide screenshots or
videos -->
| Before | After |
| ------ | ----- |
| ... | ... |
#### 📝 Additional Information
ref: https://help.aliyun.com/zh/model-studio/newly-released-models
ref:
https://bailian.console.aliyun.com/cn-beijing/?tab=doc#/doc/?type=model&url=2987148
<!-- Add any other context about the Pull Request here. -->
<!-- Breaking changes? Migration guide? Performance impact? -->
## Summary by Sourcery
Extend Qwen image generation support to cover new text-to-image and
image-to-image models while routing legacy models via dedicated
text2image/image2image endpoints and defaulting other models to the
multimodal-generation API.
New Features:
- Add model metadata and configuration for new Qwen image models
including Z-Image Turbo, Qwen Image Edit Max/Plus, Qwen Image Max/Plus,
and Wanxiang 2.5/2.6 variants.
- Introduce explicit handling of legacy text-to-image and image-to-image
Qwen models via separate async text2image and image2image endpoints.
Enhancements:
- Update the Qwen image creation flow to prefer the
multimodal-generation endpoint for newer models and improve error
messaging and logging across image workflows.
- Reformat select Qwen chat model descriptions for consistency without
changing behavior.
Tests:
- Adjust Qwen image creation tests to align with the new
multimodal-generation behavior and removed strict input validation on
qwen-image-edit-specific image URL requirements.
- Add gemini-3.1-pro-preview to Google, Vertex AI, and LobeHub providers
- Add thinkingLevel3 extend param type (low/medium/high)
- Create ThinkingLevel3Slider component for 3-level thinking control
- Fix thinkingLevel2/3 not passing values to API due to form field name mismatch
- Add medium to GoogleThinkingLevel and ChatStreamPayload thinkingLevel types
- Update planCardModels to use gemini-3.1-pro-preview
* 🌐 chore: translate non-English comments to English in src/libs
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* 🐛 fix: update test to match translated error message
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: arvinxx <arvinx@foxmail.com>
feat: support switch dashscope URL based on baseURL
feat: support switch dashscope URL based on baseURL
feat: support switch dashscope URL based on baseURL
* ♻️ refactor: replace per-item Editing components with singleton EditingPopover
Eliminate 3 duplicate Editing components (AgentItem, AgentGroupItem, Group)
in favor of a single imperative EditingPopover using @lobehub/ui Popover atoms.
Anchor elements are passed via React state (useState + callback ref) instead
of DOM queries. Removes agentRenamingId/groupRenamingId from homeStore.
* fix: edit group agent avaar
Signed-off-by: Innei <tukon479@gmail.com>
* ✅ test(e2e): update rename popover selectors and allow console in tests
Support both antd Popover and @lobehub/ui Popover atoms selectors.
Use save button click instead of click-outside for non-Enter rename flow.
Disable no-console rule for e2e and test files.
* ✅ test(e2e): fix rename popover input detection with data-testid
Add data-testid="editing-popover" to PopoverPopup. Simplify inputNewName
to use single combined selector instead of sequential try-catch loop that
caused 8s+ timeout. Support both @lobehub/ui and antd Popover.
---------
Signed-off-by: Innei <tukon479@gmail.com>
Change canary version format from X.(Y+1).0-canary.TIMESTAMP to
X.Y.(Z+1)-canary.N with auto-incrementing sequence. Also add
release prefix as build trigger and update sync PR titles.
Allow desktop app users to see and toggle the "Fetch on Client" option
in provider settings. The server-side default values for desktop remain
unchanged, so this only affects UI visibility.
* 🐛 fix: scroll ChatInput into view when starter mode activates
When clicking Create Agent/Group/Write, the SuggestQuestions panel
renders below the ChatInput and pushes total content beyond the
viewport, causing the ChatInput to scroll out of view. This adds
scrollIntoView + focus on mode change so the editor stays visible
and ready for input. Also improves E2E test to target contenteditable
inside ChatInput directly and wait for animation to settle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* update
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary
- Pass latency (task submission → webhook callback) to
`chargeAfterGenerate` for video generation metrics
- Use `batch.config` instead of webhook `result` for
`computePriceParams` (generateAudio), ensuring pricing uses
user-submitted config
- Rename `generateAudio` top-level param to `computePriceParams: {
generateAudio }` for better structure
## Test plan
- [ ] Submit a video generation task with generateAudio enabled, verify
charge uses correct pricing
- [ ] Submit a video generation task with generateAudio disabled, verify
charge reflects the difference
- [ ] Verify latency is recorded in the charge metrics
## Summary by Sourcery
Adjust video generation charging and metadata to rely on batch config
and record end-to-end latency.
Bug Fixes:
- Ensure generateAudio pricing uses the original batch configuration
instead of the webhook result payload.
Enhancements:
- Pass task submission-to-webhook latency into video charging for
improved metrics.
- Rename chargeAfterGenerate pricing input to computePriceParams for
clearer structure and future extensibility.
- Name generated video files using the batch prompt prefix when
available to improve asset identification.
Tests:
- Add unit tests for the Volcengine video provider request/response
handling, including payload mapping, client config, and error cases.
- Add initial test scaffolding for video standard parameters, cost
computation, single-price resolution, and Volcengine video webhook
handling.
Automatic sync from main to canary. Merge conflicts detected.
**Resolution steps:**
```bash
git fetch origin
git checkout sync/main-to-canary-20260214-22020422229
git merge origin/main
# Resolve conflicts
git add -A && git commit
git push
```
> Do NOT merge canary into a main-based branch — always merge main INTO
the canary-based branch to keep a clean commit graph.
- Added concurrency control to prevent overlapping sync jobs.
- Improved logic for detecting changes between main and canary branches.
- Streamlined handling of fast-forward merges and conflict resolution.
- Updated PR creation process for manual conflict resolution with detailed instructions.
Signed-off-by: Innei <tukon479@gmail.com>
## Summary
- Fix bidirectional sync race condition in `TopicUrlSync` where stale
`activeGenerationTopicId` from zustand store overwrites the URL when
navigating back to image/video pages without a `?topic=` param
- Replace `createStoreUpdater` (useEffect-based) with `useLayoutEffect`
for URL → store sync, ensuring it runs before the store → URL
subscription
- Generate latest i18n locales
## Test plan
- [ ] Visit `/video?topic=<id>`, navigate to home, click `/video` —
topic should not persist
- [ ] Visit `/image?topic=<id>`, navigate to home, click `/image` —
topic should not persist
- [ ] Click a topic in the sidebar — URL should update with
`?topic=<id>`
- [ ] Refresh page with `?topic=<id>` — correct topic should be selected
## Summary by Sourcery
Fix URL and store synchronization for generation topics and refresh
localized video page translations.
Bug Fixes:
- Prevent stale activeGenerationTopicId values in the store from
overwriting the URL when remounting image or video pages without a topic
query parameter.
Documentation:
- Regenerate and update i18n locale JSON files across all supported
languages, including new video translation files.
## Summary
- Add complete video generation feature including UI pages, store
management, server routes, and webhook handling
- Support Volcengine video generation provider with text-to-video and
image-to-video capabilities
- Add video generation topic management, config panel, generation feed,
and prompt input components
- Include database migration for video generation schema
- Refactor GenerationTopicList/TopicPanel as shared components for both
image and video generation
## Test plan
- [ ] Verify video generation page renders correctly
- [ ] Test text-to-video generation flow end-to-end
- [ ] Test image-to-video generation with reference frames
- [ ] Verify video generation topic CRUD operations
- [ ] Confirm webhook handling for async video generation results
- [ ] Check video generation config panel model selection and parameter
controls
The GITHUB_TOKEN cannot push changes to .github/workflows/ files due to
GitHub's security restrictions. The 'workflows' permission key added in
the previous commit is not a valid workflow permission scope.
Fix: Use secrets.GH_TOKEN (PAT with workflow scope) in the checkout step
so that git push has the necessary credentials to push branches that
contain workflow file changes (e.g. from merge conflicts).
Also reverts the invalid 'workflows: write' permission.
When merge conflicts involve .github/workflows/ files, GitHub requires
the `workflows: write` permission to push branches containing workflow
file changes. Without this permission, the sync branch push is rejected
with 'refusing to allow a GitHub App to create or update workflow without
workflows permission'.
- Reject webhook requests when token is missing instead of skipping verification
- Use proper union type for generation assets instead of blanket VideoGenerationAsset cast
- Replace sync js-sha256 with Node.js crypto.createHash for video hashing
- Add 500MB size limit and 5-minute timeout for video downloads
- Add displayName to VideoLoading component
Generate a one-time crypto-random token per video task, store it in
asyncTask metadata, and append it to the callback URL. The webhook
endpoint verifies the token using timing-safe comparison before
processing, returning 401 on mismatch. Old tasks without a token
are allowed through for backward compatibility.
- Make AsyncTaskModel.findByInferenceId static to avoid empty userId
- Extract GenerationTopicType for type-safe topic type narrowing
- Hoist batch query to eliminate duplicate DB call in webhook handler
- Add missing i18n keys for video error actions and status
- Fix comment accuracy in generationBatch deletion
- Add videoGeneration to PricingGroup maps to fix TS2741 type errors
- Collect url and coverUrl in addition to thumbnailUrl when deleting topics/batches
- Fix createTopic test assertion to match new optional type parameter
* ✨ chore: enhance release workflow to include conditional release body handling
- Added environment variable `RELEASE_BODY` to capture release notes from the GitHub event.
- Updated the workflow to use this variable, ensuring proper handling of release body content during manual dispatch events.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: simplify GitHub release workflow by removing hotfix-specific logic
- Consolidated the GitHub release creation step to handle both regular and hotfix releases under a single condition.
- Removed the separate hotfix release creation step to streamline the workflow.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ fix: replace UserPanel popover
- Introduced `PanelContentSkeleton` for better user experience during loading states in the UserPanel.
- Updated `UserPanel` to use the new skeleton and adjusted popover content handling.
- Refactored `PanelContent` to use `FC` type for better type safety.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: bump @lobehub/ui dependency to version 4.38.1
- Updated the @lobehub/ui package to the latest version for improved features and bug fixes.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 refactor: remove inset prop from Popover in UserPanel
- Cleaned up the Popover component in UserPanel by removing the unnecessary inset prop for improved clarity and maintainability.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
## 🩹 Hotfix v2.1.29
This PR starts a hotfix release from `main`.
### Release Process
1. ✅ Hotfix branch created from main
2. ✅ Pushed to remote
3. 🔄 Waiting for PR review and merge
4. ⏳ Auto tag + GitHub Release will be created after merge
---
Created by hotfix script
## Summary by Sourcery
Improve main-to-canary sync workflow robustness and tighten hotfix
auto-tagging criteria for release automation.
Enhancements:
- Make the main-to-canary sync workflow attempt direct merges to canary,
falling back to PR creation only when necessary or when conflicts occur,
and handle existing sync PRs more gracefully.
- Refine hotfix detection in the auto-tag workflow by requiring both a
hotfix branch prefix and a valid conventional commit-style PR title
prefix before tagging.
- Update the @lobehub/ui dependency to the latest patch version.
Build:
- Adjust release auto-tag workflow logic to gate hotfix tagging by both
branch naming and PR title format.
CI:
- Enhance GitHub Actions workflow for syncing main to canary with
conflict handling, direct-push optimization, and automated PR
management.
* ✨ feat(desktop): integrate electron-liquid-glass for macOS Tahoe
Add native liquid glass visual effect on macOS 26+ (Tahoe), replacing
vibrancy with Apple's NSGlassEffectView API via electron-liquid-glass.
- Centralize all platform visual effects in WindowThemeManager
- Strip platform props from BrowserWindow options to prevent config leaking
- Remove vibrancy from appBrowsers/WindowTemplate (managed by ThemeManager)
- Add isMacTahoe detection in env.ts and preload
- Fix applyVisualEffects to handle macOS platform symmetrically
* fix(tests): add isMacTahoe detection in Browser test environment
Introduce isMacTahoe flag in the test environment to support macOS Tahoe-specific features. This change enhances the test suite's ability to simulate and validate platform-specific behavior.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(theme): update liquid glass variant and adjust background color mix for desktop themes
- Changed liquid glass variant from 2 to 15 for improved visual effects.
- Adjusted background color mix percentages for dark and light themes on desktop to enhance visual consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(theme): adjust background color mix for dark theme on desktop
- Updated the background color mix percentage for the dark theme on desktop from 70% to 90% for improved visual effect consistency.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
Automatic sync
## Summary by Sourcery
Extend database schemas and migrations to support async task inference
tracking and typed generation topics.
New Features:
- Add an inferenceId field to async tasks with a dedicated index for
lookup by inference ID.
- Add a typed generation topic field to distinguish between image and
video topics with a default of image.
Enhancements:
- Update database schema metadata and documentation snapshots to reflect
the new async task and generation topic fields.
Tests:
- Adjust async task and generation topic tests to cover the new
inferenceId and topic type fields.
## Summary
- Optimize the main-to-canary sync workflow to directly merge and push
when there are no conflicts, avoiding unnecessary PR creation
- When merge conflicts exist, fall back to creating a PR for manual
resolution
- Add duplicate PR detection to prevent multiple PRs on the same day
## Test plan
- [ ] Push to main with no conflicts on canary → should auto-merge
without PR
- [ ] Push to main with conflicts on canary → should create PR
- [ ] Trigger workflow twice on same day with conflicts → should not
create duplicate PRs
## Summary by Sourcery
CI:
- Update the sync-main-to-canary workflow to merge main into canary
directly on no-conflict updates, only creating a PR when merge conflicts
occur and avoiding duplicate PRs for the same sync date.
* 🔧 ci: add commit prefix gate for hotfix auto-tag
* 🔧 chore: update ESLint suppressions and dependencies
- Added new ESLint suppressions for various files to address linting issues, including `no-console` and `object-shorthand`.
- Updated ESLint version to 10.0.0 in both root and desktop package.json files.
- Adjusted linting scripts for improved performance and consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: add ESLint support for YAML files in package.json
- Included ESLint fix command for YAML files (*.yml, *.yaml) in the linting scripts section.
- Ensured consistent formatting by adding a newline at the end of the file.
This update enhances linting capabilities for YAML configuration files.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: remove ESLint configuration file
- Deleted the .eslintrc.js file, which contained custom ESLint rules and overrides.
- This change simplifies the project by relying on default ESLint configurations.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
- Add handleShowOpenDialog and handlePickFile IPC methods for Electron
- Create useImageUpload hook for editor image upload with progress
- Refactor ReactImagePlugin config to support handleUpload and onPickFile
- Simplify slash command image insertion by delegating upload to plugin
- Upgrade @lobehub/editor to ^3.16.1
🔧 build: add canary desktop release workflow and channel support
Add automated canary build pipeline triggered by build/fix/style commits
on canary branch, with concurrency control to cancel stale builds.
* add
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: enhance ChatInput with customizable action bar properties
- Added `actionSize` to `ActionBarContextValue` for flexible action sizing.
- Updated `Action` component to utilize `actionSize` for dynamic sizing.
- Introduced `actionBarStyle` and `leftContent` props in `DesktopChatInput` for custom styling and content.
- Enhanced `SendButton` to accept size from `sendButtonProps`.
- Updated `ChatInput` to support new props for improved layout customization.
- Refactored `Conversation` component to implement compact action bar style and size.
This update improves the flexibility and customization of the ChatInput feature, allowing for better user experience.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: enhance NavHeader and Copilot Toolbar with layout improvements
- Added `allowShrink` property to Flexbox components in NavHeader for better responsiveness.
- Updated Text component in Copilot Toolbar to include tooltip support for ellipsis overflow, improving user experience.
These changes enhance the layout flexibility and visual consistency across the application.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: update Conversation and AgentSelectorAction components for improved styling
- Adjusted padding in the compact action bar style for better alignment.
- Enhanced AgentSelectorAction styles with additional border radius for a refined look.
- Simplified title translation in AgentSelectorAction for consistency.
These changes enhance the visual appeal and maintainability of the components within the Copilot feature.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: update ModelSwitchPanel to improve DropdownMenuPositioner prop usage
- Changed the `hoverTrigger` prop in `DropdownMenuPositioner` from a boolean to a destructured assignment for better clarity and consistency in the component's API.
This update enhances the readability and maintainability of the ModelSwitchPanel component.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
Skip duplicate check only applies to development branches now.
Main and canary branches will always execute E2E tests on every commit.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* 🐛 fix: improve GitHub Copilot auth retry logic
Simplify auth refresh tracking from counter to boolean flag and clear
cached bearer token on 401 to ensure fresh token exchange.
* 🔧 fix: update package.json formatting and import statements in GitHub Copilot provider
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix: refine GitHub Copilot auth refresh logic to check for exchange credential
Update the 401 error handling to refresh the token only if an exchange credential is available, improving the authentication flow.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore(release): bump version to v2.1.27 [skip ci]
* chore: update sync main to canary workflow
* 🐛 fix: update @lobehub/ui version and refactor dynamic import handling (#12260)
* ✨ feat: add hotfix workflow and script for automated hotfix management
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 fix: refactor PR creation command to use execFileSync for improved reliability
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @lobehub/ui version and refactor dynamic import handling
- Bump @lobehub/ui dependency from ^4.35.0 to ^4.36.2 in package.json.
- Refactor settingsContentToStatic.mts to simplify dynamic import processing by removing business feature checks.
- Add initialize.ts to enable immer's map set functionality.
- Correct import path in layout.tsx from 'initiallize' to 'initialize'.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @types/react version in package.json
- Bump @types/react dependency from ^19.2.9 to 19.2.14.
- Add @types/react version to overrides section for consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: enhance auto-tag-release workflow for strict semver validation
- Updated regex to match strict semantic versioning format, allowing for optional prerelease and build metadata.
- Added validation step to ensure the version is a valid semver before proceeding with the release process.
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove defaultSecurityBlacklist test file
- Deleted the test file for DEFAULT_SECURITY_BLACKLIST as it is no longer needed.
- This cleanup helps maintain a more streamlined test suite.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update localization files for multiple languages
- Improved translations in Arabic, Bulgarian, German, English, and Spanish for chat and tool-related strings.
- Enhanced descriptions for various parameters and added new keys for file handling and security warnings.
- Adjusted phrasing for clarity and consistency across languages.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update PR comment script to include Actions Artifacts link
- Modified the PR comment generation script to accept an additional artifactsUrl parameter.
- Updated the comment format to include both Release download and Actions Artifacts links for better accessibility.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 chore(hotfix): bump version to v2.1.28 [skip ci]
* chore: update secrets token
---------
Signed-off-by: Innei <tukon479@gmail.com>
Co-authored-by: rdmclin2 <rdmclin2@gmail.com>
Co-authored-by: Arvin Xu <arvinx@foxmail.com>
Co-authored-by: Innei <i@innei.in>
* ✨ feat: add hotfix workflow and script for automated hotfix management
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 fix: refactor PR creation command to use execFileSync for improved reliability
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @lobehub/ui version and refactor dynamic import handling
- Bump @lobehub/ui dependency from ^4.35.0 to ^4.36.2 in package.json.
- Refactor settingsContentToStatic.mts to simplify dynamic import processing by removing business feature checks.
- Add initialize.ts to enable immer's map set functionality.
- Correct import path in layout.tsx from 'initiallize' to 'initialize'.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update @types/react version in package.json
- Bump @types/react dependency from ^19.2.9 to 19.2.14.
- Add @types/react version to overrides section for consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: enhance auto-tag-release workflow for strict semver validation
- Updated regex to match strict semantic versioning format, allowing for optional prerelease and build metadata.
- Added validation step to ensure the version is a valid semver before proceeding with the release process.
Signed-off-by: Innei <tukon479@gmail.com>
* 🗑️ chore: remove defaultSecurityBlacklist test file
- Deleted the test file for DEFAULT_SECURITY_BLACKLIST as it is no longer needed.
- This cleanup helps maintain a more streamlined test suite.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update localization files for multiple languages
- Improved translations in Arabic, Bulgarian, German, English, and Spanish for chat and tool-related strings.
- Enhanced descriptions for various parameters and added new keys for file handling and security warnings.
- Adjusted phrasing for clarity and consistency across languages.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: update PR comment script to include Actions Artifacts link
- Modified the PR comment generation script to accept an additional artifactsUrl parameter.
- Updated the comment format to include both Release download and Actions Artifacts links for better accessibility.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
#### 💻 Change Type
<!-- For change type, change [ ] to [x]. -->
- [ ] ✨ feat
- [ ] 🐛 fix
- [ ] ♻️ refactor
- [ ] 💄 style
- [ ] 👷 build
- [ ] ⚡️ perf
- [ ] ✅ test
- [ ] 📝 docs
- [x] 🔨 chore
#### 🔗 Related Issue
<!-- Link to the issue that is fixed by this PR -->
<!-- Example: Fixes #xxx, Closes #xxx, Related to #xxx -->
#### 🔀 Description of Change
<!-- Thank you for your Pull Request. Please provide a description
above. -->
#### 🧪 How to Test
<!-- Please describe how you tested your changes -->
<!-- For AI features, please include test prompts or scenarios -->
- [ ] Tested locally
- [ ] Added/updated tests
- [ ] No tests needed
#### 📸 Screenshots / Videos
<!-- If this PR includes UI changes, please provide screenshots or
videos -->
| Before | After |
| ------ | ----- |
| ... | ... |
#### 📝 Additional Information
<!-- Add any other context about the Pull Request here. -->
<!-- Breaking changes? Migration guide? Performance impact? -->
## Summary by Sourcery
CI:
- Introduce a new sync-main-to-canary GitHub Actions workflow that
creates an automatic PR from main to canary on pushes to main and remove
the previous sync-main-to-dev workflow.
## 📦 Release v2.1.27
This branch contains changes for the upcoming v2.1.27 release.
### Change Type
- Checked out from dev branch and merged to main branch
### Release Process
1. ✅ Release branch created
2. ✅ Pushed to remote
3. 🔄 Waiting for PR review and merge
4. ⏳ Release workflow triggered after merge
---
Created by release script
🐛 fix: correct import path for defaultSecurityBlacklist in test
The import path was pointing to `../defaultSecurityBlacklist` (core/) but
the file was moved to `../../audit/defaultSecurityBlacklist` during a
prior refactor. The broken import was lost during a rebase conflict
resolution, causing 8 cascading TS errors.
* 🐛 fix: filter stdio MCP tools on web environment
Prevent stdio-based MCP tools (desktop-only) from being injected into agent
conversations on web platforms. Stdio transport requires Electron IPC which
is unavailable on web, causing runtime errors. Added environment-aware
filtering in createAgentToolsEngine enableChecker with comprehensive tests.
* 🐛 fix: filter stdio MCP tools on web environment
- Simplify serverExternalPackages config with nullish coalescing
- Filter out stdio MCP plugins in non-desktop environments since stdio transport requires Electron IPC
- Use Electron's setWindowOpenHandler in Browser.ts to intercept external links
- Remove window.open override from preload script
- Remove pushState/replaceState interception as no longer needed
- Update tests to reflect changes
This moves external link handling to the main process for better security
and simplifies the preload script.
- Changed type import for ReactNode to a more concise syntax.
- Removed unnecessary blur effects from motion variants to streamline animations.
- Updated AnimatePresence mode from 'popLayout' to 'sync' for improved transition handling.
Signed-off-by: Innei <tukon479@gmail.com>
Role-based menu items have their accelerators handled by Electron runtime, so tests should verify the role property rather than an explicit accelerator value.
- Schedule daily at 14:00 UTC+8, with manual dispatch support
- Version: latest stable tag minor+1 (e.g., 2.0.12 → 2.1.0-nightly.YYYYMMDDHHMM)
- Skip build when no code changes in package.json, src/, packages/, apps/desktop/
- Support force build option to bypass diff check
- Auto cleanup old nightly releases (keep 7)
- Exclude nightly from beta workflow to prevent duplicate builds
- Remove next channel from beta workflow
Electron's role-based menu items already provide default accelerators.
Explicitly setting them can override defaults and cause issues like
Ctrl+Plus (requiring Shift) not working for zoom in on Windows.
Only kept intentional overrides: F12 for devTools, F11 for fullscreen
on macOS, Alt+F4 for close and Ctrl+Y for redo on Windows.
- Changed border style in ServerVersionOutdatedAlert component for improved visual consistency.
- Commented out the check for server version status and storage mode, setting a default value for isServerVersionOutdated to true for testing purposes.
This update enhances the alert's appearance and temporarily modifies its logic for development.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(desktop): implement subscription pages embedding with webview
- Add SubscriptionIframeWrapper component for embedding subscription pages in Electron webview
- Replace compile-time ENABLE_BUSINESS_FEATURES with runtime serverConfigSelectors
- Add useIsCloudActive hook to detect cloud sync status
- Add setupSubscriptionWebviewSession service for webview session management
Resolves LOBE-4589
* ✨ feat: enhance SubscriptionIframeWrapper for improved configuration
- Updated iframe URL to use OFFICIAL_URL for better maintainability.
- Integrated server configuration to conditionally enable business features.
- Cleaned up code by removing commented-out lines and unnecessary eslint suppressions.
This update improves the flexibility and readability of the SubscriptionIframeWrapper component.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat: enhance link interception in SubscriptionIframeWrapper
- Updated the script to intercept both link clicks and window.open calls for better URL handling.
- Added functionality to resolve relative URLs to absolute before logging.
This improvement enhances the tracking of external link interactions within the iframe.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔧 chore: clean up useIsCloudActive hook
- Removed unnecessary eslint suppressions related to react-hooks rules.
- Improved code readability by eliminating commented-out lines.
This update enhances the clarity and maintainability of the useIsCloudActive hook.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* v2 init
* chore: update eslint suppressions and package dependencies
- Removed several eslint suppressions related to array sorting and reversing from eslint-suppressions.json to clean up the configuration.
- Updated @lobehub/lint package version from 2.0.0-beta.6 to 2.0.0-beta.7 in package.json for improvements and bug fixes.
- Made minor formatting adjustments in vitest.config.mts and various SKILL.md files for better readability and consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: clean up import statements and formatting
- Removed unnecessary whitespace in replaceComponentImports.ts for improved readability.
- Standardized import statements in contextEngineering.ts and createAgentExecutors.ts by adding missing spaces for consistency.
Signed-off-by: Innei <tukon479@gmail.com>
* chore: update eslint suppressions and clean up code formatting
* 🐛 fix: use vi.hoisted for mock variable initialization
Fix TDZ error in persona service test by using vi.hoisted() to ensure
mock variables are available when vi.mock factory runs.
---------
Signed-off-by: Innei <tukon479@gmail.com>
resolves LOBE-4515
- Bump @lobehub/ui dependency from ^4.33.0 to ^4.33.4 for improvements and bug fixes.
- Add min-width style to the container in UpdateAgentPromptInspector for better layout.
- Implement ellipsis with tooltip for agent title to handle overflow gracefully.
- Adjust length diff display to prevent text wrapping.
Signed-off-by: Innei <tukon479@gmail.com>
- Introduced new settings for enabling auto-scroll during AI responses in both English and Chinese locales.
- Updated chat configuration and user settings to include `enableAutoScrollOnStreaming`.
- Enhanced the UI to allow users to toggle this feature in the agent settings.
- Refactored auto-scroll logic to respect user preferences and agent-specific settings.
This feature improves user experience by ensuring that the latest AI responses are always visible during streaming.
Signed-off-by: Innei <tukon479@gmail.com>
- Remove duplicate AddTopicButon.tsx files from agent and group layouts
- Refactor migrate-spa-navigation.ts to use switch statement for better readability
- Clean up unused imports in migration script
* ✨ feat(store): introduce StoreSetter interface and refactor agent group actions
- Added StoreSetter interface to manage state updates in a more flexible manner.
- Refactored ChatGroupInternalAction, ChatGroupCurdAction, and ChatGroupMemberAction to utilize the new StoreSetter for state management.
- Enhanced action methods to improve clarity and maintainability.
- Introduced createActionProxy utility to streamline action handling across slices.
- Updated lifecycle and member slices to align with the new structure, ensuring consistent state management practices.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor squash
refactor: replace createActionProxy with flattenActions for action handling
- Updated multiple store files to utilize flattenActions instead of createActionProxy, improving the handling of action methods and ensuring proper prototype method binding.
- Removed createActionProxy utility as it is no longer needed, streamlining the action management process across the application.
This change enhances maintainability and consistency in state management practices.
Signed-off-by: Innei <tukon479@gmail.com>
chore: format code
Signed-off-by: Innei <tukon479@gmail.com>
fix: correct assignment syntax in GroupChatSupervisor and ResourceSyncEngine
- Updated assignment syntax from object-like notation to standard assignment for error handling and state updates in GroupChatSupervisor and ResourceSyncEngine classes.
- Ensured proper variable assignments for error handling and state management, enhancing code clarity and functionality.
Signed-off-by: Innei <tukon479@gmail.com>
fix: update transformApiArgumentsToAiState return type and logic
- Changed the return type of transformApiArgumentsToAiState from Promise<string> to Promise<string | undefined> to better reflect possible outcomes.
- Modified the return statement to return undefined instead of an empty string when the builtinToolLoading for the given key is true, improving clarity in the function's behavior.
Signed-off-by: Innei <tukon479@gmail.com>
* feat(upload): enhance uploadBase64FileWithProgress return type and add dimensions
- Introduced a new interface, UploadWithProgressResult, to define the structure of the result returned by uploadBase64FileWithProgress.
- Updated the return type of uploadBase64FileWithProgress and uploadFileWithProgress methods to reflect the new interface, improving type safety and clarity.
- This change allows for better handling of image dimensions and file metadata during the upload process.
Signed-off-by: Innei <tukon479@gmail.com>
* refactor(zustand): migrate to class-based actions and enhance action composition
- Updated the implementation of actions from plain StateCreator objects to class-based actions, improving encapsulation and maintainability.
- Introduced a new pattern for defining actions using private fields to prevent internal state leakage.
- Replaced createActionProxy with flattenActions for better method binding and prototype support in action handling.
- Enhanced the structure for multi-class slices, allowing for cleaner composition of actions within store files.
This refactor streamlines state management practices and improves code clarity across the application.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
- Remove unused success state and related conditional rendering in UpdateIdentityMemoryInspector
- Simplify rendering logic for better readability
- Add custom styles for ErrorResponse component to improve layout and presentation
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(skillStore): add "Want more skills?" prompt with feedback integration
- Add WantMoreSkills component below CommunityList
- Extend useFeedbackModal to support preset initial values
- Update FeedbackModal to accept and display initial form values
- Add i18n translations for zh-CN and en-US
Closes LOBE-4163
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* 🔧 fix(skillStore): show skill request prompt at list end instead of fixed footer
- Move WantMoreSkills to VirtuosoGrid Footer, shown only when list ends
- Update text to "已经到底了,未找到所需技能?提交申请 →"
- Use Typography.Link for hyperlink style on action text
- Update feedback form template with structured format
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix: initial values not set
* chore: remove skill install banner shadow
* chore: use same list height
* chore: update i18n files
* fix: klavis disconnected style
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
* ♻️ refactor(fileSearch): consolidate determineContentType to base class and use os.homedir()
- Move determineContentType method to FileSearchImpl base class with merged type mappings
- Replace process.env.HOME with os.homedir() in macOS and Linux implementations
- Replace process.env.USERPROFILE with os.homedir() in Windows implementation
- Remove duplicate implementation from three platform-specific classes
* refactor: content search service
* chore: add engine text
* fix: show engine
* test: add unit tests for contentSearch and fileSearch modules
- Add base.test.ts and index.test.ts for contentSearch module
- Add base.test.ts and index.test.ts for fileSearch module
- Test buildGrepArgs, determineContentType, escapeGlobPattern, etc.
- Test factory functions for platform-specific implementations
* 🐛 fix(contentSearch): use correct ripgrep glob patterns for nested path exclusion
Change `!node_modules` and `!.git` to `!**/node_modules/**` and `!**/.git/**`
to properly exclude nested directories as per ripgrep documentation.
* fix: types
- Refresh token on every app launch (with 5-minute debounce to prevent rapid restarts)
- Trigger refresh on Mac app activation (Dock click) with same debounce
- Track lastRefreshAt timestamp in encrypted token storage
- Add isRemoteServerConfigured() helper method to avoid code duplication
- Fix cloud mode check that incorrectly required remoteServerUrl
- Add comprehensive tests for all refresh scenarios
* feat: implement GitHub Copilot integration with OAuth Device Flow authentication
- Updated package.json to include new GitHub Copilot model.
- Added GitHub Copilot model provider and associated runtime logic.
- Implemented OAuth Device Flow for authentication, including UI components for user interaction.
- Enhanced AI provider settings to support OAuth configuration.
- Updated types and key vaults to accommodate GitHub Copilot tokens.
This integration allows users to authenticate via GitHub Copilot, enabling access to its models through a seamless OAuth experience.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: expand GitHub Copilot model definitions and add new models
- Updated existing models with new descriptions, display names, and IDs.
- Introduced several new models including GPT-5 mini, GPT-4o variants, Grok Code Fast 1, and Claude Haiku 4.5.
- Adjusted context window tokens and max output values for various models.
- Enhanced model capabilities with function call and vision abilities.
This update enriches the AI model offerings and improves the overall functionality of the GitHub Copilot integration.
Signed-off-by: Innei <tukon479@gmail.com>
* ✅ test: add unit tests for OAuth Device Flow and GitHub Copilot
- Add OAuthDeviceFlowService tests (12 tests)
- Add GithubCopilotOAuthService tests (13 tests)
- Add LobeGithubCopilotAI runtime tests (12 tests)
- Add updateConfig keyVaults merge tests (5 tests)
- Fix sleep import in githubCopilot runtime (use inline Promise)
* feat: enhance OAuth Device Flow integration and user experience
- Added new OAuth-related strings to localization files for English, Chinese, and default locales.
- Refactored ProviderConfig component to streamline OAuth authentication handling and improve UI presentation.
- Updated OAuthDeviceFlowAuth component to include user information display (username and avatar).
- Enhanced backend logic to fetch and store GitHub user information during OAuth authentication.
- Improved error handling and user feedback during the OAuth process.
This update significantly enhances the user experience for OAuth authentication, providing clearer communication and a more integrated interface.
Signed-off-by: Innei <tukon479@gmail.com>
* feat: improve OAuth provider handling in ProviderConfig and OAuthDeviceFlowAuth components
- Integrated OAuth authentication status querying in ProviderConfig to conditionally render the form based on authentication state.
- Refactored OAuthDeviceFlowAuth to enhance user experience during the authentication process, including better state management and UI updates.
- Ensured that the form is only displayed when the user is authenticated for OAuth providers.
This update streamlines the OAuth integration, providing a more responsive and user-friendly interface.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: update OpenAI model snapshots with new configurations
- Modified model definitions for GPT 3.5 Turbo and Embedding V2 Ada, including updated context window tokens, descriptions, and display names.
- Enabled function call capability for GPT 3.5 Turbo and changed the type for Embedding V2 Ada from "embedding" to "chat".
This update ensures the model snapshots reflect the latest configurations and capabilities.
Signed-off-by: Innei <tukon479@gmail.com>
* fix: correct casing in model-bank package.json and enhance aiProvider test
- Updated the casing of the GitHub Copilot model path in package.json for consistency.
- Added a call to KeyVaultsGateKeeper.getUserKeyVaults in the aiProvider test to improve test coverage and functionality.
This update ensures better adherence to naming conventions and enhances the robustness of the aiProvider tests.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(electron): refactor RecentlyViewed with Pinned + Recent architecture
- Add Pinned section for user-pinned pages (persisted to localStorage)
- Add Recent section with auto-deduplication and 20 items limit
- Support dynamic title updates (e.g., conversation names instead of generic "Chat")
- Add Pin/Unpin toggle on hover
- Keep navigation history (back/forward) independent from recent pages
Closes LOBE-4212
Closes LOBE-4230
* 📝 docs(linear): update issue management guidelines
- Revise description for clarity on triggering conditions for Linear issues.
- Add critical section on PR creation with Linear issues, emphasizing immediate comment requirements.
- Update completion comment format to include structured summary and key changes.
- Clarify workflow steps and correct examples for task completion and status updates.
Signed-off-by: Innei <tukon479@gmail.com>
* ✨ feat(electron): history stack
- Introduce a new plugin system for RecentlyViewed, allowing dynamic resolution of page references.
- Implement caching for display data, improving performance and user experience.
- Refactor existing page handling to support various page types (agents, groups, etc.) with dedicated plugins.
- Update Recent and Pinned pages management to utilize the new plugin system for better data integrity and retrieval.
Signed-off-by: Innei <tukon479@gmail.com>
---------
Signed-off-by: Innei <tukon479@gmail.com>
* chore: upgrade market sdk to 0.29.2
* feat: add skill recommendations to agent detail
* fix: agent link error
* feat: support agents using this skill
* feat: support agents using tool list virtual and load more
* chore: remove lobehub skill detail loading
* feat: mcp detail support load more
* fix: mcp detail in comunity scroll problem
* chore: update i18n files
* Added support for including native bindings in standalone output when building with Docker.
* Updated outputFileTracingIncludes to conditionally include necessary files for `@napi-rs/canvas` and pnpm package locations.
Signed-off-by: Innei <tukon479@gmail.com>
* Added createStaticStyles for styling the popup component
* Updated popupClassName to utilize the new styles
Signed-off-by: Innei <tukon479@gmail.com>
* feat: add write document and image create starter
* chore: update doc starter e2e tests
* chore: remove image stater form home input
* chore: move model header to actionbar extra place
* test: fix e2e test
- Add `overflow: auto` to ReadFileView component to fix content scrolling issue
- Update new topic creation to use current active agent instead of always navigating to inbox
Closes LOBE-4372
- Add DesktopFileMenuBridge component for native menu integration
- Update navigation events in electron-client-ipc
- Modify menu implementations across all platforms (Linux, macOS, Windows)
- Add hotkey settings for desktop features
- Update layout and menu creation hooks for desktop navigation
- Removed temporary workspace setup and dynamic import assertions for i18n codemod.
- Updated workflow to directly run the electron workflow modifiers script.
Signed-off-by: Innei <tukon479@gmail.com>
resolves LOBE-4449
- Introduced a new icon for the full-width view option using Maximize2 from lucide-react.
- Updated the useMenu hook in both agent and page editor headers to include the new full-width menu item.
Signed-off-by: Innei <tukon479@gmail.com>
* 🔨 chore(database): added id_nanoid to replace id using seq and identity
* 🔨 chore(database): assgin database id column value to id_nanoid
* 🔨 chore(database): update dbml
* 🔨 chore(database): add not null & unique index
* 🔨 chore(database): drop foreign key dependency, switch to depend on id_nanoid
* 🔨 chore(database): switch to use id_nanoid as primary key
* 🔨 chore(database): drop old id column
* 🔨 chore(database): rename id_nanoid to id
* 🔨 chore(database): remove unique constraint
* 🔨 chore(database): updated dbml
* 🔨 chore(database): incorrect --> statement-breakpoint
* 🐛 fix: use custom avatar for group chat in sidebar
When a group chat has a custom avatar set, the sidebar was always showing
the member composition avatar instead. This fix:
- Queries chatGroups.avatar and chatGroups.backgroundColor in HomeRepository
- Prioritizes custom avatar (string) over member avatars (array) in data layer
- Replaces GroupAvatar with AgentGroupAvatar in AgentGroupItem for proper
avatar type detection (custom vs member composition)
Closes LOBE-4883
* ✅ test: add DB tests for group chat custom avatar in sidebar
Add 6 test cases covering the custom avatar fix for chat groups:
getSidebarAgentList:
- should return custom avatar when chat group has one set
- should return member avatars when chat group has no custom avatar
- should prioritize custom avatar over member avatars
searchAgents:
- should return custom avatar for chat groups with custom avatar in search
- should return member avatars for chat groups without custom avatar in search
- should prioritize custom avatar over member avatars in search
* refactor Notebook Executor
* 🐛 fix: register Notebook tool in server runtime
Notebook tool (lobe-notebook) was only registered on the client side,
causing server-side tool calls to fail with "not implemented" error.
- Add NotebookRuntimeService wrapping DocumentModel/TopicDocumentModel
- Add notebook server runtime registration
- Pass context to runtime methods for topicId passthrough
- Add tests for NotebookRuntimeService and runtime registration
Resolves LOBE-4880
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* 🌐 chore: translate non-English comments to English in siliconcloud provider
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
* ✅ test: update siliconcloud test to match translated error message
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-authored-by: arvinxx <arvinx@foxmail.com>
Replace `overflow: 'hidden'` with `overflowX: 'hidden', overflowY: 'auto'`
on the topic list container so users can scroll through topics that exceed
the viewport height on mobile devices.
Closeslobehub/lobe-chat#12029
* fix: add Array.isArray() validation in favoriteTopic to prevent TypeError
Fixes#12072
The favoriteTopic function was using `if (!groups)` which only catches
null/undefined values. When SWR cache contains malformed data (objects,
strings, or other non-array types), the subsequent .map() call would
fail with "TypeError: h.map is not a function".
Changes:
- Replace `if (!groups)` with `if (!Array.isArray(groups))`
- Add defensive Array.isArray() check for group.topics before mapping
- Provide empty array fallback when group.topics is not an array
This ensures proper type validation and prevents runtime errors when
favoriting topics in group chat scenarios.
* test: add regression tests for favoriteTopic malformed cache handling
Add comprehensive regression tests for issue #12072 to verify that
favoriteTopic handles malformed SWR cache data without throwing TypeError:
- Test handling of non-array groups in cache (null, string, object, number)
- Test handling of groups with non-array topics field
- Test correct favorite state updates in well-formed cache
- Test no-op scenario when topic already has target state
These tests ensure the defensive Array.isArray() checks prevent
crashes when the SWR cache contains unexpected data structures.
* fix: correct regression test assertion for malformed groups
The test was incorrectly asserting that group.topics should be [] for
malformed entries. The actual behavior is correct: when no topic ID
matches, the function returns the original groups unchanged via
reference equality. The key regression being tested is that the function
doesn't throw a TypeError when encountering non-array topics.
* 🐛 fix: show notification when file upload fails due to storage plan limit
Previously, when file storage exceeded the plan limit, the TRPC
middleware threw a FORBIDDEN error that was silently swallowed by
the upload components with no user feedback. Now `uploadWithProgress`
catches this specific error and displays a notification guiding
users to upgrade or free up space.
* 🌐 chore: run i18n for upload storage limit error message
* 🌍 i18n: update model descriptions across multiple languages
Added new model descriptions and improved existing ones in Arabic, Bulgarian, German, French, Italian, Japanese, and Korean locales. This update enhances the clarity and detail of model capabilities, ensuring better user understanding and accessibility.
* 🔧 chore(vscode): add typescript.tsdk and disable mdx server
Fix MDX extension crash caused by Cursor's bundled TypeScript version
* 🔧 chore(claude): add skills symlink to .claude directory
* 📝 docs: update development guides with current tech stack and architecture
- Update tech stack: Next.js 16 + React 19, hybrid routing (App Router + React Router DOM), tRPC, Drizzle ORM + PostgreSQL, react-i18next
- Update directory structure to reflect monorepo layout (apps/, packages/, e2e/, locales/)
- Expand src/server/ with detailed subdirectory descriptions
- Add complete SPA routing architecture with desktop and mobile route tables
- Add tRPC router grouping details (lambda, async, tools, mobile)
- Add data flow diagram
- Simplify dev setup section to link to setup-development guide
- Fix i18n default language description (English, not Chinese)
- Sync all changes between zh-CN and English versions
* 📝 docs: expand data flow diagram in folder structure guide
Replace the single-line data flow with a detailed layer-by-layer
flow diagram showing each layer's location and responsibility.
* 📝 docs: modernize feature development guide
- Remove outdated clientDB/pglite/indexDB references
- Update schema path to packages/database/src/schemas/
- Update types path to packages/types/src/
- Replace inline migration steps with link to db-migrations guide
- Add complete layered architecture table (Client Service, WebAPI,
tRPC Router, Server Service, Server Module, Repository, DB Model)
- Clarify Client Service as frontend code
- Add i18n handling section with workflow and key naming convention
- Remove verbose CSS style code, keep core business logic only
- Expand testing section with commands, skill refs, and CI tip
* 🔥 docs: remove outdated frontend feature development guide
Content is superseded by the comprehensive feature-development guide
which covers the full chain from schema to testing.
* 📝 docs: add LobeHub ecosystem and community resources
Add official ecosystem packages (LobeUI, LobeIcons, LobeCharts,
LobeEditor, LobeTTS, LobeLint, Lobe i18n, MCP Mark) and community
platforms (Agent Market, MCP Market, YouTube, X, Discord).
* 📝 docs: improve contributing guidelines and resources
- Clarify semantic release triggers (feat/fix vs style/chore)
- Add testing section with Vitest/E2E/CI requirements
- Update contribution steps to include CI check
- Add LobeHub ecosystem packages and community platforms to resources
* 📝 docs: rewrite architecture guide to reflect current platform design
* 📝 docs: add code quality tools to architecture guide
* 📝 docs: rewrite chat-api guide to reflect current architecture
- Update sequence diagram with Agent Runtime loop as core execution engine
- Replace PluginGateway with ToolExecution layer (Builtin/MCP/Plugin)
- Update all path references (model-runtime, agent-runtime, fetch-sse packages)
- Split old AgentRuntime section into Model Runtime + Agent Runtime
- Add tool calling taxonomy: Builtin, MCP, and Plugin (deprecated)
- Add client-side vs server-side execution section
- Remove outdated adapter pseudo-code examples
* 📝 docs: update file paths in add-new-image-model guide
- src/libs/standard-parameters/ → packages/model-bank/src/standard-parameters/
- src/config/aiModels/ → packages/model-bank/src/aiModels/
- src/libs/model-runtime/ → packages/model-runtime/src/providers/
* 📝 docs: restore S3_PUBLIC_DOMAIN in deployment guides
The S3_PUBLIC_DOMAIN env var was incorrectly removed from all
documentation in commit 4a87b31. This variable is still required
by the code (src/server/services/file/impls/s3.ts) to generate
public URLs for uploaded files. Without it, image URLs sent to
vision models are just S3 keys instead of full URLs.
Closes#12161
* 📦 chore: pin @lobehub/ui to 4.33.4 to fix SortableList type errors
@lobehub/ui 4.34.0 introduced breaking type changes in SortableList
where SortableListItem became strict, causing type incompatibility
in onChange and renderItem callbacks across 6 files. Pin to 4.33.4
via pnpm overrides to enforce consistent version across monorepo.
* 🐛 fix: correct ReadableStream type annotations and add dom.asynciterable
- Add dom.asynciterable to tsconfig lib for ReadableStream async iteration
- Fix createCallbacksTransformer return type: TransformStream<string, Uint8Array>
- Update stream function return types from ReadableStream<string> to
ReadableStream<Uint8Array> (llama.ts, ollama.ts, claude.ts)
- Remove @ts-ignore from for-await loops in test files
- Add explicit string[] type for chunks arrays
* Revert "📝 docs: restore S3_PUBLIC_DOMAIN in deployment guides"
This reverts commit 24073f83d3.
* ✨ feat(model-runtime): add Claude Opus 4.6 support for Bedrock runtime
- Add Opus 4.6 to Bedrock and LobeHub hosted model banks with adaptive thinking and effort config
- Sync Bedrock runtime to support adaptive thinking (type: 'adaptive') and output_config.effort
- Strip assistant turn prefill for Opus 4.6 (not supported)
- Add missing search ability to Opus 4.5, Sonnet 4.5, Haiku 4.5 and 3.7 Sonnet in Bedrock
- Fix single-quote string escaping issues in Bedrock model descriptions
* 🐛 fix(model-runtime): clamp default thinking budget_tokens against max_tokens
* 🐛 fix(model-runtime): remove unnecessary 'as any' for adaptive thinking type
* 💄 style: update planCardModels to latest model lineup
* feat: add adaptive thinking and effort configuration for Claude Opus 4.6
* fix: update @anthropic-ai/sdk dependency and refine thinking type handling in payload
* fix: enhance payload handling for Claude Opus 4.6
* i18n
* fix: add the pending review tag in profile pages
* fix: add lost i18n files
* fix: add the pending review tag in group-agents profiles
* chore: update lost i18n files
* 🔥 chore(docker-compose): remove Casdoor SSO dependency
Casdoor is no longer needed since BetterAuth now supports email/password registration natively.
LOBE-3907
* ♻️ refactor(docker-compose): restructure directories
- Rename local/ to dev/ for development dependencies
- Remove logto/ and zitadel/ from production/
- Restore Casdoor config in production/grafana/
- Simplify dev/ to core services only (postgresql, redis, rustfs, searxng)
- Update docker-compose.development.yml to use dev/
- Remove minio-bucket.config.json (switched to rustfs)
* ♻️ refactor(docker-compose): simplify dev environment setup
- Remove docker-compose.development.yml, use dev/docker-compose.yml directly
- Add npm scripts: dev:docker, dev:docker:down, dev:docker:reset
- Simplify .env.example.development (remove variable refs, redundant vars)
- Update docker-compose/dev/.env.example (consistent passwords)
- Add docker-compose/dev/data/ to .gitignore
- Update setup docs: use npm scripts, remove image generation section
* 🔧 chore: add SSRF_ALLOW_PRIVATE_IP_ADDRESS to dev env example
* 🔒 security: auto-generate KEY_VAULTS_SECRET and AUTH_SECRET in setup.sh
- Remove hardcoded secrets from docker-compose.yml
- Add placeholders to .env.example files
- Generate secrets dynamically in setup.sh using openssl rand -base64 32
* 🔧 chore(docker-compose): expose SearXNG port and improve dev scripts
- Add SearXNG port mapping (8180:8080) for host access
- Use --wait flag in dev:docker to ensure services are healthy
- Include db:migrate in dev:docker:reset for one-command reset
- Update MinIO reference to RustFS in zh-CN docs
- Add SearXNG to service URLs and port conflict docs
Extended test coverage for src/utils/textLength.ts with 26 additional test cases covering:
- CJK character detection (Chinese, Japanese, Korean)
- Special Unicode ranges (CJK Compatibility Ideographs, CJK Extension A, Hangul Jamo)
- Edge cases (numbers, special characters, emojis, newlines, tabs)
- Boundary conditions for truncation
- Custom weight configurations
- Very long text and performance scenarios
All 34 tests pass successfully.
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
* 🐛 fix(model-runtime): fix moonshot interleaved thinking and circular dependency
- Add apiTypes.ts to break circular dependency between createRuntime and baseRuntimeMap
- Use dynamic import for baseRuntimeMap in createRuntime.ts
- Add moonshot to baseRuntimeMap for RouterRuntime support
- Convert reasoning to thinking block in normalizeMoonshotMessages for Anthropic format
- Add tests for interleaved thinking scenarios
* ♻️ refactor(moonshot): extract shared helpers to reduce code duplication
* 🐛 fix(AgentSetting): center Empty component in opening questions
* ♻️ refactor(model-runtime): extract Anthropic provider into reusable factory
- Create `anthropicCompatibleFactory` for shared Anthropic-compatible logic
- Migrate Anthropic provider to use the new factory
- Migrate Moonshot provider from OpenAI-compatible to Anthropic-compatible API
- Move shared utilities (resolveCacheTTL, resolveMaxTokens, etc.) to factory
* ♻️ refactor(model-runtime): convert Moonshot to RouterRuntime with auto API format detection
- Add baseURLPattern support to RouterRuntime for URL-based routing
- Moonshot now auto-selects OpenAI or Anthropic format based on baseURL
- /anthropic suffix -> Anthropic format (with kimi-k2.5 thinking)
- /v1 or default -> OpenAI format
- Remove moonshot from baseRuntimeMap to avoid circular dependency
- Update model-bank config: default to OpenAI format with api.moonshot.ai/v1
- Export CreateRouterRuntimeOptions type from RouterRuntime
- Fix type annotation in Anthropic test
* ✨ feat(model-bank): add Kimi K2.5 to LobeHub provider
- Add Kimi K2.5 model with multimodal capabilities
- Supports vision, reasoning, function calling, structured output, and search
- Context window: 262K tokens, max output: 32K tokens
* 🐛 fix(model-runtime): address PR review feedback
- Restore forceImageBase64 for Moonshot OpenAI runtime to fix vision requests
- Simplify baseURLPattern to only support RegExp (remove string support)
- Add baseURLPattern matching tests for RouterRuntime
* feat: refactor community user pages
* feat: add the agents-group like in social types
* feat: add the user favoitor filter
* fix: slove the agents list show the updateAt time
The createDocument API requires a 'description' parameter, but the system prompt
didn't mention it. This caused models (especially Gemini) to omit the description
field when calling createDocument, resulting in validation errors.
Added <api_parameters> section to clearly document all required and optional
parameters for each Notebook API.
closes#11391
2026-02-01 14:09:52 +08:00
6890 changed files with 588915 additions and 120978 deletions
description: "Agent tracing CLI for inspecting agent execution snapshots. Use when user mentions 'agent-tracing', 'trace', 'snapshot', wants to debug agent execution, inspect LLM calls, view context engine data, or analyze agent steps. Triggers on agent debugging, trace inspection, or execution analysis tasks."
user-invocable: false
---
# Agent Tracing CLI Guide
`@lobechat/agent-tracing` is a zero-config local dev tool that records agent execution snapshots to disk and provides a CLI to inspect them.
## How It Works
In `NODE_ENV=development`, `AgentRuntimeService.executeStep()` automatically records each step to `.agent-tracing/` as partial snapshots. When the operation completes, the partial is finalized into a complete `ExecutionSnapshot` JSON file.
**Data flow**: executeStep loop -> build `StepPresentationData` -> write partial snapshot to disk -> on completion, finalize to `.agent-tracing/{timestamp}_{traceId}.json`
**Context engine capture**: In `RuntimeExecutors.ts`, the `call_llm` executor emits a `context_engine_result` event after `serverMessagesEngine()` processes messages. This event carries the full `contextEngineInput` (DB messages, systemRole, model, knowledge, tools, userMemory, etc.) and the processed `output` messages (the final LLM payload).
3.**Final LLM Payload** — Processed messages after context engine (system date injection, user memory, history truncation, etc.), with `[0]`, `[1]`, ... indices. Use `--msg N` to view full content.
## Integration Points
- **Recording**: `src/server/services/agentRuntime/AgentRuntimeService.ts` — in the `executeStep()` method, after building `stepPresentationData`, writes partial snapshot in dev mode
- **Context engine event**: `src/server/modules/AgentRuntime/RuntimeExecutors.ts` — in `call_llm` executor, after `serverMessagesEngine()` returns, emits `context_engine_result` event
- **Store**: `FileSnapshotStore` reads/writes to `.agent-tracing/` relative to `process.cwd()`
| `@chat-adapter/state-redis` | Redis state (production) |
| `@chat-adapter/state-ioredis` | ioredis state (alternative) |
| `@chat-adapter/state-memory` | In-memory state (development) |
## Changesets (Release Flow)
This monorepo uses [Changesets](https://github.com/changesets/changesets) for versioning and changelogs. Every PR that changes a package's behavior must include a changeset.
# → choose bump type: patch (fixes), minor (features), major (breaking)
# → write a short summary for the CHANGELOG
```
This creates a file in `.changeset/` — commit it with the PR. When merged to `main`, the Changesets GitHub Action opens a "Version Packages" PR to bump versions and update CHANGELOGs. Merging that PR publishes to npm.
## Webhook setup
Each adapter exposes a webhook handler via `bot.webhooks.{platform}`. Wire these to your HTTP framework's routes (e.g. Next.js API routes, Hono, Express).
description: LobeHub CLI (@lobehub/cli) development guide. Use when working on CLI commands, adding new subcommands, fixing CLI bugs, or understanding CLI architecture. Triggers on CLI development, command implementation, or `lh` command questions.
disable-model-invocation: true
---
# LobeHub CLI Development Guide
## Overview
LobeHub CLI (`@lobehub/cli`) is a command-line tool for managing and interacting with LobeHub services. Built with Commander.js + TypeScript.
- **Package**: `apps/cli/`
- **Entry**: `apps/cli/src/index.ts`
- **Binaries**: `lh`, `lobe`, `lobehub` (all aliases for the same CLI)
- **Build**: tsup
- **Runtime**: Node.js / Bun
## Architecture
```
apps/cli/src/
├── index.ts # Entry point, registers all commands
The base directory (`~/.lobehub/`) can be overridden with the `LOBEHUB_CLI_HOME` env var (e.g. `LOBEHUB_CLI_HOME=.lobehub-dev` for dev mode isolation).
## Key Dependencies
-`commander` - CLI framework
-`@trpc/client` + `superjson` - Type-safe API client
-`src/server/routers/lambda/video/index.ts` — video creation (uses `authedProcedure` + `serverDatabase`)
-`src/server/routers/lambda/generation.ts` — status checking
**Note**: Image/video routes do NOT use the `keyVaults` middleware — they read API keys from the database via `initModelRuntimeFromDB` or `createAsyncCaller`.
Manage knowledge bases for RAG (Retrieval-Augmented Generation). Supports directory tree structure with folders, documents, and file uploads.
**Source**: `apps/cli/src/commands/kb.ts`
### `lh kb list`
```bash
lh kb list [--json [fields]]
```
**Table columns**: ID, NAME, DESCRIPTION, UPDATED
### `lh kb view <id>`
```bash
lh kb view [fields]] < id > [--json
```
**Displays**: Name, description, full directory tree with all files and documents (recursively fetched). Shows indented tree structure with item type (File/Doc), file type, and size.
**API**: Uses `file.getKnowledgeItems` to recursively fetch items. Folders (`custom/folder` fileType) are traversed in parallel via `Promise.all` for performance.
This generates an empty SQL file and properly updates `_journal.json` and snapshot. Then edit the generated SQL file to add your custom SQL:
```sql
-- Custom SQL migration file, put your code below! --
CREATEEXTENSIONIFNOTEXISTSpg_search;
```
**Do NOT manually create migration files or edit `_journal.json`** — always use `drizzle-kit generate` to ensure correct journal entries and snapshots.
description: Internationalization guide using react-i18next. Use when adding translations, creating i18n keys, or working with localized text in React components (.tsx files). Triggers on translation tasks, locale management, or i18n implementation.
description: Linear issue management guide. Use when working with Linear issues, creating issues, updating status, or adding comments. Triggers on Linear issue references (LOBE-xxx), issue tracking, or project management tasks. Requires Linear MCP tools to be available.
description: "Linear issue management. MUST USE when: (1) user mentions LOBE-xxx issue IDs (e.g. LOBE-4540), (2) user says 'linear', 'linear issue', 'link linear', (3) creating PRs that reference Linear issues. Provides workflows for retrieving issues, updating status, and adding comments."
---
# Linear Issue Management
Before using Linear workflows, search for `linear` MCP tools. If not found, treat as not installed.
## ⚠️ CRITICAL: PR Creation with Linear Issues
**When creating a PR that references Linear issues (LOBE-xxx), you MUST:**
1. Create the PR with magic keywords (`Fixes LOBE-xxx`)
2.**IMMEDIATELY after PR creation**, add completion comments to ALL referenced Linear issues
3. Do NOT consider the task complete until Linear comments are added
This is NON-NEGOTIABLE. Skipping Linear comments is a workflow violation.
## Workflow
1.**Retrieve issue details** before starting: `mcp__linear-server__get_issue`
@@ -18,9 +28,26 @@ Before using Linear workflows, search for `linear` MCP tools. If not found, trea
When creating issues with `mcp__linear-server__create_issue`, **MUST add the `claude code` label**.
## Completion Comment (REQUIRED)
## Completion Comment Format
Every completed issue MUST have a comment summarizing work done:
```markdown
## Changes Summary
- **Feature**: Brief description of what was implemented
- **Files Changed**: List key files modified
- **PR**: #xxx or PR URL
### Key Changes
- Change 1
- Change 2
- ...
```
This is critical for:
Every completed issue MUST have a comment summarizing work done. This is critical for:
- Team visibility
- Code review context
- Future reference
@@ -28,6 +55,7 @@ Every completed issue MUST have a comment summarizing work done. This is critica
## PR Association (REQUIRED)
When creating PRs for Linear issues, include magic keywords in PR body:
-`Fixes LOBE-123`
-`Closes LOBE-123`
-`Resolves LOBE-123`
@@ -41,11 +69,11 @@ When working on multiple issues, update EACH issue IMMEDIATELY after completing
3. Run related tests
4. Create PR if needed
5. Update status to **"In Review"** (NOT "Done")
6. Add completion comment
6.**Add completion comment immediately**
7. Move to next issue
**Note:** Status → "In Review" when PR created. "Done" only after PR merged.
**❌ Wrong:** Complete all → Update all statuses → Add all comments
**❌ Wrong:** Complete all → Create PR → Forget Linear comments
**✅ Correct:** Complete A → Update A → Comment A → Complete B → ...
You are **LobeHub’s English UI Copy & Microcopy Specialist**.
LobeHub is an assistant workspace: users can create **Agents** and **Agent Teams** so people↔agents and agent↔agent can collaborate to improve productivity in work and life.
Brand vibe: youthful, friendly, modern on the surface; professional, reliable, productivity- and controllability-first underneath. Overall style reference: Notion / Figma / Apple / Discord / OpenAI / Gemini — clear, restrained, trustworthy, human but not cheesy.
Product slogan: **For Collaborative Agents**. Your copy must continuously reinforce that LobeHub is not about “generation”, but about a **collaborative agent system**: shareable context, traceable outcomes, replayable runs, evolvable setup, and **human-in-the-loop**.
---
## 1) Fixed Terminology (must follow)
Use **exactly** these English terms across the product. Do not mix synonyms for the same concept.
- 空间: **Workspace**
- 助理: **Agent**
- 群组: **Group**
- 上下文: **Context**
- 记忆: **Memory**
- 连接器: **Integration**
- 技能 /tool/plugin: **Skill**
- 助理档案: **Agent Profile**
- 话题: **Topic**
- 文稿: **Page**
- 社区: **Community**
- 资源: **Resource**
- 库: **Library**
- MCP: **MCP**
- 模型服务商: **Provider**
Terminology rule: one concept = one term site-wide. Never alternate with “bot/assistant/AI agent/team/workspace” variations.
---
## 2) Your Responsibilities
- Improve, rewrite, or create from scratch any **English UI copy**: titles, buttons, form labels/help text, placeholders, onboarding, empty states, toasts, modals, errors, permission prompts, settings, creation/run flows, collaboration and Agent Team pages, etc.
- Copy must work for both:
- general users (immediately understandable)
- power users (not childish)
- It must fit both playful and serious contexts.
- Avoid overclaiming AI capabilities; add human warmth at the right moments.
---
## 3) The Three Brand Principles (bake into structure & wording)
- **Create**: create an Agent in one sentence; clear next step from idea → usable.
- **Collaborate**: multi-agent collaboration; align info and outputs; share Context (controlled, manageable).
- **Evolve**: Agents can remember preferences **only with user consent**; become more helpful over time; emphasize explainability, settings, and replay.
2.**Layered messaging (single version for everyone)**:
- Main line: simple and actionable
- Optional second line: more precise / technical / boundary-setting (subtitle, helper text, tooltip, collapsible)
- Do not produce “Pro vs Lite” variants; one main + optional detail
3.**Use terms sparingly but correctly**: prefer plain words (“connect”, “run”, “context”) unless a technical term is necessary. When it is, add a plain-English explanation.
4.**Consistency**: keep verbs consistent across similar actions (Create / Connect / Run / Pause / Retry / View details / Clear Memory).
5.**Actionable**: every message tells the user what to do next. Avoid generic “OK/Cancel”; use specific actions.
- Retry / View details / Go to Settings / Contact support / Copy logs
Never blame the user. Don’t show only an error code; put codes in “Details” if needed.
For data/security/billing: be neutral, thorough, and respectful—warmth comes from clarity, not emotion.
---
## 7) Your Special Task: CN i18n → EN (localized, length-aware)
You translate **raw Chinese i18n strings into English** for LobeHub.
Requirements:
- Prefer **localized**, product-native English over literal translation.
- Do **not** chase perfect one-to-one consistency if a more natural UI phrase reads better.
- Keep the **character length difference small**; try to make the English string **roughly the same visual length** as the Chinese source (avoid overly long expansions).
- Preserve meaning, tone, and actionability; keep verbs consistent with LobeHub’s UI patterns.
- If space is tight (buttons, tabs, toasts), prioritize: **verb + object**, drop optional words first.
- If the Chinese includes placeholders/variables, preserve them exactly (e.g., `{name}`, `{{count}}`, `%s`) and keep word order sensible.
- Keep capitalization consistent with UI norms (buttons/title case only when appropriate).
Output format when translating:
- Provide **English only**, unless asked otherwise.
- If multiple options are useful, give **one best option** + **one shorter fallback** (only when length constraints are likely).
---
You always optimize for: **clarity, control, collaboration, replayability, and human-in-the-loop**—in a modern, restrained, trustworthy English voice.
## 8) Product Introduction
LobeHub, we define agents as the unit of work. We’re building the first human–agent co-working, co-evolving network.
It is a fundamentally new, agent-first experience.You can pop up your agents or agent teams while writing, while chatting -- from ideation, to execution, to delivery -- across your entire workflow. Here, agents are not just tools, but always-on units of work.
### Create
It is a unified workspace where you can find, build, or team up with agent co-workers.Simply describe what you need, and Lobe AI will generate the prompts and assemble the right set of tools to compose your agent.In agent marketplace, you can easily discover agents created by others,use them instantly,and flexibly swap in your own tools.
### Collaboration
You can also spin up agent groups to handle system-level projects, even like building a quant team.
Within this group, some agents track signals and mine quantitative factors in real time, some manage risk, some execute orders, collaborate together to make money.
We’re defining how humans and agents work together. Now we support agent-to-agent collaboration, and we continue to scale new forms of collaboration networks — from agents collaborating across teams, to multiple humans working through the same agent.
### Evolve
Humans and agents should co-evolve, and we design this paradigm from both technical and economic perspectives. Our memory system is structured and editable,enabling models to better align with individual users, while allowing users to provide cleaner reward signals for continual learning. Agent evolution is powered by shared human intelligence through our agent marketplace. Creators are rewarded, and agents, in turn, pay for human intelligence.
Is AI replacing humans? No.
We’re building a human–agent co-working, co-evolving society.
Agents become smarter and more personalized through human intelligence, taking on repetitive and exhausting work — so humans can focus on fewer, but more important things: taste, and creation.
description: Complete project architecture and structure guide. Use when exploring the codebase, understanding project organization, finding files, or needing comprehensive architectural context. Triggers on architecture questions, directory navigation, or project overview needs.
---
# LobeChat Project Overview
# LobeHub Project Overview
## Project Description
Open-source, modern-design AI Agent Workspace: **LobeHub** (previously LobeChat).
description: OpenResponses API compliance testing. Use when testing the Response API endpoint, running compliance tests, or debugging Response API schema issues. Triggers on 'compliance', 'response api test', 'openresponses test'.
---
# OpenResponses Compliance Test
Run the official OpenResponses compliance test suite against the local (or remote) Response API endpoint.
## Quick Start
```bash
# From the openapi package directory
cd lobehub/packages/openapi
# Run all tests (dev mode, localhost:3010)
APP_URL=http://localhost:3010 bun run test:response-compliance -- \
| `APP_URL` | `http://localhost:3010` | Server base URL (auto-appends `/api/v1`) |
| `API_KEY` | — | API key (alternative to `--api-key` flag) |
## How It Works
The script (`lobehub/packages/openapi/scripts/compliance-test.sh`) clones the official [openresponses/openresponses](https://github.com/openresponses/openresponses) repo into `scripts/openresponses-compliance/` (gitignored) and runs its CLI test runner. First run clones; subsequent runs update from upstream.
## Debugging Failures
1. Run with `-v` to see full request/response payloads
2. Common failure patterns:
- **"Failed to parse JSON"**: Auth failed, server returned HTML redirect
- **"Response has no output items"**: LLM execution not yet implemented
- **"Expected number, received null"**: Missing required field in response schema
- **"Invalid input"**: Zod validation on response schema — check field format
description: SPA route and feature structure. Use when adding or modifying SPA routes in src/routes, defining new route segments, or moving route logic into src/features. Covers how to keep routes thin and how to divide files between routes and features.
---
# SPA Routes and Features Guide
SPA structure:
- **`src/spa/`** – Entry points (`entry.web.tsx`, `entry.mobile.tsx`, `entry.desktop.tsx`) and router config (`router/`). Router lives here to avoid confusion with `src/routes/`.
- **`src/routes/`** – Page segments only (roots).
- **`src/features/`** – Business logic and UI by domain.
This project uses a **roots vs features** split: `src/routes/` only holds page segments; business logic and UI live in `src/features/` by domain.
## When to Use This Skill
- Adding a new SPA route or route segment
- Defining or refactoring layout/page files under `src/routes/`
- Moving route-specific components or logic into `src/features/`
- Deciding where to put a new component (route folder vs feature folder)
| `_layout/index.tsx` or `layout.tsx` | Layout for this segment: wrap with `<Outlet />`, optional shell (e.g. sidebar + main). Should be thin: prefer re-exporting or composing from `@/features/*`. |
| `index.tsx` or `page.tsx` | Page entry for this segment. Only import from features and render; no business logic. |
| `[param]/index.tsx` (e.g. `[id]`, `[cronId]`) | Dynamic segment page. Same rule: thin, delegate to features. |
**Rule:** Route files should only **import and compose**. No new `features/` folders or heavy components inside `src/routes/`.
---
## 2. What Belongs in `src/features/`
Put **domain-oriented** UI and logic here:
- Layout building blocks: sidebars, headers, body panels, drawers
- Hooks and store usage for that domain
- Domain-specific forms, lists, modals, etc.
Organize by **domain** (e.g. `Pages`, `Home`, `Agent`, `PageEditor`), not by route path. One route can use several features; one feature can be used by several routes.
Each feature should:
- Live under `src/features/<FeatureName>/`
- Export a clear public API via `index.ts` or `index.tsx`
- Use `@/features/<FeatureName>/...` for internal imports when needed
---
## 3. How to Add a New SPA Route
1.**Choose the route group**
-`(main)/`– desktop main app
-`(mobile)/`– mobile
-`(desktop)/`– Electron-specific
-`onboarding/`, `share/`– special flows
2.**Create only segment files under `src/routes/`**
- e.g. `src/routes/(main)/my-feature/_layout/index.tsx` and `src/routes/(main)/my-feature/index.tsx` (and optional `[id]/index.tsx`).
3.**Implement layout and page content in `src/features/`**
- Create or reuse a domain (e.g. `src/features/MyFeature/`).
- Put layout (sidebar, header, body) and page UI there; export from the feature’s `index`.
4.**Keep route files thin**
- Layout: `export { default } from '@/features/MyFeature/MyLayout'` or compose a few feature components + `<Outlet />`.
- Page: import from `@/features/MyFeature` (or a specific subpath) and render; no business logic in the route file.
5.**Register the route**
- Add the segment to `src/spa/router/desktopRouter.config.tsx` (or the right router config) with `dynamicElement` / `dynamicLayout` pointing at the new route paths (e.g. `@/routes/(main)/my-feature`).
---
## 4. How to Divide Files (route vs feature)
| Question | Put in `src/routes/` | Put in `src/features/` |
| Is it the route’s layout wrapper or page entry? | Yes –`_layout/index.tsx`, `index.tsx`, `[id]/index.tsx` | No |
| Does it contain business logic or non-trivial UI? | No | Yes – under the right domain |
| Is it a reusable layout piece (sidebar, header, body)? | No | Yes |
| Is it a hook, store usage, or domain logic? | No | Yes |
| Is it only re-exporting or composing feature components? | Yes | No |
**Examples**
- **Route (thin):**\
`src/routes/(main)/page/_layout/index.tsx` → `export { default } from '@/features/Pages/PageLayout'`
- **Feature (real implementation):**\
`src/features/Pages/PageLayout/` → Sidebar, DataSync, Body, Header, styles, etc.
- **Route (thin):**\
`src/routes/(main)/page/index.tsx` → Import `PageTitle`, `PageExplorerPlaceholder` from `@/features/Pages` and `@/features/PageExplorer`; render with `<PageTitle />` and placeholder.
- **Feature:**\
Page list, actions, drawers, and hooks live under `src/features/Pages/`.
---
## 5. Progressive Migration (existing code)
We are migrating existing routes to this structure step by step:
- **Phase 1 (done):** `/page` route – segment files in `src/routes/(main)/page/`, implementation in `src/features/Pages/`.
When touching an old route that still has logic or `features/` inside `src/routes/`:
1. Prefer adding **new** code in `src/features/<Domain>/` and importing from routes.
2. For larger refactors, move existing route-only logic into the right feature and then thin out the route files (re-export or compose from features).
3. Use `git mv` when moving files so history is preserved.
---
## 6. Reference Structure (after Phase 1)
**Route (thin):**
```
src/routes/(main)/page/
├── _layout/index.tsx → re-export or compose from @/features/Pages/PageLayout
├── index.tsx → import from @/features/Pages, @/features/PageExplorer
└── [id]/index.tsx → import from @/features/Pages, @/features/PageExplorer
```
**Feature (implementation):**
```
src/features/Pages/
├── index.ts → export PageLayout, PageTitle
├── PageTitle.tsx
└── PageLayout/
├── index.tsx → Sidebar + Outlet + DataSync
├── DataSync.tsx
├── Sidebar.tsx
├── style.ts
├── Body/ → list, actions, drawer, etc.
└── Header/ → breadcrumb, add button, etc.
```
Router config continues to point at **route** paths (e.g. `@/routes/(main)/page`, `@/routes/(main)/page/_layout`); route files then delegate to features.
description: Zustand store data structure patterns for LobeHub. Covers List vs Detail data structures, Map + Reducer patterns, type definitions, and when to use each pattern. Use when designing store state, choosing data structures, or implementing list/detail pages.
---
# LobeHub Store Data Structures
This guide covers how to structure data in Zustand stores for optimal performance and user experience.
## Core Principles
### ✅ DO
1.**Separate List and Detail** - Use different structures for list pages and detail pages
2.**Use Map for Details** - Cache multiple detail pages with `Record<string, Detail>`
3.**Use Array for Lists** - Simple arrays for list display
4.**Types from @lobechat/types** - Never use `@lobechat/database` types in stores
5.**Distinguish List and Detail types** - List types may have computed UI fields
### ❌ DON'T
1.**Don't use single detail object** - Can't cache multiple pages
2.**Don't mix List and Detail types** - They have different purposes
3.**Don't use database types** - Use types from `@lobechat/types`
4.**Don't use Map for lists** - Simple arrays are sufficient
---
## Type Definitions
Types should be organized by entity in separate files:
```
@lobechat/types/src/eval/
├── benchmark.ts # Benchmark types
├── agentEvalDataset.ts # Dataset types
├── agentEvalRun.ts # Run types
└── index.ts # Re-exports
```
### Example: Benchmark Types
```typescript
// packages/types/src/eval/benchmark.ts
importtype{EvalBenchmarkRubric}from'./rubric';
// ============================================
// Detail Type - Full entity (for detail pages)
// ============================================
/**
* Full benchmark entity with all fields including heavy data
*/
exportinterfaceAgentEvalBenchmark{
createdAt: Date;
description?: string|null;
id: string;
identifier: string;
isSystem: boolean;
metadata?: Record<string,unknown>|null;
name: string;
referenceUrl?: string|null;
rubrics: EvalBenchmarkRubric[];// Heavy field
updatedAt: Date;
}
// ============================================
// List Type - Lightweight (for list display)
// ============================================
/**
* Lightweight benchmark item - excludes heavy fields
* May include computed statistics for UI
*/
exportinterfaceAgentEvalBenchmarkListItem{
createdAt: Date;
description?: string|null;
id: string;
identifier: string;
isSystem: boolean;
name: string;
// Note: rubrics NOT included (heavy field)
// Computed statistics for UI display
datasetCount?: number;
runCount?: number;
testCaseCount?: number;
}
```
### Example: Document Types (with heavy content)
```typescript
// packages/types/src/document.ts
/**
* Full document entity - includes heavy content fields
*/
exportinterfaceDocument{
id: string;
title: string;
description?: string;
content: string;// Heavy field - full markdown content
editorData: any;// Heavy field - editor state
metadata?: Record<string,unknown>;
createdAt: Date;
updatedAt: Date;
}
/**
* Lightweight document item - excludes heavy content
*/
exportinterfaceDocumentListItem{
id: string;
title: string;
description?: string;
// Note: content and editorData NOT included
createdAt: Date;
updatedAt: Date;
// Computed statistics
wordCount?: number;
lastEditedBy?: string;
}
```
**Key Points:**
- **Detail types** include ALL fields from database (full entity)
- **List types** are **subsets** that exclude heavy/large fields
- List types may add computed statistics for UI (e.g., `testCaseCount`)
- **Each entity gets its own file** (not mixed together)
- **All types** exported from `@lobechat/types`, NOT `@lobechat/database`
**Heavy fields to exclude from List:**
- Large text content (`content`, `editorData`, `fullDescription`)
description: Testing guide using Vitest. Use when writing tests (.test.ts, .test.tsx), fixing failing tests, improving test coverage, or debugging test issues. Triggers on test creation, test debugging, mock setup, or test-related questions.
---
# LobeChat Testing Guide
# LobeHub Testing Guide
## Quick Reference
**Commands:**
```bash
# Run specific test file
bunx vitest run --silent='passed-only''[file-path]'
@@ -19,15 +20,15 @@ cd packages/database && bunx vitest run --silent='passed-only' '[file]'
cd packages/database &&TEST_SERVER_DB=1 bunx vitest run --silent='passed-only''[file]'
```
**Never run**`bun run test` - it runs all 3000+ tests (~10 minutes).
**Never run**`bun run test` - it runs all 3000+ tests (\~10 minutes).
When tests fail due to implementation changes (not bugs), evaluate before blindly fixing:
### Keep & Fix (update test data/assertions)
- **Behavior tests**: Tests that verify _what_ the code does (output, side effects, user-visible behavior). Just update mock data formats or expected values.
- Example: Tool data structure changed from `{ name }` to `{ function: { name } }` → update mock data
- Example: Output format changed from `Current date: YYYY-MM-DD` to `Current date: YYYY-MM-DD (TZ)` → update expected string
### Delete (over-specified, low value)
- **Param-forwarding tests**: Tests that assert exact internal function call arguments (e.g., `expect(internalFn).toHaveBeenCalledWith(expect.objectContaining({ exact params }))`) — these break on every refactor and duplicate what behavior tests already cover.
- **Implementation-coupled tests**: Tests that verify _how_ the code works internally rather than _what_ it produces. If a higher-level test already covers the same behavior, the low-level test adds maintenance cost without coverage gain.
### Decision Checklist
1. Does the test verify **externally observable behavior** (API response, DB write, rendered output)? → **Keep**
2. Does the test only verify **internal wiring** (which function receives which params)? → Check if a behavior test already covers it. If yes → **Delete**
3. Is the same behavior already tested at a **higher integration level**? → Delete the lower-level duplicate
4. Would the test break again on the **next routine refactor**? → Consider raising to integration level or deleting
### When Writing New Tests
- Prefer **integration-level assertions** (verify final output) over **white-box assertions** (verify internal calls)
- Use `expect.objectContaining` only for stable, public-facing contracts — not for internal param shapes that change with refactors
- Mock at boundaries (DB, network, external services), not between internal modules
## Common Issues
1.**Module pollution**: Use `vi.resetModules()` when tests fail mysteriously
LobeChat Desktop uses Vitest as the test framework. Controller unit tests should be placed in the `__tests__` directory adjacent to the controller file, named with the original controller filename plus `.test.ts`.
LobeHub Desktop uses Vitest as the test framework. Controller unit tests should be placed in the `__tests__` directory adjacent to the controller file, named with the original controller filename plus `.test.ts`.
description: TypeScript code style and optimization guidelines. Use when writing TypeScript code (.ts, .tsx, .mts files), reviewing code quality, or implementing type-safe patterns. Triggers on TypeScript development, type safety questions, or code style discussions.
description: TypeScript code style and optimization guidelines. MUST READ before writing or modifying any TypeScript code (.ts, .tsx, .mts files). Also use when reviewing code quality or implementing type-safe patterns. Triggers on any TypeScript file edit, code style discussions, or type safety questions.
---
# TypeScript Code Style Guide
@@ -14,6 +14,9 @@ description: TypeScript code style and optimization guidelines. Use when writing
- Prefer `as const satisfies XyzInterface` over plain `as const`
- Prefer `@ts-expect-error` over `@ts-ignore` over `as any`
- Avoid meaningless null/undefined parameters; design strict function contracts
- Prefer ES module augmentation (`declare module '...'`) over `namespace`; do not introduce `namespace`-based extension patterns
- When a type needs extensibility, expose a small mergeable interface at the source type and let each feature/plugin augment it locally instead of centralizing all extension fields in one registry file
- For package-local extensibility patterns like `PipelineContext.metadata`, define the metadata fields next to the processor/provider/plugin that reads or writes them
## Async Patterns
@@ -22,6 +25,17 @@ description: TypeScript code style and optimization guidelines. Use when writing
- Use promise-based variants: `import { readFile } from 'fs/promises'`
- Use `Promise.all`, `Promise.race` for concurrent operations where safe
## Imports
- This project uses `simple-import-sort/imports` and `consistent-type-imports` (`fixStyle: 'separate-type-imports'`)
- **Separate type imports**: always use `import type { ... }` for type-only imports, NOT `import { type ... }` inline syntax
- When a file already has `import type { ... }` from a package and you need to add a value import, keep them as **two separate statements**:
```ts
import type { ChatTopicBotContext } from '@lobechat/types';
import { RequestTrigger } from '@lobechat/types';
```
- Within each import statement, specifiers are sorted **alphabetically by name**
## Code Structure
- Prefer object destructuring
@@ -50,3 +64,4 @@ description: TypeScript code style and optimization guidelines. Use when writing
- Never log user private information (API keys, etc.)
- Don't use `import { log } from 'debug'` directly (logs to console)
- Use `console.error` in catch blocks instead of debug package
- Always log the error in `.catch()` callbacks — silent `.catch(() => fallback)` swallows failures and makes debugging impossible
echo"export { POST } from 'lobehub/src/app/(backend)/api/workflows/feature-name/layer/route';" > lobehub-cloud/src/app/\(backend\)/api/workflows/feature-name/layer/route.ts
```
### Type Errors After Moving to Lobehub
**Cause**: Cloud-specific types or services used in lobehub code
**Solution**:
1. Extract cloud-specific logic to cloud-only wrapper
2. Use dependency injection for services
3. Define generic interfaces in lobehub
---
## Related Documentation
- [SKILL.md](../SKILL.md) - Standard workflow patterns
description: React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
license: MIT
metadata:
author: vercel
version: "1.0.0"
---
# Vercel React Best Practices
Comprehensive performance optimization guide for React and Next.js applications, maintained by Vercel. Contains 45 rules across 8 categories, prioritized by impact to guide automated refactoring and code generation.
## When to Apply
Reference these guidelines when:
- Writing new React components or Next.js pages
- Implementing data fetching (client or server-side)
`useEffectEvent` provides a cleaner API for the same pattern: it creates a stable function reference that always calls the latest version of the handler.
Import directly from source files instead of barrel files to avoid loading thousands of unused modules. **Barrel files** are entry points that re-export multiple modules (e.g., `index.js` that does `export * from './module'`).
Popular icon and component libraries can have **up to 10,000 re-exports** in their entry file. For many React packages, **it takes 200-800ms just to import them**, affecting both development speed and production cold starts.
**Why tree-shaking doesn't help:** When a library is marked as external (not bundled), the bundler can't optimize it. If you bundle it to enable tree-shaking, builds become substantially slower analyzing the entire module graph.
**Incorrect (imports entire library):**
```tsx
import { Check, X, Menu } from 'lucide-react'
// Loads 1,583 modules, takes ~2.8s extra in dev
// Runtime cost: 200-800ms on every cold start
import { Button, TextField } from '@mui/material'
// Loads 2,225 modules, takes ~4.2s extra in dev
```
**Correct (imports only what you need):**
```tsx
import Check from 'lucide-react/dist/esm/icons/check'
import X from 'lucide-react/dist/esm/icons/x'
import Menu from 'lucide-react/dist/esm/icons/menu'
// User object has 20+ fields, only store what UI needs
function cachePrefs(user: FullUser) {
try {
localStorage.setItem('prefs:v1', JSON.stringify({
theme: user.preferences.theme,
notifications: user.preferences.notifications
}))
} catch {}
}
```
**Always wrap in try-catch:** `getItem()` and `setItem()` throw in incognito/private browsing (Safari, Firefox), when quota exceeded, or when disabled.
## Use Passive Event Listeners for Scrolling Performance
Add `{ passive: true }` to touch and wheel event listeners to enable immediate scrolling. Browsers normally wait for listeners to finish to check if `preventDefault()` is called, causing scroll delay.
Avoid interleaving style writes with layout reads. When you read a layout property (like `offsetWidth`, `getBoundingClientRect()`, or `getComputedStyle()`) between style changes, the browser is forced to trigger a synchronous reflow.
**Incorrect (interleaved reads and writes force reflows):**
```typescript
function updateElementStyles(element: HTMLElement) {
Prefer CSS classes over inline styles when possible. CSS files are cached by the browser, and classes provide better separation of concerns and are easier to maintain.
When comparing arrays with expensive operations (sorting, deep equality, serialization), check lengths first. If lengths differ, the arrays cannot be equal.
In real-world applications, this optimization is especially valuable when the comparison runs in hot paths (event handlers, render loops).
**Incorrect (always runs expensive comparison):**
```typescript
function hasChanges(current: string[], original: string[]) {
// Always sorts and joins, even when lengths differ
Two O(n log n) sorts run even when `current.length` is 5 and `original.length` is 100. There is also overhead of joining the arrays and comparing the strings.
**Correct (O(1) length check first):**
```typescript
function hasChanges(current: string[], original: string[]) {
// Early return if lengths differ
if (current.length !== original.length) {
return true
}
// Only sort when lengths match
const currentSorted = current.toSorted()
const originalSorted = original.toSorted()
for (let i = 0; i < currentSorted.length; i++) {
if (currentSorted[i] !== originalSorted[i]) {
return true
}
}
return false
}
```
This new approach is more efficient because:
- It avoids the overhead of sorting and joining the arrays when lengths differ
- It avoids consuming memory for the joined strings (especially important for large arrays)
if (projects[i].updatedAt < oldest.updatedAt) oldest = projects[i]
if (projects[i].updatedAt > newest.updatedAt) newest = projects[i]
}
return { oldest, newest }
}
```
Single pass through the array, no copying, no sorting.
**Alternative (Math.min/Math.max for small arrays):**
```typescript
const numbers = [5, 2, 8, 1, 9]
const min = Math.min(...numbers)
const max = Math.max(...numbers)
```
This works for small arrays, but can be slower or just throw an error for very large arrays due to spread operator limitations. Maximal array length is approximately 124000 in Chrome 143 and 638000 in Safari 18; exact numbers may vary - see [the fiddle](https://jsfiddle.net/qw1jabsx/4/). Use the loop approach for reliability.
## Use toSorted() Instead of sort() for Immutability
`.sort()` mutates the array in place, which can cause bugs with React state and props. Use `.toSorted()` to create a new sorted array without mutation.
**Incorrect (mutates original array):**
```typescript
function UserList({ users }: { users: User[] }) {
// Mutates the users prop array!
const sorted = useMemo(
() => users.sort((a, b) => a.name.localeCompare(b.name)),
[users]
)
return <div>{sorted.map(renderUser)}</div>
}
```
**Correct (creates new array):**
```typescript
function UserList({ users }: { users: User[] }) {
// Creates new sorted array, original unchanged
const sorted = useMemo(
() => users.toSorted((a, b) => a.name.localeCompare(b.name)),
[users]
)
return <div>{sorted.map(renderUser)}</div>
}
```
**Why this matters in React:**
1. Props/state mutations break React's immutability model - React expects props and state to be treated as read-only
2. Causes stale closure bugs - Mutating arrays inside closures (callbacks, effects) can lead to unexpected behavior
**Browser support (fallback for older browsers):**
`.toSorted()` is available in all modern browsers (Chrome 110+, Safari 16+, Firefox 115+, Node.js 20+). For older environments, use spread operator:
```typescript
// Fallback for older browsers
const sorted = [...items].sort((a, b) => a.value - b.value)
This applies to all CSS transforms and transitions (`transform`, `opacity`, `translate`, `scale`, `rotate`). The wrapper div allows browsers to use GPU acceleration for smoother animations.
Use explicit ternary operators (`? :`) instead of `&&` for conditional rendering when the condition can be `0`, `NaN`, or other falsy values that render.
**Incorrect (renders "0" when count is 0):**
```tsx
function Badge({ count }: { count: number }) {
return (
<div>
{count && <span className="badge">{count}</span>}
</div>
)
}
// When count = 0, renders: <div>0</div>
// When count = 5, renders: <div><span class="badge">5</span></div>
This is especially helpful for large and static SVG nodes, which can be expensive to recreate on every render.
**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, the compiler automatically hoists static JSX elements and optimizes component re-renders, making manual hoisting unnecessary.
When rendering content that depends on client-side storage (localStorage, cookies), avoid both SSR breakage and post-hydration flickering by injecting a synchronous script that updates the DOM before React hydrates.
**Incorrect (breaks SSR):**
```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
// localStorage is not available on server - throws error
Server-side rendering will fail because `localStorage` is undefined.
**Incorrect (visual flickering):**
```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState('light')
useEffect(() => {
// Runs after hydration - causes visible flash
const stored = localStorage.getItem('theme')
if (stored) {
setTheme(stored)
}
}, [])
return (
<div className={theme}>
{children}
</div>
)
}
```
Component first renders with default value (`light`), then updates after hydration, causing a visible flash of incorrect content.
**Correct (no flicker, no hydration mismatch):**
```tsx
function ThemeWrapper({ children }: { children: ReactNode }) {
return (
<>
<div id="theme-wrapper">
{children}
</div>
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
try {
var theme = localStorage.getItem('theme') || 'light';
var el = document.getElementById('theme-wrapper');
if (el) el.className = theme;
} catch (e) {}
})();
`,
}}
/>
</>
)
}
```
The inline script executes synchronously before showing the element, ensuring the DOM already has the correct value. No flickering, no hydration mismatch.
This pattern is especially useful for theme toggles, user preferences, authentication states, and any client-only data that should render immediately without flashing default values.
Reduce SVG coordinate precision to decrease file size. The optimal precision depends on the viewBox size, but in general reducing precision should be considered.
**Incorrect (excessive precision):**
```svg
<path d="M 10.293847 20.847362 L 30.938472 40.192837" />
When updating state based on the current state value, use the functional update form of setState instead of directly referencing the state variable. This prevents stale closures, eliminates unnecessary dependencies, and creates stable callback references.
**Incorrect (requires state as dependency):**
```tsx
function TodoList() {
const [items, setItems] = useState(initialItems)
// Callback must depend on items, recreated on every items change
The first callback is recreated every time `items` changes, which can cause child components to re-render unnecessarily. The second callback has a stale closure bug—it will always reference the initial `items` value.
**Correct (stable callbacks, no stale closures):**
4. **Prevents bugs** - Eliminates the most common source of React closure bugs
**When to use functional updates:**
- Any setState that depends on the current state value
- Inside useCallback/useMemo when state is needed
- Event handlers that reference state
- Async operations that update state
**When direct updates are fine:**
- Setting state to a static value: `setCount(0)`
- Setting state from props/arguments only: `setName(newName)`
- State doesn't depend on previous value
**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, the compiler can automatically optimize some cases, but functional updates are still recommended for correctness and to prevent stale closure bugs.
Pass a function to `useState` for expensive initial values. Without the function form, the initializer runs on every render even though the value is only used once.
**Incorrect (runs on every render):**
```tsx
function FilteredList({ items }: { items: Item[] }) {
// buildSearchIndex() runs on EVERY render, even after initialization
Use lazy initialization when computing initial values from localStorage/sessionStorage, building data structures (indexes, maps), reading from the DOM, or performing heavy transformations.
For simple primitives (`useState(0)`), direct references (`useState(props.value)`), or cheap literals (`useState({})`), the function form is unnecessary.
Extract expensive work into memoized components to enable early returns before computation.
**Incorrect (computes avatar even when loading):**
```tsx
function Profile({ user, loading }: Props) {
const avatar = useMemo(() => {
const id = computeAvatarId(user)
return <Avatar id={id} />
}, [user])
if (loading) return <Skeleton />
return <div>{avatar}</div>
}
```
**Correct (skips computation when loading):**
```tsx
const UserAvatar = memo(function UserAvatar({ user }: { user: User }) {
const id = useMemo(() => computeAvatarId(user), [user])
return <Avatar id={id} />
})
function Profile({ user, loading }: Props) {
if (loading) return <Skeleton />
return (
<div>
<UserAvatar user={user} />
</div>
)
}
```
**Note:** If your project has [React Compiler](https://react.dev/learn/react-compiler) enabled, manual memoization with `memo()` and `useMemo()` is not necessary. The compiler automatically optimizes re-renders.
Use Next.js's `after()` to schedule work that should execute after a response is sent. This prevents logging, analytics, and other side effects from blocking the response.
`React.cache()` only works within one request. For data shared across sequential requests (user clicks button A then button B), use an LRU cache.
**Implementation:**
```typescript
import { LRUCache } from 'lru-cache'
const cache = new LRUCache<string, any>({
max: 1000,
ttl: 5 * 60 * 1000 // 5 minutes
})
export async function getUser(id: string) {
const cached = cache.get(id)
if (cached) return cached
const user = await db.user.findUnique({ where: { id } })
cache.set(id, user)
return user
}
// Request 1: DB query, result cached
// Request 2: cache hit, no DB query
```
Use when sequential user actions hit multiple endpoints needing the same data within seconds.
**With Vercel's [Fluid Compute](https://vercel.com/docs/fluid-compute):** LRU caching is especially effective because multiple concurrent requests can share the same function instance and cache. This means the cache persists across requests without needing external storage like Redis.
**In traditional serverless:** Each invocation runs in isolation, so consider Redis for cross-process caching.
If you must pass objects, pass the same reference:
```typescript
const params = { uid: 1 }
getUser(params) // Query runs
getUser(params) // Cache hit (same reference)
```
**Next.js-Specific Note:**
In Next.js, the `fetch` API is automatically extended with request memoization. Requests with the same URL and options are automatically deduplicated within a single request, so you don't need `React.cache()` for `fetch` calls. However, `React.cache()` is still essential for other async tasks:
- Database queries (Prisma, Drizzle, etc.)
- Heavy computations
- Authentication checks
- File system operations
- Any non-fetch async work
Use `React.cache()` to deduplicate these operations across your component tree.
The React Server/Client boundary serializes all object properties into strings and embeds them in the HTML response and subsequent RSC requests. This serialized data directly impacts page weight and load time, so **size matters a lot**. Only pass fields that the client actually uses.
description: "Version release workflow. Use when the user mentions 'release', 'hotfix', 'version upgrade', 'weekly release', or '发版'/'发布'/'小班车'. Provides guides for Minor Release and Patch Release workflows."
---
# Version Release Workflow
## Overview
The primary development branch is **canary**. All day-to-day development happens on canary. When releasing, canary is merged into main. After merge, `auto-tag-release.yml` automatically handles tagging, version bumping, creating a GitHub Release, and syncing back to the canary branch.
Only two release types are used in practice (major releases are extremely rare and can be ignored):
| Type | Use Case | Frequency | Source Branch | PR Title Format | Version |
| Minor | Feature iteration release | \~Every 4 weeks | canary | `🚀 release: v{x.y.0}` | Manually set |
| Patch | Weekly release / hotfix / model / DB migration | \~Weekly or as needed | canary or main | Custom (e.g. `🚀 release: 20260222`) | Auto patch +1 |
## Minor Release Workflow
Used to publish a new minor version (e.g. v2.2.0), roughly every 4 weeks.
### Steps
1. **Create a release branch from canary**
```bash
git checkout canary
git pull origin canary
git checkout -b release/v{version}
git push -u origin release/v{version}
```
2. **Determine the version number** — Read the current version from `package.json` and compute the next minor version (e.g. 2.1.x → 2.2.0)
3. **Create a PR to main**
```bash
gh pr create \
--title "🚀 release: v{version}" \
--base main \
--head release/v{version} \
--body "## 📦 Release v{version} ..."
```
> \[!IMPORTANT]: The PR title must strictly match the `🚀 release: v{x.y.z}` format. CI uses a regex on this title to determine the exact version number.
4. **Automatic trigger after merge**: auto-tag-release detects the title format and uses the version number from the title to complete the release.
### Scripts
```bash
bun run release:branch # Interactive
bun run release:branch --minor # Directly specify minor
```
## Patch Release Workflow
Version number is automatically bumped by patch +1. There are 4 common scenarios:
| New Model Launch | canary | Community PR merged directly | New model launch, triggered by PR title prefix |
| DB Schema Migration | main | `release/db-migration-{name}` | Database migration, requires dedicated changelog |
All scenarios auto-bump patch +1. Patch PR titles do not need a version number. See `reference/patch-release-scenarios.md` for detailed steps per scenario.
4. **Dispatch sync-main-to-canary** — syncs main back to the canary branch
## Claude Action Guide
When the user requests a release:
### Minor Release
1. Read `package.json` to get the current version and compute the next minor version
2. Create a `release/v{version}` branch from canary
3. Push and create a PR — **title must be `🚀 release: v{version}`**
4. Inform the user that merging the PR will automatically trigger the release
### Precheck
Before creating the release branch, verify the source branch:
- **Weekly Release** (`release/weekly-*`): must branch from `canary`
- **All other release/hotfix branches**: must branch from `main` — run `git merge-base --is-ancestor main <branch> && echo OK` to confirm
- If the branch is based on the wrong source, delete and recreate from the correct base
### Patch Release
Choose the appropriate workflow based on the scenario (see `reference/patch-release-scenarios.md`):
- **Weekly Release**: Create a `release/weekly-{YYYYMMDD}` branch from canary, scan `git log main..canary` to write the changelog, title like `🚀 release: 20260222`
- **Bug Hotfix**: Create a `hotfix/` branch from main, use a gitmoji prefix title (e.g. `🐛 fix: ...`)
- **New Model Launch**: Community PRs trigger automatically via title prefix (`feat` / `style`), no extra steps needed
- **DB Migration**: Create a `release/db-migration-{name}` branch from main, cherry-pick migration commits, write a dedicated migration changelog
### Important Notes
- **Do NOT manually modify the version in package.json** — CI will auto-bump it
- **Do NOT manually create tags** — CI will create them automatically
- The Minor Release PR title format is a hard requirement — incorrect format will not use the specified version number
- Patch PRs do not need a version number — CI auto-bumps patch +1
- All release PRs must include a user-facing changelog
## Changelog Writing Guidelines
All release PR bodies (both Minor and Patch) must include a user-facing changelog. Scan changes via `git log main..canary --oneline` or `git diff main...canary --stat`, then write following the format below.
### Format Reference
- Weekly Release: See `reference/changelog-example/weekly-release.md`
- DB Migration: See `reference/changelog-example/db-migration.md`
### Writing Tips
- **User-facing**: Describe changes that users can perceive, not internal implementation details
- **Clear categories**: Group by features, models/providers, desktop, stability/fixes, etc.
- **Highlight key items**: Use `**bold**` for important feature names
- **Credit contributors**: Collect all committers via `git log` and list alphabetically
- **Flexible categories**: Choose categories based on actual changes — no need to force-fit all categories
- Added 5 new tables: `agent_eval_benchmarks`, `agent_eval_datasets`, `agent_eval_records`, `agent_eval_runs`, `agent_eval_run_topics`
### Notes for Self-hosted Users
- The migration runs automatically on application startup
- No manual intervention required
The migration owner: @{pr-author} — responsible for this database schema change, reach out for any migration-related issues.
> **Note for Claude**: Replace `{pr-author}` with the actual PR author. Retrieve via `gh pr view <number> --json author --jq '.author.login'` or `git log` commit author. Do NOT hardcode a username.
A real-world changelog reference for weekly patch release PR bodies.
---
This release includes **82 commits** , Key updates are below.
### New Features and Enhancements
- Added **Agent Benchmark** support for more systematic agent performance evaluation.
- Introduced the **video generation** feature end-to-end, including entry points, sidebar "new" badge support, and skeleton loading for topic switching.
- Expanded memory capabilities: support for memory effort/tool permission configuration and improved timeout calculation for memory analysis tasks.
- Added desktop editor support for image upload via file picker.
### Models and Provider Expansion
- Added a new provider: **Straico**.
- Added/updated support for:
- Claude Sonnet 4.6
- Gemini 3.1 Pro Preview
- Qwen3.5 series
- Grok Imagine (`grok-imagine-image`)
- MiniMax 2.5
- Added related i18n copy and model parameter adaptations.
New AI model or provider support, typically contributed via community PRs.
### How it works
- Community contributors submit PRs with titles like `✨ feat: add xxx model` or `💄 style: support xxx models`
- These PR title prefixes (`feat` / `style`) are in the auto-tag trigger list
- No special branch naming or manual release steps required — merging the PR triggers auto patch +1
### When Claude is involved
If asked to add model support, just create a normal feature PR. The title prefix will trigger the release automatically.
---
## 4. DB Schema Migration
Database schema changes that need to be released independently. These require a dedicated changelog explaining the migration for self-hosted users.
### Steps
1. **Create release branch from main and cherry-pick migration commits**
```bash
git checkout main
git pull --rebase origin main
git checkout -b release/db-migration-{name}
git cherry-pick <migration-commit-hash>
git push -u origin release/db-migration-{name}
```
2. **Write a migration-specific changelog** — See `db-migration-changelog-example.md` for the format. This should explain:
- What tables/columns are added, modified, or removed
- Whether the migration is backwards-compatible
- Any action required by self-hosted users
- **Migration owner**: Use the actual PR author (retrieve via `gh pr view <number> --json author --jq '.author.login'` or `git log` commit author), never hardcode a username
3. **Create PR to main** with the migration changelog as the PR body
description: Zustand state management guide. Use when working with store code (src/store/**), implementing actions, managing state, or creating slices. Triggers on Zustand store development, state management questions, or action implementation.
---
# LobeChat Zustand State Management
# LobeHub Zustand State Management
## Action Type Hierarchy
### 1. Public Actions
Main interfaces for UI components:
- Naming: Verb form (`createTopic`, `sendMessage`)
@@ -29,11 +29,35 @@ Prioritize modules with business logic:
## Workflow
### 0. Pre-check: Scan Existing Test PRs
Before selecting a module, **MUST** scan existing PRs to avoid duplicate work:
1. **List in-flight PRs**:
```bash
gh pr list --search "automatic/add-tests-" --state open --json number,title,headRefName,mergeable
```
2. **Close conflicting PRs**: For any PR where `mergeable` is `"CONFLICTING"`, close it with a comment:
```bash
gh pr close <number> --comment "Closing: this PR has merge conflicts with main and is outdated. A new test PR may be created for this module."
```
3. **Build exclusion list**: Extract module names from the remaining open PR branch names (`automatic/add-tests-<module-name>-<date>`), and **exclude those modules** from selection in the next step.
4. **Output summary** (for logging):
- Total open test PRs found
- PRs closed due to conflicts
- Modules currently in-flight (excluded from selection)
### 1. Select a Module to Process
**Selection Strategy**:
- Randomly pick ONE module from the target directories
- **MUST skip modules that already have an open PR** (from step 0's exclusion list)
@@ -5,10 +5,11 @@ You are a support assistant for LobeChat authentication migration issues. Your j
**IMPORTANT**: The official documentation website is `https://lobehub.com`. When providing documentation links, always use `https://lobehub.com/docs/...` format. Never use `lobechat.com` - that domain is incorrect.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.