🚀 release: 20260427#14217
Conversation
…ol (#13875) Made-with: Cursor
- Update changelog documentation format across all historical changelog files - Merge release-changelog-style skill into version-release skill - Update changelog examples with improved formatting and structure Made-with: Cursor
* 🐛 fix(app): include working panel into Lab feature, minor fixes * 🐛 fix(app): conditional disabled.
* ✨ feat: associate web crawl documents with agent documents - Add `associate` method to AgentDocumentModel for linking existing documents - Add `associateDocument` to AgentDocumentsService, TRPC router, and client service - Update web browsing executor to associate crawled pages with agent after notebook save - Add server-side crawl-to-agent-document persistence in webBrowsing runtime - Add `findOrCreateFolder` to DocumentModel for folder hierarchy support - Extract `DOCUMENT_FOLDER_TYPE` constant from hardcoded 'custom/folder' strings - Add tests for associate, findOrCreateFolder, and service layer Fixes LOBE-7242 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: log errors in web crawl agent document association Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: add onCrawlComplete callback to WebBrowsingExecutionRuntime Replace monkey-patching of crawlMultiPages with a proper onCrawlComplete callback in the runtime constructor options. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: move document save logic into WebBrowsingExecutionRuntime Replace onCrawlComplete callback with documentService dependency injection. The runtime now directly handles createDocument + associateDocument internally. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: pass per-call context to documentService via crawlMultiPages Add WebBrowsingDocumentContext (topicId, agentId) as a parameter to crawlMultiPages, which flows through to documentService methods. This allows a singleton runtime with per-call context on the client side. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: enforce document ownership in associate and match root folders by null parentId - associate: verify documentId belongs to current user before creating link - findOrCreateFolder: add parentId IS NULL condition for root-level lookup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
docs: add release changelog skills
* Add document history versioning and TRPC APIs * 🩹 Improve document history patching for rekeyed editor nodes * Refine PageEditor history timeline UI * Enhance modal API documentation and update modal implementation guidelines. Introduce new modal components and migration notes for transitioning from legacy `@lobehub/ui` to `@lobehub/ui/base-ui`. Update version history localization for improved clarity in UI. Add new CompareModal components for document history comparison. Signed-off-by: Innei <tukon479@gmail.com> * 🔥 chore(docs): remove document history tech spec Made-with: Cursor * Enhance document history management by introducing a 30-day limit for history queries and updating related APIs. Refactor history service methods to support new options for filtering history based on the saved date. Improve UI elements in the PageEditor history timeline for better user experience. Signed-off-by: Innei <tukon479@gmail.com> * Add document history management features and improve API integration - Introduced constants for document history retention and limits. - Updated document history service to compact history based on new retention limits. - Refactored PageEditor to utilize constants for document history limits. - Added new TRPC router for document history management. - Enhanced JSON diffing capabilities for better patching of document history. Signed-off-by: Innei <tukon479@gmail.com> * ♻️ refactor: sync document history schema and simplify history service - Sync simplified document_history table from feat/document-history-db - Remove version/storage_kind/payload/base_version, use editor_data + saved_at - Rewrite pagination with composite (savedAt, id) cursor - Update TRPC APIs from version-based to historyId-based - Replace DocumentVersionControl with AutoSaveHint - Add integration tests for history service * ✨ feat: add per-source document history retention limits - autosave / manual: retain 20 entries each - restore / system: retain 5 entries each - trimHistoryBySource now deletes in batches of 100 to avoid unbounded overflow - removed obsolete constants: PATCH_THRESHOLD, RETENTION_LIMIT, SNAPSHOT_INTERVAL - added integration tests for large overflow trimming * ✨ add llm_call history source and queue-based snapshot for page agent * 💄 restyle document history list to Notion timeline * 💄 fix history timeline alignment, unify fonts and highlight current * ✨ feat(PageEditor): refine document history compare UI and date formatting Made-with: Cursor * ✨ feat(editor): add validation for editor data and update related interfaces - Introduced `isValidEditorData` function to validate editor data structure. - Updated `GetHistoryItemOutput` and `DocumentHistoryItemResult` interfaces to allow `editorData` to be `null`. - Modified `getDocumentEditorData` to return `null` for invalid editor data. - Added integration tests to ensure proper handling of invalid editor data in document history service. - Enhanced editor actions to prevent saving of invalid editor data. Signed-off-by: Innei <tukon479@gmail.com> * 💾 chore(database): split document history indexes * Fix manual saves and optimize history item rendering * 🌐 locale: add missing llm_call translation key in en-US file.json Add pageEditor.history.saveSource.llm_call = \"AI Edit\" to match the default locale and prevent raw i18n key from showing in the history panel. --------- Signed-off-by: Innei <tukon479@gmail.com>
* 🐛 fix(desktop): prevent invalid proxy toggle saves
* 🩹 fix: close proxy form ci gaps
* ✨ style: enhance SaveBar component with updated styles and improved color variables
Signed-off-by: Innei <tukon479@gmail.com>
* 🩹 fix(test): increase ProxyForm test timeout and add explicit delay: null
CI runs with coverage instrumentation cause these form-interaction
tests to take ~4–6s each, exceeding the default 5000ms timeout.
Increase describe timeout to 10000ms and add { delay: null } to
all user.type() calls to keep them stable under coverage.
* 🩹 fix(test): resolve ProxyForm test type errors with user-event v14
---------
Signed-off-by: Innei <tukon479@gmail.com>
* ♻️ refactor(desktop): consolidate global shortcuts and remove default showApp hotkey - Add desktopGlobalShortcuts.ts as single source for Electron + renderer defaults - Wire ShortcutManager and store to DEFAULT_ELECTRON_DESKTOP_SHORTCUTS - Use DesktopHotkeyId for @shortcut; drop local shortcuts barrel - Stop re-exporting DESKTOP_HOTKEYS_REGISTRATION from hotkeys Fixes LOBE-7181 Made-with: Cursor * ✨ feat(desktop): introduce new stubs for business constants and types - Added `@lobechat/business-const` and `@lobechat/types` packages to support workspace dependency resolution. - Updated `package.json` and `pnpm-workspace.yaml` to include new stubs. - Refactored imports in `index.ts` to utilize the new constants structure. - Enhanced `desktopGlobalShortcuts.ts` with improved type definitions for hotkeys. This change streamlines the management of constants and types across the desktop application. Signed-off-by: Innei <tukon479@gmail.com> * ♻️ refactor(hotkeys): consolidate desktop global shortcut definitions (LOBE-7181) Made-with: Cursor * ✨ feat(session, user): replace direct type imports with constants - Updated session.ts to use constants for session types instead of direct imports from @lobechat/types. - Updated user.ts to use a constant for the default topic display mode, enhancing consistency and maintainability. This change improves code clarity and reduces dependencies on external type definitions. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>
* 🔖 chore(release): release version v2.1.50 [skip ci] * 📝 docs: Update changelog docs and release skills (#13897) * 🔨 chore: update .vscode/settings.json (#13894) * 🐛 fix(builtin-tool-local-system): honor glob scope in local system tool (#13875) Made-with: Cursor * 📝 docs: Update changelog docs and release skills (#13897) - Update changelog documentation format across all historical changelog files - Merge release-changelog-style skill into version-release skill - Update changelog examples with improved formatting and structure Made-with: Cursor --------- Co-authored-by: YuTengjing <ytj2713151713@gmail.com> Co-authored-by: Innei <i@innei.in> * 🐛 fix: resolve merge conflicts in sync main to canary Restore canary versions of skill docs that were overwritten during main-to-canary sync, keeping #13899 improvements intact. --------- Co-authored-by: CanisMinor <i@canisminor.cc> Co-authored-by: YuTengjing <ytj2713151713@gmail.com> Co-authored-by: Innei <i@innei.in> Co-authored-by: Innei <tukon479@gmail.com>
…sume (#13902) 🐛 fix: persist ccSessionId in topic metadata for CC multi-turn resume The renderer writes `ccSessionId` to topic metadata after each Claude Code execution so the next turn can spawn `claude --resume <id>`, but the server zod schema on `updateTopicMetadata` didn't list `ccSessionId`, so zod silently stripped it — every turn started a fresh CC session and lost prior context.
* fix: should inject the user Locals Language into systemRole * fix: slove the ts * fix: update the snapshot test * fix: update the test.ts * fix: test fixed
…roup block (#13904) Made-with: Cursor
* 🐛 fix: show success status for tool calls with no return value When a tool call completes without returning content, the status indicator was incorrectly showing a loading spinner instead of a success checkmark. This fix passes the isToolCalling operation state to StatusIndicator to correctly determine when a tool has finished executing. https://claude.ai/code/session_01EBaKqzVTeEmrUXgFdNk7WH * 🐛 fix(conversation): improve tool execution status handling Updated the logic for determining tool execution states in both the Tool and Inspector components. The changes ensure that the status indicator accurately reflects when a tool is actively processing, even if no result is returned. This prevents misleading loading indicators and enhances user experience during tool interactions. Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(DocumentHistoryDiff): correct JSX syntax for CircleLoading component Removed unnecessary semicolon from CircleLoading component in DocumentHistoryDiff to ensure proper rendering. This minor fix enhances code clarity and maintains JSX standards. Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(ModeSwitch.test): refactor tests to improve readability and performance Updated the ModeSwitch test suite by removing unnecessary async/await patterns, simplifying the mock configuration, and ensuring consistent cleanup after each test. These changes enhance the clarity and efficiency of the test cases for the onboarding mode switch functionality. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com> Co-authored-by: Claude <noreply@anthropic.com>
fix: remove 'Management' from API Key tab title
* fix: slove the manual mode cant use some builtin tools * refactor: change the active skill tools from lobe-activtor to lobe-skill tools * fix: only inject the avaiable skill when use the auto mode * fix: update the desktop tools skill * fix: add the some test to ensure the builin tools will use in manual mode
* ✨ feat: return full brief data in task activities (LOBE-7266) The activity feed for tasks previously emitted a stripped `brief` row that concatenated `resolvedAction` and `resolvedComment` and omitted everything BriefCard needs (taskId, topicId, agentId, cronJobId, agents, actions, artifacts, readAt, resolvedAt, etc.). Map the full `BriefItem` into each activity row and reuse `BriefService.enrichBriefsWithAgents` to populate the participant avatars. The CLI and prompt formatter now compose the action + comment display string themselves. * 🐛 fix: degrade gracefully when brief agent enrichment fails getTaskDetail was calling BriefService.enrichBriefsWithAgents inside Promise.all without a fallback, so a failure in the agent-tree lookup would reject the whole request — a regression vs. the existing .catch(() => []) pattern used by other activity reads in this method. Fall back to agentless briefs on error so the task detail keeps rendering.
…o `5.9.0` (#13920) 🐛 fix(app): right panel should use stableLayout, bump @lobehub/ui to 5.9.0
…ude code (#13754) * ♻️ refactor(acp): move agent provider to agencyConfig + restore creation entry - Move AgentProviderConfig from chatConfig to agencyConfig.heterogeneousProvider - Rename type from 'acp' to 'claudecode' for clarity - Restore Claude Code agent creation entry in sidebar + menu - Prioritize heterogeneousProvider check over gateway mode in execution flow - Remove ACP settings from AgentChat form (provider is set at creation time) - Add getAgencyConfigById selector for cleaner access - Use existing agent workingDirectory instead of duplicating in provider config Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ✨ feat(acp): defer terminal events + extract model/usage per turn Three improvements to ACP stream handling: 1. Defer agent_runtime_end/error: Previously the adapter emitted terminal events from result.type directly into the Gateway handler. The handler immediately fires fetchAndReplaceMessages which reads stale DB state (before we persist final content/tools). Fix: intercept terminal events in the executor's event loop and forward them only AFTER content + metadata has been written to DB. 2. Extract model/usage per assistant event: Claude Code sets model name and token usage on every assistant event. Adapter now emits a 'step_complete' event with phase='turn_metadata' carrying these. Executor accumulates input/output/cache tokens across turns and persists them onto the assistant message (model + metadata.totalTokens). 3. Missing final text fix: The accumulated assistant text was being written AFTER agent_runtime_end triggered fetchAndReplaceMessages, so the UI rendered stale (empty) content. Deferred terminals solve this. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> 🐛 fix(acp): eliminate orphan-tool warning flicker during streaming Root cause: LobeHub's conversation-flow parser (collectToolMessages) filters tool messages by matching `tool_call_id` against `assistant.tools[].id`. The previous flow created tool messages FIRST, then updated assistant.tools[], which opened a brief window where the UI saw tool messages that had no matching entry in the parent's tools array — rendering them as "orphan" with a scary "请删除" warning to the user. Fix: Reorder persistNewToolCalls into three phases: 1. Pre-register tool entries in assistant.tools[] (id only, no result_msg_id) 2. Create the tool messages in DB (tool_call_id matches pre-registered ids) 3. Back-fill result_msg_id and re-write assistant.tools[] Between phase 1 and phase 3 the UI always sees consistent state: every tool message in DB has a matching entry in the parent's tools array. Verified: orphan count stays at 0 across all sampled timepoints during streaming (vs 1+ before fix). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> 🐛 fix(acp): dedupe tool_use + capture tool_result + persist result_msg_id Three critical fixes to ACP tool-call handling, discovered via live testing: 1. **tool_use dedupe** — Claude Code stream-json previously produced 15+ duplicate tool messages per tool_call_id. The adapter now tracks emitted ids so each tool_use → exactly one tool message. 2. **tool_result content capture** — tool_result blocks live in `type: 'user'` events in Claude Code's stream-json, not in assistant events. The adapter now handles the 'user' event type and emits a new `tool_result` HeterogeneousAgentEvent which the executor consumes to call messageService.updateToolMessage() with the actual result content. Previously all tool messages had empty content. 3. **result_msg_id on assistant.tools[]** — LobeHub's parse() step links tool messages to their parent assistant turn via tools[].result_msg_id. Without it, the UI renders orphan-message warnings. The executor now captures the tool message id returned by messageService.createMessage and writes it back into the assistant.tools[] JSONB. Also adds vitest config + 9 unit tests for the adapter covering lifecycle, content mapping, and tool_result handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> ✨ feat(acp): integrate external AI agents via ACP protocol Adds support for connecting external AI agents (Claude Code and future agents like Codex, Kimi CLI) into LobeHub Desktop via a new heterogeneous agent layer that adapts agent-specific protocols to the unified Gateway event stream. Architecture: - New @lobechat/heterogeneous-agents package: pluggable adapters that convert agent-specific outputs to AgentStreamEvent - AcpCtr (Electron main): agent-agnostic process manager with CLI presets registry, broadcasts raw stdout lines to renderer - acpExecutor (renderer): subscribes to broadcasts, runs events through adapter, feeds into existing createGatewayEventHandler - Tool call persistence: creates role='tool' messages via messageService before emitting tool_start/tool_end to the handler Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: rename acpExecutor to heterogeneousAgentExecutor - Rename file acpExecutor.ts → heterogeneousAgentExecutor.ts - Rename ACPExecutorParams → HeterogeneousAgentExecutorParams - Rename executeACPAgent → executeHeterogeneousAgent - Change operation type from execAgentRuntime to execHeterogeneousAgent - Change operation label to "Heterogeneous Agent Execution" - Change error type from ACPError to HeterogeneousAgentError - Rename acpData/acpContext variables to heteroData/heteroContext Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: rename AcpCtr and acp service to heterogeneousAgent Desktop side: - AcpCtr.ts → HeterogeneousAgentCtr.ts - groupName 'acp' → 'heterogeneousAgent' - IPC channels: acpRawLine → heteroAgentRawLine, etc. Renderer side: - services/electron/acp.ts → heterogeneousAgent.ts - ACPService → HeterogeneousAgentService - acpService → heterogeneousAgentService - Update all IPC channel references in executor Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🔧 chore: switch CC permission mode to bypassPermissions Use bypassPermissions to allow Bash and other tool execution. Previously acceptEdits only allowed file edits, causing Bash tool calls to fail during CC execution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: don't fallback activeAgentId to empty string in AgentIdSync Empty string '' causes chat store to have a truthy but invalid activeAgentId, breaking message routing. Pass undefined instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: use AI_RUNTIME_OPERATION_TYPES for loading and cancel states stopGenerateMessage and cancelOperation were hardcoding ['execAgentRuntime', 'execServerAgentRuntime'], missing execHeterogeneousAgent. This caused: - CC execution couldn't be cancelled via stop button - isAborting flag wasn't set for heterogeneous agent operations Now uses AI_RUNTIME_OPERATION_TYPES constant everywhere to ensure all AI runtime operation types are handled consistently. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✨ feat: split multi-step CC execution into separate assistant messages Claude Code's multi-turn execution (thinking → tool → final text) was accumulating everything onto a single assistant message, causing the final text response to appear inside the tool call message. Changes: - ClaudeCodeAdapter: detect message.id changes and emit stream_end + stream_start with newStep flag at step boundaries - heterogeneousAgentExecutor: on newStep stream_start, persist previous step's content, create a new assistant message, reset accumulators, and forward the new message ID to the gateway handler This ensures each LLM turn gets its own assistant message, matching how Gateway mode handles multi-step agent execution. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: fix multi-step CC execution and add DB persistence tests Adapter fixes: - Fix false step boundary on first assistant after init (ghost empty message) Executor fixes: - Fix parentId chain: new-step assistant points to last tool message - Fix content contamination: sync snapshot of content accumulators on step boundary - Fix type errors (import path, ChatToolPayload casts, sessionId guard) Tests: - Add ClaudeCodeAdapter unit tests (multi-step, usage, flush, edge cases) - Add ClaudeCodeAdapter E2E test (full multi-step session simulation) - Add registry tests - Add executor DB persistence tests covering: - Tool 3-phase write (pre-register → create → backfill) - Tool result content + error persistence - Multi-step parentId chain (assistant → tool → assistant) - Final content/reasoning/model/usage writes - Sync snapshot preventing cross-step contamination - Error handling with partial content persistence - Full multi-step E2E (Read → Write → text) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🔧 chore: add orphan tool regression tests and debug trace - Add orphan tool regression tests for multi-turn tool execution - Add __HETERO_AGENT_TRACE debug instrumentation for event flow capture Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✨ feat: support image attachments in CC via stream-json stdin - Main process downloads files by ID from cloud (GET {domain}/f/{fileId}) - Local disk cache at lobehub-storage/heteroAgent/files/ (by fileId) - When fileIds present, switches to --input-format stream-json + stdin pipe - Constructs user message with text + image content blocks (base64) - Pass fileIds through executor → service → IPC → controller Closes LOBE-7254 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: pass imageList instead of fileIds for CC vision support - Use imageList (with url) instead of fileIds — Main downloads from URL directly - Cache by image id at lobehub-storage/heteroAgent/files/ - Only images (not arbitrary files) are sent to CC via stream-json stdin Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: read imageList from persisted DB message instead of chatUploadFileList chatUploadFileList is cleared after sendMessageInServer, so tempImages was empty by the time the executor ran. Now reads imageList from the persisted user message in heteroData.messages instead. Also removes debug console.log/console.error statements. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * update i18n * 🐛 fix: prevent orphan tool UI by deferring handler events during step transition Root cause: when a CC step boundary occurs, the adapter produces [stream_end, stream_start(newStep), stream_chunk(tools_calling)] in one batch. The executor deferred stream_start via persistQueue but forwarded stream_chunk synchronously — handler received tools_calling BEFORE stream_start, dispatching tools to the OLD assistant message → UI showed orphan tool warning. Fix: add pendingStepTransition flag that defers ALL handler-bound events through persistQueue until stream_start is forwarded, guaranteeing correct event ordering. Also adds: - Minimal regression test in gatewayEventHandler confirming correct ordering - Multi-tool per turn regression test from real LOBE-7240 trace - Data-driven regression replaying 133 real CC events from regression.json Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✨ feat: add lab toggle for heterogeneous agent (Claude Code) - Add enableHeterogeneousAgent to UserLabSchema + defaults (off by default) - Add selector + settings UI toggle (desktop only) - Gate "Claude Code Agent" sidebar menu item behind the lab setting - Remove regression.json (no longer needed) - Add i18n keys for the lab feature Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: gate heterogeneous agent execution behind isDesktop check Without this, web users with an agent that has heterogeneousProvider config would hit the CC execution path and fail (no Electron IPC). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ♻️ refactor: rename tool identifier from acp-agent to claude-code Also update operation label to "External agent running". Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✨ feat: add CLI agent detectors for system tools settings Detect agentic coding CLIs installed on the system: - Claude Code, Codex, Gemini CLI, Qwen Code, Kimi CLI, Aider - Uses validated detection (which + --version keyword matching) - New "CLI Agents" category in System Tools settings - i18n for en-US and zh-CN Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🐛 fix: fix token usage over-counting in CC execution Two bugs fixed: 1. Adapter: same message.id emitted duplicate step_complete(turn_metadata) for each content block (thinking/text/tool_use) — all carry identical usage. Now deduped by message.id, only emits once per turn. 2. Executor: CC result event contains authoritative session-wide usage totals but was ignored. Now adapter emits step_complete(result_usage) from the result event, executor uses it to override accumulated values. Fixes LOBE-7261 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🔧 chore: gitignore cc-stream.json and .heterogeneous-tracing/ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * 🔧 chore: untrack .heerogeneous-tracing/ Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * ✨ feat: wire CC session resume for multi-turn conversations Reads `ccSessionId` from topic metadata and passes it as `resumeSessionId` into the heterogeneous-agent executor, which forwards it into the Electron main-process controller. `sendPrompt` then appends `--resume <id>` so the next turn continues the same Claude Code session instead of starting fresh. After each run, the CC init-event session_id (captured by the adapter) is persisted back onto the topic so the chain survives page reloads. Also stops killing the session in `finally` — it needs to stay alive for subsequent turns; cleanup happens on topic deletion or app quit. * 🐛 fix: record cache token breakdown in CC execution metadata The prior token-usage fix only wrote totals — `inputCachedTokens`, `inputWriteCacheTokens` and `inputCacheMissTokens` were dropped, so the pricing card rendered zero cached/write-cache tokens even though CC had reported them. Map the accumulated Anthropic-shape usage to the same breakdown the anthropic usage converter emits, so CC turns display consistently with Gateway turns. Refs LOBE-7261 * ♻️ refactor: write CC usage under metadata.usage instead of flat fields Flat `inputCachedTokens / totalInputTokens / ...` on `MessageMetadata` are the legacy shape; new code should put usage under `metadata.usage`. Move the CC executor to the nested shape so it matches the convention the rest of the runtime is migrating to. Refs LOBE-7261 * ♻️ refactor(types): mark flat usage fields on MessageMetadata as deprecated Stop extending `ModelUsage` and redeclare each token field inline with a `@deprecated` JSDoc pointing to `metadata.usage` (nested). Existing readers still type-check, but IDEs now surface the deprecation so writers migrate to the nested shape. * ♻️ refactor(types): mark flat performance fields on MessageMetadata as deprecated Stop extending `ModelPerformance` and redeclare `duration` / `latency` / `tps` / `ttft` inline with `@deprecated`, pointing at `metadata.performance`. Mirrors the same treatment just done for the token usage fields. * ✨ feat: CC agent gets claude avatar + lands on chat page directly Skip the shared createAgent hook's /profile redirect for the Claude Code variant — its config is fixed so the profile editor would be noise — and preseed the Claude avatar from @lobehub/icons-static-avatar so new CC agents aren't blank. * 🐛 fix(conversation-flow): read usage/performance from nested metadata `splitMetadata` only scraped the legacy flat token/perf fields, so messages written under the new canonical shape (`metadata.usage`, `metadata.performance`) never populated `UIChatMessage.usage` and the Extras panel rendered blank. - Prefer nested `metadata.usage` / `metadata.performance` when present; keep flat scraping as fallback for pre-migration rows. - Add `usage` / `performance` to FlatListBuilder's filter sets so the nested blobs don't leak into `otherMetadata`. - Drop the stale `usage! || metadata` fallback in the Assistant / CouncilMember Extra renders — with splitMetadata fixed, `item.usage` is always populated when usage data exists, and passing raw metadata as ModelUsage is wrong now that the flat fields are gone. * 🐛 fix: skip stores.reset on initial dataSyncConfig hydration `useDataSyncConfig`'s SWR onSuccess called `refreshUserData` (which runs `stores.reset()`) whenever the freshly-fetched config didn't deep-equal the hard-coded initial `{ storageMode: 'cloud' }` — which happens on every first load. The reset would wipe `chat.activeAgentId` just after `AgentIdSync` set it from the URL, and because `AgentIdSync`'s sync effects are keyed on `params.aid` (which hasn't changed), they never re-fire to restore it. Result: topic SWR saw `activeAgentId === ''`, treated the container as invalid, and left the sidebar stuck on the loading skeleton. Gate the reset on `isInitRemoteServerConfig` so it only runs when the user actually switches sync modes, not on the first hydration. * ✨ feat(claude-code): wire Inspector layer for CC tool calls Mirrors local-system: each CC tool now has an inspector rendered above the tool-call output instead of an opaque default row. - `Inspector.tsx` — registry that passes the CC tool name itself as the shared factories' `translationKey`. react-i18next's missing-key fallback surfaces the literal name (Bash / Edit / Glob / Grep / Read / Write), so we don't add CC-specific entries to the plugin locale. - `ReadInspector.tsx` / `WriteInspector.tsx` — thin adapters that map Anthropic-native args (`file_path` / `offset` / `limit`) onto the shared inspectors' shape (`path` / `startLine` / `endLine`), so shared stays pure. Bash / Edit / Glob / Grep reuse shared factories directly. - Register `ClaudeCodeInspectors` under `claude-code` in the builtin-tools inspector dispatch. Also drops the redundant `Render/Bash/index.tsx` wrapper and pipes the shared `RunCommandRender` straight into the registry. * ♻️ refactor: use agentSelectors.isCurrentAgentHeterogeneous Two callsites (ConversationArea / useActionsBarConfig) were reaching into `currentAgentConfig(...)?.agencyConfig?.heterogeneousProvider` inline. Switch them to the existing `isCurrentAgentHeterogeneous` selector so the predicate lives in one place. * update * ♻️ refactor: drop no-op useCallback wrapper in AgentChat form `handleFinish` just called `updateConfig(values)` with no extra logic; the zustand action is already a stable reference so the wrapper added no memoization value. Leftover from the ACP refactor (930ba41) where the handler once did more work — hand the action straight to `onFinish`. * update * ⏪ revert: roll back conversation-flow nested-shape reads Unwind the `splitMetadata` nested-preference + `FlatListBuilder` filter additions from 306fd65. The nested `metadata.usage` / `metadata.performance` promotion now happens in `parse.ts` (and a `?? metadata?.usage` fallback at the UI callsites), so conversation-flow's transformer layer goes back to its original flat-field-only behavior. * update * 🐛 fix(cc): wire Stop to cancel the external Claude Code process Previously hitting Stop only flipped the `execHeterogeneousAgent` operation to `cancelled` in the store — the spawned `claude -p` process kept running and kept streaming/persisting output for the user. The op's abort signal had no listeners and no `onCancelHandler` was registered. - On session start, register an `onCancelHandler` that calls `heterogeneousAgentService.cancelSession(sessionId)` (SIGINT to the CLI). - Read the op's `abortController.signal` and short-circuit `onRawLine` so late events the CLI emits between SIGINT and exit don't leak into DB writes. - Skip the error-event forward in `onError` / the outer catch when the abort came from the user, so the UI doesn't surface a misleading error toast on top of the already-cancelled operation. Verified end-to-end: prompt that runs a long sequence of Reads → click Stop → `claude -p` process is gone within 2s, op status = cancelled, no error message written to the conversation. * ✨ feat(sidebar): mark heterogeneous agents with an "External" tag Pipes the agent's `agencyConfig.heterogeneousProvider.type` through the sidebar data flow and renders a `<Tag>` next to the title for any agent driven by an external CLI runtime (Claude Code today, more later). Mirrors the group-member External pattern so future provider types just need a label swap — the field is a string, not a boolean. - `SidebarAgentItem.heterogeneousType?: string | null` on the shared type - `HomeRepository.getSidebarAgentList` selects `agents.agencyConfig` and derives the field via `cleanObject` - `AgentItem` shows `<Tag>{t('group.profile.external')}</Tag>` when the field is present Verified client-side by injecting `heterogeneousType: 'claudecode'` into a sidebar item at runtime — the "外部" tag renders next to the title in the zh-CN locale. * ♻️ refactor(i18n): dedicated key for the sidebar external-agent tag Instead of reusing `group.profile.external` (which is about group members that are user-linked rather than virtual), add `agentSidebar.externalTag` specifically for the heterogeneous-runtime tag. Keeps the two concepts separate so we can swap this one to "Claude Code" / provider-specific labels later without touching the group UI copy. Remember to run `pnpm i18n` before the PR so the remaining locales pick up the new key. * 🐛 fix: clear remaining CI type errors Three small fixes so `tsgo --noEmit` exits clean: - `AgentIdSync`: `useChatStoreUpdater` is typed off the chat-store key, whose `activeAgentId` is `string` (initial ''). Coerce the optional URL param to `''` so the store key type matches; `createStoreUpdater` still skips the setState when the value is undefined-ish. - `heterogeneousAgentExecutor.test.ts`: `scope: 'session'` isn't a valid `MessageMapScope` (the union dropped that variant); switch the fixture to `'main'`, which is the correct scope for agent main conversations. - Same test file: `Array.at(-1)` is `T | undefined`; non-null assert since the preceding calls guarantee the slot is populated. * 🐛 fix: loosen createStoreUpdater signature to accept nullable values Upstream `createStoreUpdater` types `value` as exactly `T[Key]`, so any call site feeding an optional source (URL param, selector that may return undefined) fails type-check — even though the runtime already guards `typeof value !== 'undefined'` and no-ops in that case. Wrap it once in `store/utils/createStoreUpdater.ts` with a `T[Key] | null | undefined` value type so callers can pass `params.aid` directly, instead of the lossy `?? ''` fallback the previous commit used (which would have written an empty-string sentinel into the chat store). Swap the import in `AgentIdSync.tsx`. --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
style: add qwen3.6-flash/plus & pixverse-c1 support
…13853) * ✨ feat(onboarding): enhance agent onboarding experience and add feature flags - Added new promotional messages for agent onboarding in both Chinese and default locales. - Updated HighlightNotification component to support action handling and target attributes. - Introduced feature flags for agent onboarding in the configuration schema and tests. - Implemented logic to conditionally display onboarding options based on feature flags and user state. - Added tests for the onboarding flow and promotional notifications in the footer. This update aims to improve the user experience during the onboarding process and ensure proper feature management through flags. Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(home): add footer promotion pipeline with feature-flag gating Extract resolveFooterPromotionState for agent onboarding vs Product Hunt promos. Normalize isMobile boolean, refine HighlightNotification CTA layout, extend tests. Made-with: Cursor * ✨ feat(locales): add agent onboarding promotional messages in multiple languages Added new promotional messages for agent onboarding across various locales, enhancing the user experience with localized action labels, descriptions, and titles. This update supports a more engaging onboarding process for users globally. Signed-off-by: Innei <tukon479@gmail.com> * 💄 chore: refresh quick wizard onboarding promo * 🐛 fix(chat): keep long mixed assistant content outside workflow fold * ✨ feat(onboarding): add agent onboarding feedback panel and service LOBE-7210 Made-with: Cursor * ✨ feat(markdown-patch): add shared markdown patch tool with SEARCH/REPLACE hunks Introduce @lobechat/markdown-patch util and expose patchDocument API on the web-onboarding and agent-documents builtin tools so agents can apply byte-exact SEARCH/REPLACE hunks instead of resending full document content. * ✨ feat(onboarding): prefer patchDocument for non-empty documents Teach the onboarding agent (systemRole) and context engine (OnboardingActionHintInjector) to prefer patchDocument over updateDocument when SOUL.md or User Persona already has content, keeping updateDocument reserved for the initial seed write or full rewrites. * 🐛 fix(conversation): add rightActions to ChatInput component Updated the AgentOnboardingConversation component to include rightActions in the ChatInput, enhancing the functionality of the onboarding conversation interface. Signed-off-by: Innei <tukon479@gmail.com> * Add specialized onboarding approval UI * 🐛 fix(serverConfig): handle fetch errors in server config actions Updated the server configuration action to include error handling for fetch failures, ensuring that the server config is marked as initialized when an error occurs. Additionally, modified the SWR mock to simulate error scenarios in tests. Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(tests): update Group component tests with new data-testid attributes Added data-testid attributes for workflow and answer segments in the Group component tests to improve test targeting. Adjusted the isFirstBlock property for consistency and ensured the component renders correctly with the provided props. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>
…13916) 🐛 fix(auth): clear current-browser OIDC session on sign-out When a user signs out and signs back in as a different account, the oidc-provider session cookie (_session) still references the old accountId. The next /authorize silently reuses it, issuing tokens for the wrong user. Fix: add a POST /oidc/clear-session endpoint that: 1. Reads the _session cookie from the current request 2. Deletes the matching row in oidc_sessions (by primary key) 3. Expires the _session cookies in the response The frontend logout action calls this endpoint *before* signOut() while the better-auth session is still valid. Only the current browser's OIDC session is affected — other devices (desktop, CLI, mobile) keep their sessions intact.
* ♻️ refactor: adopt Notebook list + EditorCanvas for agent documents
The agent working sidebar previously used a FileTree directory view and
a hand-rolled Markdown+TextArea editor with manual save. Agent documents
already back onto the canonical `documents` table via an FK, so they can
reuse the exact same rendering surface as Notebook.
- AgentDocumentsGroup: replace FileTree with a flat card list styled
after Portal/Notebook/DocumentItem (icon + title + description + delete).
- AgentDocumentEditorPanel: drop the bespoke draft/save/segmented view
logic; mount the shared <EditorCanvas documentId={doc.documentId}
sourceType="notebook" /> inside an EditorProvider so auto-save and
rich editing are handled by useDocumentStore.
* ✨ feat: promote agent documents as the primary workspace panel
- Replace the agent-document sidebar with a Notebook-style list: pill
filter (All/Docs/Web), per-item createdAt, globe icon for sourceType=web.
- Add a stable panel header "Resources" with a close button (small size,
consistent with other chat header actions); no border divider.
- Wire clicks to the shared Portal Document view via openDocument(),
retiring the inline AgentDocumentEditorPanel.
- Portal/Document/Header now resolves title directly from documentId
via documentService.getDocumentById + a skeleton loading state.
- Portal top-right close icon switched to `X`.
- Layout: move AgentWorkingSidebar to the rightmost position; auto-collapse
the left navigation sidebar while Portal is open (PortalAutoCollapse).
- Header: remove dead NotebookButton, drop the Notebook menu item; add a
WorkingPanelToggle visible only when the working panel is collapsed.
- ProgressSection hides itself when the topic has no GTD todos.
- Builtin tool list removes Notebook; migrate CreateDocument Render and
Streaming renderers to builtin-tool-agent-documents (notebook package
kept for legacy rendering of historical tool calls).
- agent_documents list UI now reads from a separate SWR key
(documentsList) so the agent-store context mapping doesn't strip
documentId/sourceType/createdAt from the UI payload.
- i18n: add workingPanel.resources.filter.{all,documents,web},
viewMode.{list,tree}, and the expanded empty-state copy; zh-CN
translations seeded for preview.
- New local-testing reference: agent-browser-login (inject better-auth
cookie for authenticated agent-browser sessions).
* update
* 🐛 fix: satisfy tsc strict i18next keys, remove duplicate getDocumentById, coerce showLeftPanel
* ♻️ refactor: graduate agent working panel out of labs
…13929) ✨ feat(cc-partial-messages): stream token-level deltas via --include-partial-messages Enables Claude Code's --include-partial-messages flag so the CLI emits token-level deltas wrapped in stream_event events. The adapter surfaces these deltas as incremental stream_chunk events and suppresses the trailing full-block emission from handleAssistant for any message.id whose text/thinking has already been streamed. Message-boundary handling is refactored into an idempotent openMainMessage() helper so stepIndex advances on the first signal of a new turn (delta or assistant), keeping deltas attached to the correct step. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…es (#13937) * Keep heterogeneous-agent attachment cache writes inside the cache root The desktop heterogeneous-agent controller used raw image ids as path segments for cache payload and metadata files. Path-like ids could escape the intended cache directory, and pre-seeded traversal targets could be treated as cache hits. Hashing the cache key removes any path semantics from user-controlled ids while preserving stable cache reuse. A regression test covers both out-of-root write prevention and ignoring pre-seeded traversal cache files. Constraint: The fix must preserve deterministic cache hits without trusting user-controlled path segments Rejected: path.basename(image.id) | collapses distinct ids onto the same filename and leaves edge-case normalization concerns Confidence: high Scope-risk: narrow Reversibility: clean Directive: Any future cache layout change must keep user-controlled identifiers out of direct filesystem path composition Tested: Custom local reproduction against current controller source; custom local validation against patched source; regression test added for desktop controller path handling Not-tested: Upstream vitest/CI run in this workspace (desktop dependencies unavailable locally) * Keep heterogeneous-agent cache regression aligned with runtime MIME behavior The traversal regression test uses a data:text/plain URL under the desktop node test environment, so the controller returns text/plain from the fetch response headers. The expectation now matches the actual runtime behavior instead of assuming the image/png fallback path. Constraint: The regression should validate cache isolation rather than rely on an incorrect MIME fallback assumption Rejected: Mock fetch in the regression test | adds extra indirection without improving the path traversal coverage Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep this test focused on path safety and cache-hit behavior; avoid coupling it to unrelated transport mocks unless the controller logic changes Tested: Local patched-controller validation harness; static review against desktop vitest node environment behavior Not-tested: Upstream vitest/CI run in this workspace (desktop dependencies unavailable locally) * Keep heterogeneous-agent cache regression isolated to the temp test namespace The first regression test used a fixed traversal target name under the shared system temp directory. Switching that escape target to a unique name derived from the test's temporary appStoragePath preserves the same out-of-root check while avoiding accidental interaction with unrelated files under /tmp. Constraint: The regression must still verify escape prevention beyond appStoragePath without touching shared fixed temp paths Rejected: Remove the out-of-root assertion entirely | weakens coverage for the exact traversal behavior this PR is meant to guard Confidence: high Scope-risk: narrow Reversibility: clean Directive: Keep filesystem regressions hermetic; if a test needs to reason about escaped paths, derive them from per-test temp namespaces whenever possible Tested: Static review of resolved path behavior before/after the change Not-tested: Upstream vitest/CI run in this workspace (desktop dependencies unavailable locally) --------- Co-authored-by: OpenAI Codex <codex@example.com>
…13945) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…#14193) * 🐛 fix(conversation): disable first assistant block markdown streaming * Add assistant group generating selector * 🐛 fix(conversation): preserve workflow block markdown streaming * ✅ test(conversation): mock assistant group generating selector
…nt turn (#14182) * 🐛 fix(agent-runtime): scope pending-approval check to current assistant turn A stale `pluginIntervention.status === 'pending'` row from a prior turn (e.g. an abandoned approval flow whose user never clicked approve/reject) gets loaded back into `state.messages` via `historyMessages`, hijacks every subsequent `tool_result` / `tools_batch_result` phase, and parks the loop in `waiting_for_human` forever — so after a tool call succeeds, the next LLM call is never scheduled. Scope the pending check to tool messages whose `parentId` matches the current assistant turn (the most recent assistant with `tool_calls`). * ✅ test(agent-runtime): cover persisted tools pending approvals
* feat: support dm policy * feat: update channels docs about dm strategy * feat: add dm reject policy docs and default to open * feat: add platform reply locale * feat: discord extract locale * feat: optimize locale ack messages * fix: qq platform respond twice * feat: support dm policy and group policy * feat: add userID to allowList * feat: support white list form * fix: group policy * fix: bot slash commands passby
* ✨ feat(conversation): persist per-topic chat scroll position to localStorage Restores scroll position when switching back to a topic, keyed by messageMapKey(context). Falls back to scroll-to-bottom for new topics or when the user was already at the bottom. Storage is capped at 500 entries with 30-day expiry and silent fallback on quota errors. Fixes LOBE-8251 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🔨 chore(conversation): rename scroll snapshot storage prefix to LOBEHUB Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🔨 chore(conversation): use LOBEHUB_SCROLL as scroll snapshot key prefix Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(conversation): preserve scroll across draft-to-topic key transition When a draft conversation (`*_new` key) gets promoted to a real topic via onTopicCreated, the contextKey changes mid-stream for the same logical conversation. Treating it as a topic switch loaded a missing snapshot and fell back to scrollToIndex(end), yanking users away from content they were reading. Now we detect the draft-promotion shape, migrate the snapshot to the new key, and skip the restore pass while data is already on screen. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🔥 chore(settings): remove queryRewrite system agent Removes the unused knowledge-base query rewrite system agent: settings UI in agent/service-model pages, type definition, default config, store selector, server env parser, locale strings across 18 languages, env-variable docs, and the now-orphan chainRewriteQuery prompt chain. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* 💄 style(chat-input): drop @-mention hint from follow-up placeholder for heterogeneous agents Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 💄 style(home): hide suggested questions when agent task flag is on Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ✨ feat(task): wire QStash-driven heartbeat self-rescheduling Implements LOBE-8233: heartbeat tasks now self-arm via QStash delayed publish (or LocalScheduler setTimeout in dev). After each topic completes, TaskLifecycleService re-arms the next tick based on current DB state, with a 3-strike fuse on consecutive errors and a skip-when-urgent-brief guard. Adds /heartbeat-tick + /watchdog workflow handlers (signed) and extracts TaskRunnerService from the task.run mutation so both router and tick handler share one runner. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🐛 fix(task): unblock heartbeat fuse + safe overlap handling + TaskItem typing - TaskLifecycle re-arm now excludes type='error' urgent briefs from the human-waiting check; the fresh error brief from onTopicComplete was always present and stalled retries after the very first failure, making the 3-strike fuse unreachable. - TaskRunner only rolls back running→paused when *this* invocation set the running state; heartbeatTick treats CONFLICT as a graceful 'in-flight' skip so overlapping ticks don't 500 or clobber the in-flight run's status. - buildTaskPrompt now types its task arg + getReviewConfig as TaskItem (the prompts package already depends on @lobechat/types) so server TaskModel methods are assignable without parameter contravariance errors. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ♻️ refactor(task): extract qstashAuth Hono middleware for webhook signature verification Three handlers (on-topic-complete, heartbeat-tick, watchdog) duplicated the same `c.req.text() → verifyQStashSignature → 401` boilerplate. Extracted to src/server/workflows-hono/middlewares/qstashAuth.ts and mounted on the routes; handlers now just `c.req.json()` (Hono cross-converts the cached body so the middleware reading text() doesn't break json() in the handler). Note: this is for one-shot QStash webhook receivers. Upstash *Workflow* endpoints (memory-user-memory) keep using `serve()` from `@upstash/workflow/hono`, which has its own built-in verification. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ♻️ refactor(task): move buildTaskPrompt back to server (it's a DB orchestrator, not a renderer) Putting buildTaskPrompt under @lobechat/prompts was a layering mistake: the function does ~10 DB calls (briefs / topics / subtasks / dep identifier resolution / parent task assembly) and just maps the rows through to buildTaskRunPrompt at the end. The prompts package should stay pure rendering — buildTaskRunPrompt already lives there as the actual renderer. Moving the orchestrator back to src/server/services/taskRunner/ also lets it import model classes directly instead of structurally-typed deps, dropping the TaskPromptDeps abstraction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Made-with: Cursor
* ✨ feat(cmdk): show agent identity on topic search results When two topics share the same title (e.g. customer email used as topic name), the Cmd+K search results were indistinguishable. Surface the owning agent's avatar + title before the date so users can tell them apart at a glance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * 🔒 fix(cmdk): scope topic→agent join to current user Prevent cross-tenant agent metadata (avatar / backgroundColor / title) from leaking into Cmd+K topic search results when a topic row carries an agentId that resolves to another user's agent — a state reachable via crafted/migrated rows where topic creation persists input.agentId even after resolveContext fails. The agents JOIN now matches on (id AND agents.userId = current user); mismatched rows fall through as null and the renderer omits the agent chip rather than surfacing foreign data. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…eceiving feedback dynamically, for memory (#14187)
…rules (#14134) When users mention Klavis-managed services (Notion, Slack, Google Drive, Airtable, Jira, Figma, etc.), the activator now recognizes these as credential/connection intents and activates lobe-creds automatically. This enables the full Klavis OAuth flow to be triggered inline without requiring the user to manually navigate to settings. Related to #14090
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 57781850ce
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🐳 Database Docker Build Completed!Version: Pull ImageDownload the Docker image to your local machine: docker pull lobehub/lobehub:pr-release-weekly-20260427-62c4210Important This build is for testing and validation purposes. |
🚀 Desktop App Build Completed!Version: 📦 Release Download · 📥 Actions Artifacts Build Artifacts
Warning Note: This is a temporary build for testing purposes only. |
🚀 LobeHub v2.1.53 (20260427)
Release Date: April 27, 2026
Since v2.1.52: 194 merged PRs · 17 contributors
✨ Highlights
Cmd+W/Cmd+Ttab shortcuts with misc desktop polish #13983, ✨ feat(electron): add + button to TabBar for new topic in active context #13972, ♻️ refactor(desktop): increase recent working directories from 5 to 20 with scroll container #14036, 🐛 fix(desktop): surface human approval notifications #14092)@lobechat/agent-signalruntime for dynamic memory feedback signals, with OTel metrics and self-iteration in Lab. (✨ feat(agent-signal): created new package agent-signal #14157, ✨ feat(agent-signal): added AgentSignalRuntime #14170, ✨ feat(agent-signal,agent-tracing,observability-otel): added o11y metrics,agent-tracingfor rendering-Sfor signals #14159, ✨ feat(agent-signal,app,const,types): added self interation into lab, and feature flag #14169, ✨ feat(agent-signal,agent-signal/policies): added signal policy for receiving feedback and update memory as needed #14187)xhigheffort tier, GPT-5.5, DeepSeek V4 Flash/Pro with reasoning slider, Kimi K2.6, MiMo-V2.5/Pro, gpt-image-2, Qwen3.6 Flash/Plus, and Pixverse-c1. (✨ feat: add Claude Opus 4.7 with xhigh effort tier #13903, ✨ feat: add GPT-5.5 model support #14147, ✨ feat(deepseek): add V4 Flash/Pro cards + reasoning_effort slider #14114, 💄 style: add new Kimi K2.6 model #14004, ✨ feat: add MiMo-V2.5 and MiMo-V2.5-Pro model cards #14089, ✨ feat: add gpt-image-2 to LobeHub-hosted card #14039, 💄 style: add qwen3.6-flash/plus & pixverse-c1 support #13923)🏗️ Heterogeneous Agent
isCanUseVisiondefault and add aggregator fallback. (🐛 fix(agent-runtime): tighten isCanUseVision default and add aggregator fallback #14172)ccSessionIdin topic metadata for CC multi-turn resume. (🔨 chore: persistccSessionIdin topic metadata for CC multi-turn resume #13902)--include-partial-messages. ( 🔨 chore: stream token-level deltas via--include-partial-messages#13929)🧠 Agent Signal & Self-Iteration
@lobechat/agent-signalpackage with dynamic feedback signals. (✨ feat(agent-signal): created new package agent-signal #14157)agent-tracingfor rendering-Sfor signals #14159)💬 Conversation
📱 Platforms & Integrations
Desktop / Electron
+button for new topic, dark theme blend, close icon by default. (✨ feat(electron): add + button to TabBar for new topic in active context #13972, 💄 style(electron): refine desktop tab bar dark theme surface #14203, 💄 style(tab-bar): blend inactive tabs with titlebar, show close icon by default #13973)Cmd+W/Cmd+Ttab shortcuts with misc desktop polish #13983, ♻️ refactor(desktop): consolidate global shortcuts (LOBE-7181) #13880)Git Workflow
Mobile
Bot / Messaging
🤖 Models & Providers
New models
xhigheffort tier; strip temperature/top_p. (✨ feat: add Claude Opus 4.7 with xhigh effort tier #13903, 🐛 fix: strip temperature/top_p for Claude Opus 4.7 #13909)New providers
Runtime reliability
function.namein streaming tool_call deltas. (🐛 fix(model-runtime): tolerate null function.name in streaming tool_call deltas #14139)thoughtSignatureincall_tools_batchnormalization. (🐛 fix(agent-runtime): preserve Gemini 3 thoughtSignature in call_tools_batch normalization #14032)image_urlparts when target model lacks vision. (🐛 fix(context-engine): downgradeimage_urlparts when target model lacks vision #14029)safety_identifierfor OpenAI Responses API. (🐛 fix(model-runtime): usesafety_identifierfor OpenAI Responses API #14148)formatErrorEventData. (🐛 fix(agent-runtime): unwrap underlying PG error in formatErrorEventData #14038)🖥️ User Experience
updateDocument, persona analytics snapshot, footer promotion pipeline, wrap-up button. (✨ feat(onboarding): add preset agent naming suggestions #13931, ✨ feat(onboarding): structured hunk ops for updateDocument #13989, ✨ feat(onboarding): persist topic onboarding analytics snapshot #13930, ✨ feat(onboarding): add feature flags and footer promotion pipeline #13853, ✨ feat(onboarding): add wrap-up button for agent onboarding #13934)🔧 Tooling
@lobechat/model-bankautomated npm release with provenance. (👷 build(model-bank): automate npm release #14015, 🐛 fix(model-bank): publish initial npm package publicly #14017, 🐛 fix(model-bank): add repository metadata for provenance #14018)activateToolscannot find identifier. (🐛 fix: fallback to skill activation when activateTools cannot find identifier #14010)lobe-gtdandlobe-crondescriptions. (🐛 fix: inject timezone and cron jobs list into cron tool system prompt #14012, 🐛 fix: clarify lobe-gtd and lobe-cron tool descriptions to prevent routing confusion #14013)🔒 Security & Reliability
👥 Contributors
Huge thanks to 17 contributors who shipped 194 merged PRs this week.
@hardy · @shaun0927 · @hezhijie0327 · @sxjeru · @arvinxx · @Innei · @tjx666 · @lijian · @neko · @rdmclin2 · @AmAzing129 · @sudongyuer · @CanisMinor · @rivertwilight
Plus @lobehubbot and renovate[bot] for maintenance.
Full Changelog: v2.1.52...v2.1.53