Commit Graph
653 Commits
Author SHA1 Message Date
diguaandCursor f4d5010e77 refactor: unify session list/detail queries into @openchatlab/core
Extract duplicated session info assembly from electron/main/worker/query/sessions.ts,
packages/server/src/http/routes/web.ts, and sessions.ts into shared core functions.

- Add CoreSessionInfo type covering all single-DB queryable AnalysisSession fields
- Add buildSessionInfo pure mapper (meta + overview → flat info)
- Add getSessionInfo convenience (one-call DB query)
- Add getSummaryCount and getLastPlatformMessageId helpers
- Electron: thin adapter with cache-first overview, platform-specific dbPath/avatar/aiCount
- Server web.ts & sessions.ts: delegate to getSessionInfo, eliminate inline assembly
- Add 9 unit tests for all new core session functions

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-17 13:08:48 +08:00
diguaandCursor 9ad0c49acf refactor: unify message query functions into @openchatlab/core
Extract duplicated query logic from electron/main/worker/query/messages.ts
and src/services/message/fetch.ts into shared async functions in core.

- Add AsyncSqlExecutor abstraction (packages/core/src/query/executor.ts)
- Add 8 shared async query functions (message-query-functions.ts)
- Extend buildMsgConditions with memberId/systemFilter/textOnlyFilter
- Electron: thin adapter via sync-to-async executor, FTS remains platform-specific
- Web/CLI: thin adapter via pluginQuery executor
- Fix pre-existing SearchMessageResult type mismatch (add missing fields)
- Add 10 unit tests verifying executor consistency

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-17 12:56:25 +08:00
digua ebca4a4f09 refactor: unify message query layer with shared SQL template and mapper
Extract duplicated 12-column message SELECT, types, and row mapper into
@openchatlab/core/query/message-sql.ts as single source of truth.
Migrate Electron worker, CLI Web FetchMessageAdapter, filter.ts, and
core hydrateMessagesByIds to use shared FULL_MSG_SELECT + mapMessageRow.
Remove DbMessageRow, sanitizeMessageRow, and all inline SQL duplicates.
2026-05-16 00:40:49 +08:00
digua 40bdc9c1b0 fix: resolve sync display bugs and unify import logic
- Fix subscription sync not showing +xx: trigger foreground pull after
  adding sessions instead of relying on background scheduler
- Fix negative message count (+-N): use messageCount directly as it
  already represents net new writes after dedup
- Eliminate duplicated fullImportFile: delegate to importData() to avoid
  missing fields (avatar, roles, reply_to_message_id, group_avatar)
- Fix member avatar not displaying in CLI Web: SQL alias mismatch
  (avatar vs senderAvatar)
- Add skipInitialPull param to scheduler to avoid race with foreground pull
- Add @openchatlab/sync to server package.json for proper tsx watch support
2026-05-16 00:11:30 +08:00
digua 6f8106db80 refactor: migrate Electron sync to @openchatlab/sync shared package
Replace Electron-specific config, data source, pull scheduler, and
discovery modules with @openchatlab/sync shared implementations.
Create ElectronFetcher, WorkerImporter, and BrowserWindowNotifier
adapters. Delete 5 redundant files (~27KB of duplicated code).
2026-05-15 23:31:00 +08:00
digua 158e792956 feat: add @openchatlab/sync package and CLI automation support
Extract platform-agnostic sync logic (config, data source, discovery,
pull engine, scheduler) into @openchatlab/sync. Implement server-side
adapters (NodeFetcher, DirectImporter, NoopNotifier) and HTTP routes
(/_web/automation/*) for the CLI web UI. Adapt Pinia store with
dual-transport (IPC for Electron, HTTP for Web).
2026-05-15 23:21:10 +08:00
digua 56a7939356 feat: implement all CoreDataProvider methods for Server Agent
Extract 10 query functions from Electron worker to @openchatlab/core:

- message-queries: getMessageContext, getSearchMessageContext,
  getConversationBetween, getMemberNameHistory, getMembersWithAliases,
  executeParameterizedSql
- session-queries: getChatOverview, searchSessions, getSessionMessages,
  getSessionSummaries
- filters: hasTable, hasColumn utilities

CoreDataProvider now delegates to core functions instead of throwing
NotImplementedError. All 27 Server Agent tools are functional.

Also inject segmentText (batchSegmentWithFrequency) into server
ToolExecutionContext so keyword_frequency tool works properly.
2026-05-15 22:23:27 +08:00
digua 74ea5563cb refactor: split tool registry into MCP and Agent, align agent tools with Electron
- Rename TOOL_REGISTRY to MCP_TOOL_REGISTRY (MCP Server only)
- Create AGENT_TOOL_REGISTRY with full Electron-aligned tool set (27 tools)
- MCP-only tools (list_sessions, get_session_info, search_keyword) excluded
  from agent registry
- Update ai.ts to use AGENT_TOOL_REGISTRY, mcp.ts to use MCP_TOOL_REGISTRY
- Add truncation strategies for newly registered agent tools

Note: Most newly registered agent tools require CoreDataProvider method
implementations (currently NotImplementedError). See follow-up task doc.
2026-05-15 22:03:40 +08:00
digua c789df5495 refactor: unify AI tool naming across Electron, CLI Web, and MCP
Remove chatlab_ prefix from all tool definitions in @openchatlab/tools,
aligning with Electron-style names (get_*, search_*, etc.). The chatlab_
prefix is now only added at the MCP registration layer via MCP_TOOL_PREFIX
constant, keeping MCP namespace isolation without polluting internal names.

This ensures the AI agent uses identical tool names in both Electron and
CLI Web environments, fixing skill system compatibility and tool catalog
consistency.
2026-05-15 21:39:30 +08:00
digua 17f7ebc094 docs: update 2026-05-15 22:30:18 +08:00
digua 6090c6689f refactor: extract AiLogger to @openchatlab/node-runtime for shared use
Move the file-based AI logging implementation from Electron-specific
code to a shared AiLogger class in @openchatlab/node-runtime. Both
Electron and Server/CLI now use the same logger writing to
~/.chatlab/logs/ai/. Server-side agent, tool adapter, and compression
now produce the same structured log files as Electron.
2026-05-15 22:23:49 +08:00
digua 932b2553b0 refactor: remove 3 pure re-export wrappers in electron/main/ai
Delete tokenizer/index.ts, skills/parser.ts, and assistant/parser.ts
which were single-line re-exports from @openchatlab/node-runtime.
All consumers now import directly from the shared package.
2026-05-15 22:12:50 +08:00
digua 596eaa3051 refactor: remove redundant electron/main/ai/compression wrapper
Inline createCompressionLlmAdapter and logger into the sole caller
(ipc/ai.ts) and import checkAndCompress/manualCompress directly from
@openchatlab/node-runtime. The "old API compatibility" layer was
unnecessary since there is only one internal consumer.
2026-05-15 22:08:31 +08:00
digua 787e645a60 refactor: remove redundant electron/main/ai/preprocessor directory
The 4-file preprocessor wrapper directory was entirely re-exports from
@openchatlab/node-runtime after the pipeline unification. Replace all
consumers with direct imports and add logger injection support to
PreprocessingPipelineOptions so Electron retains aiLogger integration.
2026-05-15 19:58:03 +08:00
digua 984b778033 refactor: extract shared preprocessing pipeline to @openchatlab/node-runtime
Unify the duplicated preprocessing logic between Electron (wrapWithPreprocessing)
and Server (applyPreprocessing) into a single applyPreprocessingPipeline() function
in @openchatlab/node-runtime. Both platforms now delegate to the same implementation,
eliminating ~50 lines of redundant code and fixing a redundant token counting bug
in the Server version.
2026-05-15 19:52:01 +08:00
digua ad1c6eef1e chore: remove unused electron/main/ai/tools/utils/format.ts 2026-05-15 19:40:51 +08:00
digua b5e296b631 chore: remove dead code sqlToolRunner.ts (replaced by @openchatlab/tools/sql) 2026-05-15 19:39:27 +08:00
digua 9d55676892 refactor(tools): complete migration of all Electron tools to shared definitions
Move all 24 Electron-native tool definitions to @openchatlab/tools:
- 13 data query tools (chat-overview, search-messages, deep-search,
  get-recent-messages, get-message-context, search-sessions,
  get-session-messages, get-members, get-member-name-history,
  get-conversation-between, get-session-summaries,
  response-time-analysis, keyword-frequency)
- 11 SQL template tools (message_type_breakdown, etc.)

Electron definitions/ now contains only index.ts with adaptSharedTool()
calls. All tool logic lives in the shared package.

Key changes:
- Expand ToolDataProvider with 12 new methods for full data access
- Add ToolExecutionContext fields: searchContextBefore/After,
  maxMessagesLimit, segmentText callback, translateTemplate callback
- Create shared utils: format.ts (i18n), time-params.ts, schemas.ts
- Create SQL tool system: definitions, executor, types
- WorkerDataProvider implements all new methods via workerManager
- CoreDataProvider stubs new methods (Server doesn't use these yet)
- Delete 16 Electron tool files (-1280 lines, +482 lines)
2026-05-15 19:34:35 +08:00
digua f35676cb23 refactor(electron): replace member_stats and time_stats with shared tool definitions
Create shared-tool-adapter to convert @openchatlab/tools ToolDefinition → AgentTool.
Delete Electron-specific get-member-stats.ts and get-time-stats.ts,
replaced by shared definitions via adaptSharedTool().
Make ToolExecutionContext.db optional to support Electron (no DatabaseAdapter).
2026-05-15 19:11:59 +08:00
digua 619b59270b refactor(tools): migrate 6 tool handlers to use ToolDataProvider
Replace direct @openchatlab/core function calls with dataProvider abstraction:
- member-stats, time-stats, search, recent-messages, sql, schema
- Handlers are now async, using context.dataProvider for data access
- Server consumers inject CoreDataProvider alongside db for backward compat
2026-05-15 19:07:21 +08:00
digua b1df81b064 feat(tools): implement CoreDataProvider and WorkerDataProvider
Add ToolDataProvider implementations for both platforms:
- CoreDataProvider: wraps @openchatlab/core sync queries for Server/MCP
- WorkerDataProvider: wraps workerManager async IPC for Electron
2026-05-15 19:05:00 +08:00
digua 21a0ce36f4 refactor(tools): add ToolDataProvider interface and async handler support
Prepare @openchatlab/tools for unified tool layer:
- ToolDefinition.handler now supports async (ToolResult | Promise<ToolResult>)
- Add ToolDataProvider abstraction interface for platform-agnostic data access
- Add TimeFilter, ToolCategory, TruncationStrategy types
- Update Server consumers (tool-adapter, mcp) to await handler results
2026-05-15 19:02:49 +08:00
digua 653bd966fa fix: dev native startup issues 2026-05-15 18:54:50 +08:00
digua 347c7d69dd refactor(electron): migrate all pi-ai/pi-agent-core imports to node-runtime
- Convert 20 tool definition files to import Type/AgentTool from
  @openchatlab/node-runtime instead of direct pi-* packages
- Migrate compression, summary, RAG, LLM config, and IPC modules
  to use node-runtime re-exports (completeSimple, streamSimple, etc.)
- Remove @mariozechner/pi-agent-core and @mariozechner/pi-ai from
  root package.json — now only node-runtime depends on them directly
- Electron is now fully decoupled from pi-* direct imports
2026-05-14 23:46:13 +08:00
digua 8dd3e2396c refactor(ai): extract shared Agent core to @openchatlab/node-runtime
- Create runAgentCore() in node-runtime/src/ai/agent/ encapsulating
  PiAgentCore construction, history conversion, event subscription,
  abort forwarding, tool round management, and usage collection
- Re-export pi-agent-core/pi-ai types (AgentTool, Type, Model, etc.)
  and functions (completeSimple, streamSimple) from node-runtime
- Refactor Server agent.ts to use runAgentCore, removing all direct
  pi-agent-core/pi-ai imports (~335→~210 lines)
- Remove pi-agent-core and pi-ai from Server package.json dependencies
- Refactor Electron agent/index.ts and event-handler.ts to use
  runAgentCore with DI hooks (streamFn, onConvertToLlm, onDebugContext)
- Document remaining Electron pi-ai usage points for future migration
2026-05-14 23:36:11 +08:00
digua 6348c3f4e8 refactor(electron): switch tools module to shared @openchatlab/node-runtime imports
- Replace local formatToolResultAsText, truncateFormattedMessages,
  anonymizeMessageNames with imports from @openchatlab/node-runtime
- Replace local createActivateSkillTool with shared version via DI
  (inject Electron's getSkillConfig and CORE_TOOL_NAMES)
- Retain Electron-specific translateTool (i18n) and getAllTools (tool registry)
- Net reduction of ~170 lines of duplicated code
2026-05-14 22:11:04 +08:00
digua 9dfb2dfbf4 feat(server,web): implement validateApiKey and fetchRemoteModels for web mode
- Create remote-api.ts with platform-agnostic validateApiKey (completeSimple
  test call) and fetchRemoteModels (OpenAI/Gemini model listing endpoints)
- Add POST /_web/ai/llm/validate-key and POST /_web/ai/llm/remote-models
  HTTP endpoints
- Update web shim to call new endpoints instead of returning stubs
2026-05-14 22:09:12 +08:00
digua d87bdd5712 feat(server,web): add custom provider/model CRUD HTTP endpoints
- Create custom-store.ts with platform-agnostic CRUD for custom-providers.json
  and custom-models.json (parameterized by aiDataDir)
- Add 6 HTTP endpoints: POST/PUT/DELETE for custom providers and models
- Update web shim to call new endpoints instead of returning WEB_STUB
2026-05-14 22:07:54 +08:00
digua 4b1a1e411b feat(server,web): connect compression config through SSE stream
- Add compressionConfig to SSE agent/stream request body with sensible defaults
- Pass compressionConfig from route handler to runServerAgent
- Update frontend runStream to forward compressionConfig to the SSE endpoint
2026-05-14 22:06:17 +08:00
digua 245a2e39a0 feat(tools,server): integrate preprocessing pipeline for web tool results
- Extend ToolResult with optional rawMessages field for structured message data
- Update search and recent-messages tools to return rawMessages from query results
- Add preprocessing wrapper in server tool-adapter: auto-apply data cleaning,
  denoising, desensitization, compact formatting, and token-aware truncation
  when tools return rawMessages
2026-05-14 22:04:54 +08:00
digua 07056a2258 feat: extract context compression to @openchatlab/node-runtime
Move compression logic from Electron to shared package with pluggable
LLM adapter interface. Integrate into server agent with pre-run
compression support. Electron side becomes a thin compatibility wrapper.
2026-05-14 21:43:10 +08:00
digua 68b1c7a1b2 feat: add LLM config write endpoints for Web mode
Add CRUD HTTP endpoints for LLM configurations (add/update/delete config,
set default assistant slot, set fast model slot).
Update web shim to call these endpoints instead of returning stubs.
2026-05-14 21:38:54 +08:00
digua 58d7da6367 feat: add SkillManager and activate_skill tool to shared package
Extract SkillManager from Electron to @openchatlab/node-runtime.
Create shared createActivateSkillTool factory.
Integrate skill menu into server agent system prompt and SSE route.
2026-05-14 21:34:58 +08:00
digua 76b4be1264 refactor: extract preprocessor pipeline to @openchatlab/node-runtime
Move preprocessing (pipeline, types, builtin-rules, format utilities)
from Electron to shared package. Electron side becomes thin wrappers.
2026-05-14 21:32:27 +08:00
digua b195750f34 refactor: extract tokenizer to @openchatlab/node-runtime
Move countTokens/countMessagesTokens from Electron to shared package.
Electron side becomes a thin re-export wrapper.
2026-05-14 21:27:39 +08:00
digua 6352a3f191 refactor: implement Migration Runner for config data migrations
Extract migration logic from loadConfigStore into a shared Migration Runner
system (packages/config/src/migrations/). Runs at app startup in both
Electron and CLI, enabling CLI to handle encrypted key migration independently.
2026-05-14 21:14:15 +08:00
digua b479fd3b2d feat(web): enable AI chat in web mode with shared conversation module
- Extract AIConversationManager to @openchatlab/node-runtime for Electron + Server reuse
- Add /_web/ai/conversations/* HTTP endpoints for conversation/message CRUD
- Create FetchAIAdapter to replace WebAIAdapter stub
- Implement server-side Agent with SSE streaming (/_web/ai/agent/stream)
- Add agentApi SSE client shim in frontend registry
- Migrate API key storage from encrypted llm-config.json to auth-profiles.json
- Add @openchatlab/config auth-profiles module for credential management
2026-05-14 20:55:54 +08:00
digua 12f9ae90eb feat(web): enable AI page data loading in web mode via HTTP endpoints
- Move assistant/skill MD parsers to @openchatlab/node-runtime (shared)
- Move BUILTIN_TOOL_CATALOG, provider-registry, model-catalog to @openchatlab/core
- Add /_web/ai/* HTTP routes for assistants, skills, LLM config, providers, models, tools
- Frontend shims: read ops call HTTP, write/agent ops return stubs
- Remove IS_ELECTRON guard in llm.ts to enable web-mode config loading
- Improve web-mode AI chat error message to be user-friendly
2026-05-14 20:29:06 +08:00
digua 4b15d65b13 refactor(nlp): extract shared NLP logic to core + node-runtime
Move platform-agnostic NLP types, stopwords, POS tag definitions, and
text utilities into @openchatlab/core. Move segmenter engine, word
frequency computation, and dict manager into @openchatlab/node-runtime.

Electron nlp/ becomes a thin re-export layer; server nlp.ts shrinks
from ~450 to ~85 lines retaining only HTTP route definitions. Both
platforms now share the same NLP implementation via node-runtime.

Also fixes createJiebaNlpProvider to use shared getJieba() with disk
dict loading (was using empty Jieba instance causing degraded POS tags
in language preference analysis), adds ensureDefaultDict at server
startup, and adds /_web/nlp/* HTTP routes with window.nlpApi shim.
2026-05-14 19:50:03 +08:00
digua 61a6e72c64 refactor: unify data directory for Electron and CLI
Split PathProvider into dual-root architecture: systemDir (~/.chatlab/)
for config/logs/cache/ai/settings, and userDataDir (~/.chatlab/data/ by
default) for chat databases. Both Electron and CLI share the same
config.toml for user_data_dir resolution.

- Refactor PathProvider interface (getSystemDir + getUserDataDir)
- Update config schema (data.dir → data.user_data_dir)
- Add writeConfigField() for config.toml manipulation
- Fix needsUnifiedDirMigration() to detect old Electron data even when
  user_data_dir was already set by CLI (compare paths instead of
  checking existence)
2026-05-14 19:35:36 +08:00
digua 6ca27b1194 refactor: unify query logic into @openchatlab/core and add analytics HTTP routes 2026-05-14 19:20:51 +08:00
digua ccee680077 feat(services): Phase 0 — service layer infrastructure
- Create src/services/ directory structure with 6 domain folders
- Add registry.ts: platform detection + adapter registration mechanism
- Add utils/sse.ts: generic SSE client (fetchSSE, fetchSSEWithHandlers)
- Add utils/http.ts: shared GET/POST/DELETE helpers for Fetch adapters
- Add services/index.ts: unified exports entry point
- Add task plan: .docs/tasks/2026-05-11-service-layer-refactoring.md
2026-05-13 22:07:41 +08:00
digua 42272575b7 feat(web): implement demo import for web mode via SSE endpoint
- Add POST /_web/demo/import backend endpoint: downloads demo data from
  chatlab.fun and imports using streamImport with SSE progress
- Refactor DemoImportButton.vue to support both Electron (IPC) and
  Web (SSE fetch) modes with shared result handling
2026-05-13 21:53:38 +08:00
digua 700b4266f3 fix(web): session index, CORS proxy, demo guard, and dev script improvements
- Add session index endpoints (generate-index, clear-index) with writable db
- Add window.sessionApi shims for web mode (getStats, generate, getSessions, etc.)
- Fix CORS: add Vite dev proxy for chatlab.fun, centralize CHATLAB_SITE_BASE
- Guard DemoImportButton: show fallback message in web mode
- Use tsx watch for dev:serve hot-reloading
- Reorganize dev scripts: dev:app (web frontend), dev:serve (backend), dev:web (both)
2026-05-13 21:51:27 +08:00
digua 4053b7c77f refactor(dev): reorganize dev scripts and port assignments
- dev: Electron only (renderer port 3400, unchanged)
- dev:app: Web frontend only (port 3100)
- dev:serve: Backend only (chatlab serve, default port 3110)
- dev:web: Web frontend + backend auto-start (3100 + 3110)
- Revert electron.vite.config.ts to original (no extra plugins)
- chatlabServePlugin gated by CHATLAB_AUTO_SERVE env var
2026-05-13 21:25:57 +08:00
digua 6695181759 fix(web): resolve runtime errors in web mode
- Fix streamImport error handling: close db before deleting files on failure
- Add POST /_web/sessions/:id/query endpoint for parameterized readonly SQL
- Expose PreparedStatement.readonly property in DatabaseAdapter interface
- Fix Fastify error handler to respect statusCode on non-ApiError errors
- Implement FetchAdapter.pluginQuery via HTTP endpoint
- Add web-api-shim.ts: window.chatApi/aiApi polyfills for chart-* and
  MessageList (pluginQuery, pluginCompute, getMemberActivity,
  getAvailableYears, message browsing methods)
- Fix Sidebar: navigate to home after deleting the currently viewed session
2026-05-13 21:25:50 +08:00
digua d14931bf1b fix: guard Electron-specific calls in BasicSettingsTab for web mode
Add IS_ELECTRON guards around window.api.setThemeSource,
window.api.app.getOpenAtLogin, and window.api.app.setOpenAtLogin
to prevent crashes when opening settings in web mode.
2026-05-13 20:39:46 +08:00
digua a1a6bdbb10 fix: auto-start chatlab serve backend when running dev:web
Add chatlabServePlugin to vite.web.config.mts that automatically spawns
chatlab serve on port 3400 when Vite dev server starts, so the web UI
works without manually starting the backend in a separate terminal.
2026-05-13 20:35:40 +08:00
digua a7f7f8706b fix: move multipart plugin registration to server startup
Register @fastify/multipart in startHttpServer before route registration
instead of inside registerWebRoutes, fixing 500 errors on /_web/ routes
caused by async plugin registration within route functions.
2026-05-13 20:30:31 +08:00
digua 3363640e75 feat: add web import support with adapter pattern and ImportArea refactor
- Extend QueryAdapter with importFile, detectFormat, scanMultiChatFile,
  and getSupportedFormats methods
- Implement FetchAdapter import methods with FormData upload and SSE
  progress stream parsing
- Implement ElectronAdapter import methods wrapping existing IPC calls
- Refactor ImportArea.vue to handle both Electron (native dialog + paths)
  and Web (FileDropZone + File objects) import flows
- Add 'indexing' stage to ImportProgress type
- Revert CLI-only import UI, restore drag-and-drop for web mode
2026-05-13 20:28:46 +08:00