mirror of
https://github.com/lobehub/lobehub.git
synced 2026-09-20 04:56:13 +08:00
fix/topic-switch-message-refresh
10 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
aba9e8150c |
👷 build: migrate the test suite to vitest 5 (#19355)
* 👷 build: upgrade vitest to 5.0.0 Bump vitest and @vitest/coverage-v8 to 5.0.0 and migrate the configs for Vitest 4/5: drop the removed coverage.all option and replace poolOptions.forks.singleFork with maxWorkers/isolate. * 👷 build: shim jest-dom matcher types for vitest 5 Vitest 5 exposes Assertion<R, T> and no longer reads the jest.Matchers augmentation that @testing-library/jest-dom ships, so its matchers vanish from expect(). Re-declare them on the Vitest interface, and replace the removed describe.sequential with { concurrent: false }. * 👷 build: migrate the test suite to vitest 5 Vitest 5 (and @vitest/coverage-v8) replaces the esbuild dep optimizer with Rolldown, removed environmentMatchGlobs/coverage.all/poolOptions, forwards `new` to mock implementations, requires top-level vi.mock, and no longer resets automocks in restoreAllMocks. Migrate the root config to app/server projects with Rolldown optimizer options, shim the jest-dom matchers on Assertion<R, T>, and update the affected tests (constructor mocks, hoisted mocks, awaited assertions, explicit mock types, per-test mock defaults). * 👷 build: make the openapi knowledge-base FileService mock constructable tests/ was outside the per-area sweep; vitest 5 forwards `new` to the mock implementation, so the arrow implementation threw "is not a constructor". * 👷 build: point the CI blob-report artifacts at the vitest 5 output dir Vitest 5 writes blob reports to .vitest/blob instead of .vitest-reports, so the sharded jobs uploaded nothing and the merge jobs failed with ENOENT. Track the new directory in .gitignore too. * 👷 build: refresh the desktop lockfile for vitest 5 apps/desktop/pnpm-lock.yaml is committed and the desktop build action installs with --frozen-lockfile, so the vitest/override change has to be reflected in it. * 👷 build: keep the pre-vitest-4 coverage exclusions explicit Vitest 4+ ships an empty coverageConfigDefaults.exclude, so configs that spread it silently lost the default exclusions (node_modules, dist, *.config.*) and counted more files. Inline the previous list. * 🎨 style: format the migrated vitest configs * 👷 build: keep canary's new class mocks constructable under vitest 5 exploreGraph/dispatchAuthorization/scopedDevices (canary #19375, #19352) mock classes with arrow implementations; vitest 5 constructs the implementation when the mock is newed, so the arrows throw 'is not a constructor'. |
||
|
|
20cea3a6bf |
✨ feat(page-agent): execute tools server-side via HeadlessEditor (#15023)
* ✨ feat(page-agent): execute tools server-side via HeadlessEditor Page-agent tools (initPage / editTitle / getPageContent / modifyNodes / replaceText) now run on the server against a `@lobehub/editor/headless` instance and persist through `DocumentService.updateDocument`, instead of executing inside the renderer's Lexical instance. The renderer applies the resulting snapshot via the builtin-tool `onAfterCall` hook, so the document store stays in sync without an extra fetch. This makes page-agent execution independent of the client lifecycle (editor unmount, tab switch, network blip), gives us full server-side tracing for free (OTel gen-ai + agent-signal + documentHistories), and exposes a `silent-no-op` / `unexpected-mutation` invariant when the exported editorData hash diverges from what the handler reported. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(page-agent): decouple EditorRuntime from @lobehub/editor side-effecting bundle EditorRuntime statically imported LITEXML_*_COMMAND from @lobehub/editor, which pulls ReactSlashPlugin and crashes Node (`document is not defined`) in any server-side test that transitively touched the runtime. The same import also dispatched the wrong command identity on HeadlessEditor's kernel — pnpm resolves @lobehub/editor to a different module copy than the headless bundle, so dispatchCommand would silently no-op server-side. Introduce a LiteXMLAdapter strategy: renderer wires command dispatch against the live editor; server wires HeadlessEditor.applyLiteXMLBatch / applyLiteXML so the correct headless-bundle symbols are used. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * 🐛 fix(page-agent): restore client-side mutate handlers on PageEditor mount The main commit dropped `setBeforeMutateHandler`/`setAfterMutateHandler` under the assumption that page-agent tools always execute server-side. But the chat-store path (`invokeBuiltinTool` → `PageAgentExecutor.modifyNodes` → `EditorRuntime.modifyNodes`) still routes through the client-bound runtime whenever the LLM dispatcher is the chat slice — it does not consult `manifest.executors`. Without the handlers, that path mutates the live editor but skips both `documentHistoryQueueService.enqueueEditorSnapshot` (loses undo baseline) and `commitEditorMutation(saveSource: 'llm_call')` (row never persists). Re-wire both handlers. Server-runtime path is unaffected: it instantiates its own `EditorRuntime` against `HeadlessEditor` and never sees the client's StoreUpdater wiring, so the two paths can coexist without double-writing. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(editor-runtime): split client / server entries so renderer gets adapter for free Renderer call sites shouldn't have to opt in to the obvious default (dispatch LITEXML_*_COMMAND on the live editor). Split the package into two entries: - `@lobechat/editor-runtime` — renderer entry; constructor auto-wires the LiteXML adapter from `@lobehub/editor`. Static-importing this from Node still crashes (ReactSlashPlugin), so it's the right shape for the browser only. - `@lobechat/editor-runtime/server` — server-safe entry; exports the bare class without touching `@lobehub/editor`. Callers (currently only the page-agent server runtime) supply their own HeadlessEditor- backed adapter. Drops the renderer-side setLiteXMLAdapter patch and a stale comment block in StoreUpdater. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * ♻️ refactor(page-agent): drop LiteXMLAdapter, dispatch commands directly `@lobehub/editor` 4.16.1 ships the LiteXML command identities through the side-effect-free `@lobehub/editor/litexml-commands` subpath, so a single command object is shared across the browser and node bundles and can be imported in Node without pulling the DOM-dependent editor bundle. `EditorRuntime` now imports `LITEXML_MODIFY_COMMAND` / `LITEXML_APPLY_COMMAND` from that subpath and dispatches them straight onto the editor kernel. This removes the `LiteXMLAdapter` strategy object (`setLiteXMLAdapter` / `getLiteXMLAdapter`) — a leaky abstraction whose only purpose was to keep the crash-on-Node command import out of the shared base. - editor-runtime: dispatch `LITEXML_*_COMMAND` directly; delete the adapter interface, field, setter and runtime-throw guard. - Collapse the client/server entry split (its sole reason — isolating the DOM-crashing import — is gone); both entries now re-export the isomorphic base. - pageAgent server runtime: drop the HeadlessEditor-backed adapter wiring. - Bump `@lobehub/editor` to ^4.16.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * ♻️ refactor(editor-runtime): drop redundant /server entry Now that `EditorRuntime` is isomorphic (LiteXML commands come from the DOM-free `@lobehub/editor/litexml-commands` subpath), the `./server` entry is byte-for-byte identical to the root `.` entry. Remove it and point the only consumer (pageAgent server runtime) at the root entry. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
6b010c8380 |
🐛 fix(editor-runtime): add mutation handlers for post-save synchronization (#14469)
* 🐛 fix(editor-runtime): add afterMutateHandler for post-mutation synchronization Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(editor-runtime): enhance beforeMutateHandler with context and add meaningful content check Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(editor-runtime): improve data source validation and streamline command dispatch logic Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(editor-runtime): add test for Page Agent editTitle behavior without sending content or editorData Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix(editor-runtime): update LiteXML node extraction to include attributes and improve error logging Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix: use namespace import for GeneralChatAgent to fix vi.spyOn in tests vi.spyOn on a module namespace object requires the production code to access the class through the same namespace. Destructured imports capture a direct binding that bypasses the spy, causing "Class constructor GeneralChatAgent cannot be invoked without 'new'" in tests. * 🐛 fix: replace vi.spyOn on class constructor with vi.mock for GeneralChatAgent vi.spyOn wraps a class with a plain function that loses [[Construct]] semantics in ESM, causing "Class constructor GeneralChatAgent cannot be invoked without 'new'". Replace with vi.mock + hoisted mock constructor that properly tracks calls while preserving new-ability. --------- Signed-off-by: Innei <tukon479@gmail.com> |
||
|
|
043d2a81fb |
✨ feat(agent): add floating chat panel and workspace improvements (#13887)
* ✨ feat(FloatingChatPanel): add single-instance mount guard * ✨ feat(FloatingChatPanel): add inner ChatBody layout * ✨ feat(FloatingChatPanel): add reusable floating conversation panel * ✅ test(FloatingChatPanel): add props wiring smoke tests * Refactor agent topic and page routes * Restore topic page routing for floating chat panel * ✨ feat(FloatingChatPanel): enhance ChatBody and TopicItem for improved routing and styling - Updated ChatBody to maintain scroll ownership while hiding overflow. - Refactored TopicItem to correctly highlight active topics based on routing context. - Added tests for TopicItem to ensure correct active state behavior. - Introduced static styles for FloatingChatPanel to manage layout overflow. Signed-off-by: Innei <tukon479@gmail.com> * chore: help to merge & rebase * chore: align merge with canary — drop pkg.pr.new ui, adopt canary useMenu, remove NotebookButton * ✨ feat: add ViewSwitcher component and update localization for chat views - Introduced a new ViewSwitcher component to toggle between chat, page, and task views in the conversation header. - Updated English and Chinese localization files to include new labels for the view switcher options. - Refactored the conversation header to integrate the ViewSwitcher, enhancing the user interface for better navigation. Signed-off-by: Innei <tukon479@gmail.com> * fix: update @lobehub/ui to version 5.9.1 and refactor FloatingChatPanel to use FloatingSheet component - Updated the @lobehub/ui dependency in package.json to version 5.9.1. - Refactored FloatingChatPanel to utilize the new FloatingSheet component, enhancing its layout and state management. - Introduced a new ChatLayout component for better organization of chat-related UI elements. - Adjusted routing configuration to incorporate the new ChatLayout for agent chat pages. Signed-off-by: Innei <tukon479@gmail.com> * feat: add TopicCanvas and TitleSection components for topic management - Introduced TopicCanvas component to serve as a document canvas for topics, integrating an editor and title section. - Added TitleSection component for managing topic titles and emojis, enhancing user interaction with a dedicated UI. - Updated FloatingChatPanel to accommodate the new TopicCanvas, ensuring a cohesive layout in the topic page. - Enhanced tests to verify the integration of TopicCanvas within the topic page route. Signed-off-by: Innei <tukon479@gmail.com> * ✨ feat(agent-page): bind documentId to URL and introduce HeaderSlot - Add nested /agent/:aid/:topicId/page/:docId route with PageRedirect for bare /page - Introduce useAutoCreateTopicDocument with module-level inflight de-dup - Lift Portal + WorkingSidebar to (chat) layout; keep ChatHeader in left column - Sidebar document clicks on page route navigate to /page/:docId instead of opening Portal - Add HeaderSlot (context + createPortal) as a reusable header injection point - Mount AutoSaveHint via HeaderSlot; register Files hotkey scope in TopicCanvas so Cmd+S triggers manual save - Sync desktopRouter.config.tsx and desktopRouter.config.desktop.tsx - Extend RecentlyViewed plugin to round-trip optional docId segment * Use topic titles for auto-created page documents * Add page-agent init gating and runtime diagnostics * Support current-topic agent documents * Implement Active Topic Document and Disabled Tool Call Filtering - Introduced ActiveTopicDocumentContextInjector to inject context for active topic documents into user messages. - Added DisabledToolCallFilter to remove historical tool calls for disabled tools in the current runtime scope. - Updated MessagesEngine to utilize the new context injectors and filters. - Enhanced tests to verify the correct injection of active topic document context and filtering of disabled tool calls. This update improves the handling of document editing contexts and tool management in the conversation flow. Signed-off-by: Innei <tukon479@gmail.com> * feat: enhance agent document management with LiteXML operations - Updated API names for clarity, changing 'patchDocument' to 'modifyNodes'. - Introduced LiteXML operation schema for document modifications. - Implemented new mutation for modifying document nodes via LiteXML. - Enhanced document retrieval methods to support format options (XML, Markdown, Both). - Added support for editor data snapshots and normalization of diff nodes. - Improved document history management to handle editor data with diff nodes. - Created tests for new features and ensured existing functionality remains intact. Signed-off-by: Innei <tukon479@gmail.com> * 🐛 fix: apply agent document xml edits directly * Refine document cache invalidation and editor hydration * 🐛 fix: stabilize agent topic hydration * fix: update @lobehub/editor dependency version and clean up test mocks Signed-off-by: Innei <tukon479@gmail.com> * Potential fix for pull request finding 'Useless assignment to local variable' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * 🐛 fix(document): preserve pending diff nodes through save path Skip normalizeEditorDataDiffNodes on every autosave so diff nodes awaiting user review survive persistence. Normalization now runs only on explicit Accept/Reject via DiffAllToolbar. Also flip headless litexml ops to delay:true to match the new review flow. * 🐛 fix(agent): detect agent sub-route from URL params not cached topic isInAgentSubRoute used routeTopicId (with activeTopicId fallback) as its base path. On /agent/:aid/profile with a cached activeTopicId, the base became /agent/:aid/:cachedTopicId which pathname cannot startsWith, so sub-route detection returned false and sidebar topic clicks only called switchTopic without routing back to chat — users stayed stuck on profile. Derive the sub-route base from params.topicId directly so stale store state cannot mask the check. routeTopicId export keeps the fallback for sidebar highlighting. * 🐛 fix(page): repair topic page document recovery * 🐛 fix(page-agent): block tool calls when page editor is not mounted scope is topic-bound not route-bound, so navigating from /agent/.../Page to /agent/... keeps scope==='page' and PageAgentIdentifier stayed in the injected plugin list. The LLM could still call initPage / modifyNodes / etc. against a stale editor reference, returning misleading success (e.g. nodeCount=0). Two layers of guard: - PageAgentExecutor wraps `invoke` and returns a structured PAGE_EDITOR_NOT_MOUNTED / kind: 'replan' result when the runtime editor is not mounted, pointing the LLM at lobe-agent-documents. - streamingExecutor drops PageAgentIdentifier from the tool set via the new `composeEnabledTools` pipeline when scope==='page' and the page-agent runtime is not ready. Also extract the tool-set composition (inject merge + runtime drops) out of the ~320-line internal_createAgentState into `mecha/toolSetComposer`, with unit tests. * 🐛 fix(chat): unify message stream for /agent/:topicId and /page/:docId Before this change a page-scoped conversation (FloatingChatPanel with scope='page' in the /Page route) partitioned the client message store by scope, so /agent/:topicId and /agent/:topicId/page/:docId each built their own messagesMap slot and SWR cache — but the TRPC getMessages endpoint ignores scope and returned the same messages for both, producing duplicate fetches and a visible message-history split between the two surfaces. Fixes by keeping scope='page' as a capability/surfacing marker only: - messageMapKey: collapse 'page' to the default scope early in toMessageMapContext, so threadId/groupId still win and only the main/page pair actually unifies. - useFetchMessages: build the SWR key from identity fields (agentId, groupId, threadId, topicId) instead of the full ConversationContext, so scope no longer partitions the cache. agentConfigResolver/streamingExecutor/composeEnabledTools still read scope='page' from operation.context for PageAgent injection and initialContext.pageEditor wiring — the capability layer is unchanged. Also fix two pre-existing test regressions surfaced by re-running the impacted suites: - streamingExecutor page-editor initialContext test now mocks pageAgentRuntime.isReady() (required since the PageAgent editor-ready guard landed). - FloatingChatPanel default shell props test updated to match the [180,320,520,800] snap points introduced in |
||
|
|
f1d615fa9f |
✨ feat(document): add history management and compare workflow (#13725)
* 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> |
||
|
|
aaa7b6d153 |
✨ feat(desktop): implement subscription pages embedding with webview (#12114)
* ✨ 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> |
||
|
|
fcdaf9d814 |
🔧 chore: update eslint v2 configuration and suppressions (#12133)
* 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> |
||
|
|
484814ab3a | fix types | ||
|
|
88721ebd5d |
♻️ refactor: refactor page and notebook document usage (#11345)
* update create document
* refactor
* clean document/notebook slice
* update
* fix agent access issue
* ♻️ refactor: 重构 editorCanvas 实现以支持 Notebook editor 的复用
* fix editor autosave time
* refactor page editor
* update
* fix page editor init issue
* fix page editor data flow
* finish Page refactor
* update editor canvas
* improve notebook document
* update editor runtime test
* update mode
* fix editor hot reload issue
* update mode
* fix
* update
* update
* update
|
||
|
|
be2b41c792 | ♻️ refactor: refactor with editor runtime |